/**
*   CONSTRUCTOR
*   Generiert ein Daten Array mit den Kalendertagen eines Monats.
*   Das Array beinhaltet immer volle Wochen. Tage einer Woche, die zu dem vorherigen
*   oder folgendem Monat gehören haben den Wert 0.
*
*   @param int year Jahr für den der Kalender generiert werden soll
*   @param int month Monat für den der Kalender generiert werden soll
*/
calendar = function(year, month) {
    this.data = new Array;   // Array mit den Daten des Monats
    this.year = year;   // Jahr, für den der Kalender erstellt werden soll
    this.month = month; // Monat, für den der Kalender erstellt werden soll
    this.max_month = 13;    // max. Anzahl Monate in die Zukunft
    var check_val = Date.UTC(year, month, 1);
    if (this.check_date(check_val)) {
        this.build();
        this.previous_date = this.get_previous_date();
        this.next_date = this.get_next_date();
    } else {
        return false;
    }
}   // of function

/**
*   Prüft das gewünschte Datum auf Gültigkeit.
*
*   @param int check_val    Timestamp des zu prüfenden Datums
*   @return bool    true, wenn das Datum gültig ist, ansonsten false
*/
calendar.prototype.check_date = function(check_val) {
    var current = new Date();
    var min = Date.UTC(current.getFullYear(), current.getMonth(), 1);
    var tmp = new Date(current.getFullYear(), (current.getMonth() + this.max_month), 1);
    var max = Date.UTC(tmp.getFullYear(), tmp.getMonth(), 1);
    if ( (check_val < min) || (check_val > max) ) {
        return false;
    } else {
        return true;
    }
}   // of function

/**
*   Liefert den String für den vorherigen Monat oder einen leeren String bei Fehlern.
*
*   @return string ret_val  vorheriges Datum (yyyy-mm-dd)
*/
calendar.prototype.get_previous_date = function() {
    var new_month = Number(this.month) - Number(1);
    var previous = new Date(this.year, (new_month -1), 1);
    var previous_chk = Date.UTC(previous.getFullYear(), previous.getMonth(), 1);
    var result = this.check_date(previous_chk);
    if (result) {
        ret_val = previous.getFullYear() + '-' + (previous.getMonth() +1) + '-1';
    } else {
        ret_val = '';
    }
    return ret_val;
}   // of function

/**
*   Liefert den String für den vorherigen Monat oder einen leeren String bei Fehlern.
*
*   @return string ret_val  nächstes Datum (yyyy-mm-dd)
*/
calendar.prototype.get_next_date = function() {
    var new_month = Number(this.month) + Number(1);
    var next = new Date(this.year, (new_month -1), 1);
    var next_chk = Date.UTC(next.getFullYear(), next.getMonth(), 10);
    var result = this.check_date(next_chk);
    if (result) {
        ret_val = next.getFullYear() + '-' + (next.getMonth() +1) + '-1';
    } else {
        ret_val = '';
    }
    return ret_val;
}   // of function

/**
*   Liefert den letzten Tag des Monats.
*
*   @param int year Jahr für den der Kalender generiert werden soll
*   @param int month Monat für den der Kalender generiert werden soll
*   @return int stop    letzten Tag des Monats
*/
calendar.prototype.get_lastday_of_month = function(year, month) {
    var stop = 31;
    if (month == 4 || month == 6 || month == 9 || month == 11) {
        --stop;
    }
    if (month == 2) {
        stop = stop - 3;
        if (year % 4 == 0)
        stop++;
        if (year % 100 == 0)
        stop--;
        if (year % 400 == 0)
        stop++;
    }
    return stop;
}   // of function

/**
*   Füllt das Daten Array mit den Tagen des Kalenders.
*   ACHTUNG - in JS beginnen die Monate mit 0=Jan. und enden mit 11=Dez. !!!
*/
calendar.prototype.build = function() {
    var first_date = new Date(this.year, (this.month -1), 1);
    // Wochentag des 1. des Monats ermitteln
    var first_wd = first_date.getDay();
    if (first_wd > 0) {
        first_wd--;
    } else {
        first_wd = 6;
    }
    // letzten Tag des Monats ermitteln
    var last_day = this.get_lastday_of_month(this.year, this.month);
    // letzten Wochentag des Monats ermitteln
    var date_tmp = new Date(this.year, (this.month -1), last_day);
    var last_wd = date_tmp.getDay();
    if (last_wd > 0) {
        last_wd--;
    } else {
        last_wd = 6;
    }
    // Daten Array füllen
    var idx = 0;
    // Woche vor dem 1. auffüllen
    for (i=0;i<first_wd;i++) {
        this.data[idx] = 0;
        idx++;
    }   // of for i
    // Wochentage des Monats
    for (i=1;i<=last_day;i++) {
        this.data[idx] = i;
        idx++;
    }   // of for i
    // Woche nach dem letzten des Monats aufüllen
    idx_stop = idx + last_wd;
    for (i=idx;i<idx_stop;i++) {
        this.data[idx] = 0;
        idx++;
    }
}   // of function
