
function Calendar(_date, _id, _id2, _func) {

    this.date = _date;        // Startdatum
    this.table = _id;         // Tabelle
    this.display = _id2;      // Monatsanzeige
    this.c_date = new Date(new Date().getFullYear(), new Date().getMonth(), new Date().getDate()); // aktuelles Datum
    this.func = _func;        // Event-Handler

    // gibt die Anzahl der Tage des aktuellen Monats zurück
    this.getDaysOfMonth = function() {

        var days = 31;

        switch(this.date.getMonth()) {

        case 1: days -= 3;
                if(this.date.getFullYear() % 4 == 0) days++;
                if(this.date.getFullYear() % 100 == 0) days--;
                if(this.date.getFullYear() % 400 == 0) days++;
                break;

        case 3: days--;
                break;

        case 5: days--;
                break;

        case 8: days--;
                break;

        case 10: days--;
                 break;

        default: break;
        }
        return days;
    };

    this.getMonthString = function() {

        var months = new Array("Januar", "Februar", "M" + String.fromCharCode(228)  + "rz", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember");
        return months[this.date.getMonth()] + " " + this.date.getFullYear();
    };

    this.update = function() {

        var tab = document.getElementById(this.table);
        var rows = tab.getElementsByTagName("tr");
        var firstday = new Date(this.date.getFullYear(), this.date.getMonth(), 0); // erster Tag im Monat
	    var dayCount = 0;
        var days = this.getDaysOfMonth();
        var i = 0, j = 0;

        while(i < rows.length) {
            cols = rows[i].getElementsByTagName("td");
            j = 0;
            if(cols.length == 1) {
                if(dayCount >= days) {
                    cols[0].firstChild.style.visibility = "hidden";
                } else {
                	cols[0].firstChild.style.visibility = "visible";
                }
                i++;
                continue;
            }
            while(j < cols.length) {
                // Sonderbehandlung erste Zeile
                if(i == 1) {
                    if(j < firstday.getDay()) {
                        cols[j].firstChild.data = "";
                        cols[j].className = "calendar_unused";
                        cols[j].onclick = null;
                    } else {
                        dayCount++;
                        cols[j].firstChild.data = dayCount;
                        cols[j].className = "calendar";
                        if(new Date(this.date.getFullYear(), this.date.getMonth(), dayCount) >= this.c_date) {
                            cols[j].onclick = this.func;
                        } else {
                            cols[j].onclick = "";
                            cols[j].className = "calendar_outdated";
                        }
                        if(this.c_date.getDate() == dayCount &&
                           this.c_date.getMonth() == this.date.getMonth() &&
                           this.c_date.getFullYear() == this.date.getFullYear()) {
                           cols[j].className = "calendar_today";
                        }
                    }
                } else {
                    if(dayCount == days) {
                        cols[j].firstChild.data = "";
                        cols[j].className = "calendar_unused";
                        cols[j].onclick = null;
                    } else {
                        dayCount++;
                        cols[j].firstChild.data = dayCount;
                        cols[j].className = "calendar";
                        if(new Date(this.date.getFullYear(), this.date.getMonth(), dayCount) >= this.c_date) {
                            cols[j].onclick = this.func;
                        } else {
                        	cols[j].onclick = "";
                            cols[j].className = "calendar_outdated";
                        }
                        if(this.c_date.getDate() == dayCount &&
                           this.c_date.getMonth() == this.date.getMonth() &&
                           this.c_date.getFullYear() == this.date.getFullYear()) {
                           cols[j].className = "calendar_today";
                        }
                    }
                }
                j++;
            }
            i++;
        }
        // Monatsanzeige aktualisieren
        document.getElementById(this.display).firstChild.data = this.getMonthString();
    };

    this.incMonth = function() {

        var val = (this.c_date.getMonth() + this.c_date.getFullYear() * 12) - (this.date.getMonth() + this.date.getFullYear() * 12 );

        if(val > -3) {
	        if(this.date.getMonth() != 11) {
	            this.date.setMonth(this.date.getMonth() + 1);
	        } else {
	            this.date.setFullYear(this.date.getFullYear() + 1);
	            this.date.setMonth(0);
	        }
	        this.update();
    	}
    };

    this.decMonth = function() {

        var val = (this.c_date.getMonth() + this.c_date.getFullYear() * 12) - (this.date.getMonth() + this.date.getFullYear() * 12 );

        if(val < 0) {
	        if(this.date.getMonth() != 0) {
	            this.date.setMonth(this.date.getMonth() - 1);
	        } else {
	            this.date.setFullYear(this.date.getFullYear() - 1);
	            this.date.setMonth(11);
	        }
	        this.update();
    	}
    };
}
