// ~~~ Declaration of Calendar object
//
//  notes:
//   uses 0-11 range for months internal - only for disply 1-12!
//
//
//  usage:
//  var cal = new Calendar("window.document", "formular", "datefield");
//  cal.weekdaysTexts = new Array("Mo","Di","Mi","Do","Fr","Sa","So");
//  cal.monthsTexts = new Array("Januar","Februar",...);
//  cal.init(); // initializes with today's date.
//
function Calendar(returnWindow, returnForm, returnTextField, instancename) {
        this.returnWindow = returnWindow;
        this.name = instancename;
        this.returnForm = returnForm;
        this.returnTextfield = returnTextField;
        this.year = null;
        this.month = null;
        this.day = null;
        this.firstInMonth = null;
        this.firstInMonthIsWhichWeekday = null;
        this.firstInMonthIsWhichDayInTheYear = null;
        this.firstInYear = null;
        this.firstInYearIsWhichWeekday = null;
        this.firstInWeekIsWhichDate = null;

        this.lastInMonth = null;
        this.lastInMonthIsWhichWeekday = null;

        this.selectedDay = null;
        this.activeWeek = null;
        this.activeWeekday = null;
        this.daysInMonth = null;

        this.startWeek = null;
        this.weeksInMonth = null;

        this.monthsTexts = new Array();
        this.weekdaysTexts = new Array();
        this.monthLengths = Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);

        this.seekDate = "first";
        this.closeOnSetDate = false;
        this.showWeekDays = true;

        //  methods
        //  ~~~
        this.init = Calendar_initializeDate;
        this.draw = Calendar_draw;
        this.setDate = Calendar_setDate;
        this.getUserDateInput = Calendar_getUserDateInput;
        this.refReturnField = Calendar_refReturnField;

        //  initializations
        //  ~~~
        parameters= String(window.location.search).split("&");
        for(i= 1; i<parameters.length; i++) {
             if(parameters[i].indexOf("type=")==0) {
                  this.returnTextfield = parameters[i].substr(5)
             }
             if(parameters[i].indexOf("formname=")==0) {
                  this.returnForm = parameters[i].substr(9);
             }
        }

        //  try to auto-detect parent window
        if (this.returnWindow == null) {
          if (window.opener != null) {
            this.returnWindow = "window.opener.document";
          } else {
            this.returnWindow = "window.document";
          }
        }
}

function Calendar_refReturnField() {
        return this.returnWindow+"."+this.returnForm+"."+this.returnTextfield;
}

function Calendar_setDate(date,cell) {
        // colors
        activecell.className = "enabled";
        activecell = document.getElementById(cell);
        activecell.className = "active";

        // temp = "window.opener.document."+cal.returnForm+"."+cal.returnTextfield+".value = date;";
        temp = date.split(".");
        this.day = temp[0];
        this.month = temp[1];
        this.year = temp[2];
        //  implicit typecasting...
        this.day *= 1; this.month *= 1; this.year *= 1;

        // prepare for display
        temp[1] = this.month + 1;
        if (temp[0] < 10) {
          temp[0] = "0"+temp[0];
        }
        if (temp[1] < 10) {
          temp[1] = "0"+temp[1];
        }
        date = temp[0]+"."+temp[1]+"."+temp[2];

        // calculate weekday & begin week with monday
        weekday = (new Date(temp[2],temp[1]-1,temp[0])).getDay()-1;
        if (weekday == -1) weekday = 6;

        if(!this.showWeekDays)
           temp = this.refReturnField()+".value = date;";
        else
           temp = this.refReturnField()+".value = this.weekdaysTexts[weekday]+\", \"+date;";
        eval(temp);

        if (this.closeOnSetDate == true) {
          if (window.opener) {
            window.opener.focus();
            window.close();
          }
        }
}


//
// Get the user input out of the associated form field and sets
// the calendar accordingly.
//
function Calendar_getUserDateInput(ioField){
        if(this.seekDate=="first") {
            this.seekDate = null;
            eval("userInput = "+ioField+".value;");
            wDay = this.weekdaysTexts.join("|");
            reg_exp = eval("/^ *("+wDay+")\, */");
            clearedUserInput = userInput.replace(reg_exp,"");
            if(clearedUserInput==userInput)
               this.showWeekDays = false;
            userInput_day = (clearedUserInput.substring(0,clearedUserInput.indexOf(".")));
            userInput_month = (clearedUserInput.substring((clearedUserInput.indexOf(".")+1),clearedUserInput.lastIndexOf(".")));
            userInput_year = (clearedUserInput.substring((clearedUserInput.lastIndexOf(".")+1),clearedUserInput.length));
            userInput_day *= 1; userInput_month *= 1; userInput_year *= 1;
            if(userInput_day!="") {
              this.day = userInput_day;
            }
            // attention: userInput_month is 1-12-ranged!
            // ~~~
            if(userInput_month!="") {
              userInput_month -= 1;
              if(userInput_month<0) {
                userInput_month = 11;
              } else if(userInput_month>11) {
                userInput_month = 0;
              }
              this.month = userInput_month;
              if (this.day > this.monthLengths[this.month]) {
                this.day = this.monthLengths[this.month];
              }
            }
            if(userInput_year!="") {
              if(userInput_year<100) {
                if(userInput_year<50){
                   userInput_year+=2000;
                 } else {
                   userInput_year+=1900;
                 }
              } else if (userInput_year < 1000) {
                if(userInput_year<200){
                   userInput_year+=1900;
                 } else {
                   userInput_year+=1000;
                 }
              }
              this.year = userInput_year;
            }
        }   /* ENDIF seekDate==first */
        if((!this.day) && (this.day != 0)) {
        this.day = thisDay;
      }
      if((!this.month) && (this.month != 0)) {
        this.month = thisMonth;
      }
      if((!this.year) && (this.year != 0)) {
        this.year = thisYear;
      }
}


//
// Set the calendar's date to the given parameters or to the current date.
//
function Calendar_initializeDate(iyear,imonth,iday) {

      if ((isNaN(imonth) == false) && (isNaN(iday) == false) && (isNaN(iyear) == false))
      {
        if (this.monthLengths[imonth] < iday) {
          iday = this.monthLengths[imonth];
        }
        date = new Date(iyear,imonth,iday);
      } else {
        date = new Date();
      }
      thisDay = date.getDate();
      this.day = thisDay;
      // attention: month is 0-11-ranged!
      // ~~~
      thisMonth = date.getMonth();
      this.month = thisMonth;
      thisYear = date.getFullYear();
      this.year = thisYear;
      this.getUserDateInput(this.refReturnField());


// ~~ implicit typecasting:
//
      this.day *= 1; this.month *= 1; this.year *= 1;
      activeDate = new Date(this.year, this.month, this.day);

      this.activeWeekday = activeDate.getDay();
      if(this.activeWeekday == 0) {
        this.activeWeekday = 7; // because sunday is last, not first dayOfWeek in germany
      }

// ~~ which weekday was this month's first day?
//    °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
      this.firstInMonth = new Date(this.year, this.month, 1);
      this.firstInMonthIsWhichWeekday = this.firstInMonth.getDay();
      if(this.firstInMonthIsWhichWeekday == 0) {
        this.firstInMonthIsWhichWeekday = 7; // because sunday is last, not first dayOfWeek in germany
      }

// ~~ how many days have allready passed this year?
//    °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
      // 1, because 01.01. should be the first day in the year, /not/ the zero-st :)
      // ~~~
      this.firstInMonthIsWhichDayInTheYear = 1;
      for(i = 0; i < this.month; i++) {
        this.firstInMonthIsWhichDayInTheYear += this.monthLengths[i];
        if(i == 1 && isLeapYear(this.year)) {
          this.firstInMonthIsWhichDayInTheYear += 1;
        }
      }
// ~~ which weekday was 01.01. this year?
//    °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
      this.firstInYear = new Date(this.year, 0, 1);
      this.firstInYearIsWhichWeekday = this.firstInYear.getDay();
      if(this.firstInYearIsWhichWeekday == 0) {
        this.firstInYearIsWhichWeekday = 7;
      }

// ~~ The first calendar-week in our calendar:
//    °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
      this.startWeek = Math.round(((this.firstInYearIsWhichWeekday+this.firstInMonthIsWhichDayInTheYear)/7)+0.49);
      if(this.firstInMonthIsWhichWeekday == 7) {
        this.startWeek -= 1;
      }

      this.activeWeek = Math.round(((this.firstInYearIsWhichWeekday+this.firstInMonthIsWhichDayInTheYear+this.day)/7)+0.49);
      if(this.activeWeekday > 5) {
        this.activeWeek -= 1;
      }


      this.daysInMonth = this.monthLengths[this.month];
      if(this.month == 1 && isLeapYear(this.year)) {
        this.daysInMonth += 1;
      }

      this.weeksInMonth = Math.round(((this.daysInMonth+this.firstInMonthIsWhichWeekday)/7)+0.49);

      this.lastInMonth =  new Date(this.year, this.month, this.daysInMonth);
      this.lastInMonthIsWhichWeekday = this.lastInMonth.getDay();
      if(this.lastInMonthIsWhichWeekday == 0) {
        this.weeksInMonth -= 1;
      }

      this.firstInWeekIsWhichDate = this.day - this.activeWeekday + 1;
      if(this.firstInWeekIsWhichDate < 1) {
        this.firstInWeekIsWhichDate = 1;
      } else if (this.firstInWeekIsWhichDate > this.daysInMonth) {
        this.firstInWeekIsWhichDate = this.daysInMonth;
      }
}

//
// This function fills the calendar table with the days of
// the selected month and year.
//
function Calendar_draw() {
        // update header and status texts
        //  currently not used - displayed with month
        //  document.getElementById("cellyear").innerHTML = "<h1>"+this.year+"</h1>";
        document.getElementById("cellmonth").innerHTML = this.monthsTexts[this.month]+" - "+this.year;

        var currentDay;
        var tdClass;
        var i = (2 - this.firstInMonthIsWhichWeekday);

        if (this.day > this.monthLengths[this.month]) {
          this.day = 1;
        }
        //  Always redraw all 6 rows...to clean up...
        for(var w = 0; w < 6; w++) {
            for(var d = 0; d < 7; d++) {
              elem = document.getElementById("dayfield_"+((w*7)+d+1));

              if(i > 0 && i < this.daysInMonth+1) {
                //  convert to string
                currentDay = ""+i;

                //  highlight selected day
                if(this.day == i && i != 0) {
                  elem.className = "active";
                  activecell = elem;
                } else {
                  elem.className = "enabled";
                }
                elem.innerHTML = currentDay;
                //  ACHTUNG: fieser Trick!
                //  damit die onClick Funktion ordentlich funktioniert, wird ein Verweis auf
                //  den Inhalt (innerHTML) der Zelle gemacht, da ansonsten das !letzte! Datum
                //  genommen wird (nach dem Durchlauf dieser Schleifen).
                //  Sollten statt der einfachen Zahlen irgendwann einmal andere Dinge dort stehen
                //  (Grafiken, ...) dann könnte man über das "name" Attribut des Elementes ausweichen.
                elem.onclick = function(){cal.setDate(this.innerHTML+"."+(cal.month)+"."+cal.year,this.id);};

                // temp = "function(){"+this.name+".setDate(this.innerHTML+\".\"+("+this.name+".month)+\".\"+"+this.name+".year,this.id);};";
                // elem.onclick = temp;
                //  save active cell
              } else {
                elem.className = "disabled";
                elem.innerHTML = "&nbsp;";
                elem.onclick = null;
              }

              i++;
            }
        }
} // - END function Calendar_draw();


