 function Calendar(twoway, returnFormname, returnPathDay, returnPathYear, returnHiddenField, instancename, startday, startmonth, startyear) {
   //  methods
   //  ~~~
   this.getHowManyDays         = Calendar_getHowManyDays;
   this.setFullMonthsOnly      = Calendar_setFullMonthsOnly;
   this.setOneMonthOnly        = Calendar_setOneMonthOnly;
   this.nextMonth              = Calendar_nextMonth;
   this.prevMonth              = Calendar_prevMonth;
   this.draw                   = Calendar_draw;
   this.setDate                = Calendar_setDate;
   this.getStartDateFromString = Calendar_getStartDateFromString;
   this.getStartDateFrom       = Calendar_getStartDateFrom;
   this.getEndDateFromString   = Calendar_getEndDateFromString;
   this.getEndDateFrom         = Calendar_getEndDateFrom;
   this.parseUserDateInput     = Calendar_parseUserDateInput;
   this.getCellName            = Calendar_getCellName;
   this.setPreselectedDate     = Calendar_setPreselectedDate;
   this.hideCallBack           = Calendar_hideCallBack;


   //  fields
   //  ~~~
   this.twoway = twoway;
   this.name = instancename;
   this.refReturnFormname = returnFormname;
   this.refReturnDayField = returnPathDay;
   this.refReturnYearField = returnPathYear;
   this.refReturnHiddenField = returnHiddenField;
   this.useDataPeriod = true;
   this.readOnly = true;
   this.showWeekNumbers = true;
   this.setScrollable = true;
   this.internalScrollers = true;
   // deactivates all days before "preselected"
   this.disablePast = true;

   this.viewPeriodS = new Date(startyear,startmonth,startday);
   this.viewPeriodE = new Date(startyear,startmonth,startday);
   this.dataPeriodS = null;
   this.dataPeriodE = null;

   if (this.twoway == false) {
      this.refReturnField = this.refReturnFormname+"."+returnPathDay;
   }

   // check start date parameters - default: value in return field
   if (!this.viewPeriodS.getDate()) {
      if (eval(this.refReturnField) != undefined) {
         this.getStartDateFromString( eval( this.refReturnField+".value" ) );
      } else {
         this.getStartDateFromString("today");
      }
      // PeriodEnd is set in setOneMonthOnly() ...
   }
   this.today = new Date();

   this.selectedDays = new Array();
   this.selectToday = true;
   this.multipleSelect = false;

   this.fullMonthsOnly = true;
   this.setOneMonthOnly(true);
   this.scrollable = true;
   this.hideCallBackName = "";

   this.monthsTexts = new Array();
   this.weekdaysTexts = new Array();
   this.prevMonthHTML = "&lt;";
   this.nextMonthHTML = "&gt;";
   this.weekNoHTML    = "&nbsp;";

   this.closeOnSetDate = true;
   this.showShortYear = false;
   this.howManyDays = 0;
}

function Calendar_prevMonth() {
   this.viewPeriodS.setMonth(this.viewPeriodS.getMonth()-1);
   this.viewPeriodE.setDate(1);
   this.viewPeriodE.setDate(this.viewPeriodE.getDate()-1);
   this.draw();
}

function Calendar_nextMonth() {
   this.viewPeriodS.setMonth(this.viewPeriodS.getMonth()+1);

   this.viewPeriodE.setDate(1);
   this.viewPeriodE.setMonth(this.viewPeriodE.getMonth()+2);
   this.viewPeriodE.setDate(1);
   this.viewPeriodE.setDate(this.viewPeriodE.getDate()-1);
   this.draw();
}

function Calendar_setFullMonthsOnly(truefalse) {
   this.fullMonthsOnly = truefalse;
   if (this.fullMonthsOnly) {
      this.viewPeriodE = new Date(this.viewPeriodE.getFullYear(),this.viewPeriodE.getMonth()+1,1);
      this.viewPeriodE.setDate(this.viewPeriodE.getDate()-1);
   }
}

function Calendar_setOneMonthOnly(truefalse) {
   // Set viewport to one full month
   this.oneMonthOnly = truefalse;
   if (this.oneMonthOnly) {
      this.viewPeriodS = new Date(this.viewPeriodS.getFullYear(), this.viewPeriodS.getMonth(), 1);
      this.viewPeriodE = new Date(this.viewPeriodS.getFullYear(),this.viewPeriodS.getMonth()+1,1);
      this.viewPeriodE.setDate(this.viewPeriodE.getDate()-1);
   }
}

function Calendar_getHowManyDays() {
   var tempdate = new Date( this.viewPeriodS.getFullYear(),this.viewPeriodS.getMonth(),this.viewPeriodS.getDate() );
   var days = 0;
   while (tempdate.getTime() <= this.viewPeriodE.getTime()) {
      days++;
      tempdate.setDate(tempdate.getDate()+1);
   }
   return days;
}

function Calendar_getStartDateFrom(ioField) {
   eval("userInput = "+this.returnWindow+"."+this.returnForm+"."+ioField+".value;");
   this.getStartDateFromString(userInput);
}

function Calendar_getStartDateFromString(datestring) {
   if (datestring == "today") {
      this.viewPeriodS = new Date();
   } else {
      this.viewPeriodS = this.parseUserDateInput(datestring);
      if (this.viewPeriodS == undefined) {
         this.viewPeriodS = new Date();
      }
   }
}

function Calendar_getEndDateFrom(ioField) {
   eval("userInput = "+this.returnWindow+"."+this.returnForm+"."+ioField+".value;");
   this.getEndDateFromString(userInput);
}


function Calendar_getEndDateFromString(datestring) {
   this.viewPeriodE = this.parseUserDateInput(datestring);
}


function Calendar_setPreselectedDate(date) {
   // read date from given inputfields
   if (!isDate(date)) {
     if (this.twoway) {
        var day = null;
        var year = null;

        var temp = "day = "+this.refReturnFormname+"."+this.refReturnDayField+".value;";
        eval(temp);
        day *= 1;
        temp = "year = "+this.refReturnFormname+"."+this.refReturnYearField+".value;";
        eval(temp);

        year = year.split("_");
        date = new Date(year[1],year[0],day);
     } else {
//        date = this.parseUserDateInput(eval (this.refReturnField+".value"));
        date = this.parseUserDateInput(document.forms[this.refReturnField.replace(/document\.(.*)\..*/,"$1")].elements[this.refReturnHiddenField].value);
     }

   }
   this.selectedDays.pop();
   this.selectedDays.push(new Date(date));
   this.viewPeriodS = new Date(date);
   this.viewPeriodS.setDate(1);

   this.viewPeriodE = new Date(date);
   this.viewPeriodE.setDate(1);
   this.viewPeriodE.setMonth(this.viewPeriodE.getMonth()+1);
   this.viewPeriodE.setDate(1);
   this.viewPeriodE.setDate(this.viewPeriodE.getDate()-1);
}

// Speziell fuer Daenemark!
function Calendar_hideCallBack() {
   // da es nur 2 Kalender geben kann - letztes Zeichen nehmen
   var temp = this.name.charAt(this.name.length-1);
   temp = this.hideCallBackName+"('"+temp+"');";
   eval(temp);
}

function Calendar_parseUserDateInput(userInput){
   if (isString(userInput)) {
      var matchReg = /(\d+)\D+(\d+)\D+(\d+)\D*/;
      matchReg.exec( userInput );

      var userInput_day   = RegExp.$1;
      var userInput_month = RegExp.$2;
      var userInput_year  = RegExp.$3;

      userInput_day *= 1; userInput_month *= 1; userInput_year *= 1;
      // 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;
         }
      }
      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;
            }
         }
      }
      if  ((userInput_year != 0) && (userInput_day != 0)) {
        return new Date(userInput_year, userInput_month, userInput_day);
      }

   } else if (isDate(userInput)) {
     return userInput;
   }

   return null;
}

function Calendar_getCellName(date) {
   return this.name+"_df_"+date.getFullYear()+"/"+(date.getMonth())+"/"+date.getDate();
}

// This function toggles the given date's style
function Calendar_setDate(cell) {
  // set the colors by style
   if (!this.readOnly) {
      if (this.multipleSelect) {
         var tempday = document.getElementById(cell);
         tempday.className = (tempday.className == "active") ? "enabled" : "active";
      } else {
         // remove old selection - select ONE day only
         if (this.selectedDays.length == 1) {
            tempday = document.getElementById(this.getCellName(this.selectedDays[0]));
           if (tempday != null) {
              modifyClassName(tempday, "active", false);
              modifyClassName(tempday, "enabled", true);
           }
         }
         tempday = document.getElementById(cell);
         modifyClassName(tempday, "active", true);
         //tempday.className = (tempday.className == "active") ? "enabled" : "active";

         var dayField = "input_day"+this.name.substr(6,1);
         var date = cell.substring((this.name.length)+4,cell.length);
         var temp = date.split("/");
         var year = 1*temp[0];
         var month = 1*temp[1];
         var day = 1*temp[2];


         var datum = new Date(year,month,day);
         this.selectedDays.pop();
         this.selectedDays.push(new Date(datum));

         if (this.twoway) {
            syncDays(dayField,datum,periodStart,periodEnd,false);
            temp = this.refReturnFormname+"."+this.refReturnDayField+".value = "+datum.getDate();
            eval(temp);
            temp = this.refReturnFormname+"."+this.refReturnYearField+".value = '"+(datum.getMonth())+"'+'_'+'"+datum.getFullYear()+"'";
            eval(temp);
            temp = this.refReturnFormname+"."+this.refReturnHiddenField+".value = '"+datum.getDate()+"."+(datum.getMonth()+1)+"."+datum.getFullYear()+"'";
            eval(temp);
            var calid = this.name.charAt(this.name.length-1);
            correctReturnSelection(calid, this.twoway);
         } else {
            date = formatDate(datum,false);
            // calculate weekday & begin week with monday
            var weekday = datum.getDay()-1;
            if (weekday == -1) weekday = 6;
            temp = this.refReturnField+".value = this.weekdaysTexts[weekday]+\", \"+date;";
            eval(temp);
         }
         this.hideCallBack();
      }
   }
}


//
// This function fills the calendar table with the days of
// the selected month and year.
function Calendar_draw() {
   this.howManyDays = this.getHowManyDays();

   if (this.bitfield && this.useDataPeriod) {
      // calc difference in days between viewPeriodS and dataPeriodS
      // to find bitfield begin...
      var tempdate = new Date(this.dataPeriodS);
      var bitfieldindex = 0;
      if (tempdate.getTime() < this.viewPeriodS.getTime()) {
         while (tempdate.getTime() < this.viewPeriodS.getTime()) {
            bitfieldindex++;
            tempdate.setDate(tempdate.getDate()+1);
         }
      } else {
         while (tempdate.getTime() > this.viewPeriodS.getTime()) {
            bitfieldindex--;
            tempdate.setDate(tempdate.getDate()-1);
         }
      }
   }

   var div = document.getElementById(this.name);
   // create table if it does not already exist
   var table = document.getElementById(this.name+"_table");
   if (table == null) {
      table = document.createElement("TABLE");
      div.insertBefore(table,div.firstChild);
      table.setAttribute("cellSpacing", "0");
      table.style.width = "100%";
      table.id = this.name+"_table";
      table.className = "calendar";
   }

   // Recycling: remove complete table body...it's recreated => fast delete?
   var tbody = document.getElementById(this.name+"_tbody");
   if (tbody != null) {
      tbody.parentNode.removeChild(tbody);
   }

   // (re-)create tbody
   tbody = document.createElement("TBODY");
   table.appendChild(tbody);
   tbody.id = this.name+"_tbody";
   // update header and status texts
   tempdate = new Date(this.viewPeriodS.getFullYear(),this.viewPeriodS.getMonth(),this.viewPeriodS.getDate());

   // show month name above weekdays
   if (this.oneMonthOnly) {
      // create row for month name
      current_row = document.createElement("TR");
      if (this.scrollable) {
         if (this.internalScrollers) {
            current_cell= document.createElement("TH");
            current_cell.id = this.name+"_heading_months_lt";
         } else {
            current_cell = document.getElementById(this.name+"prev");
         }
         var tempdate2 = new Date(tempdate);
         tempdate2.setDate(1);
         var thistoday = new Date(this.today);
         thistoday.setDate(1);
         if ( ( (!this.useDataPeriod) ||
                (!this.dataPeriodS) ||
                (this.dataPeriodS && (tempdate2.getTime() > this.dataPeriodS.getTime())))
            ) {
            current_cell.innerHTML=this.prevMonthHTML;
            current_cell.className = "prevMonth";
            if (this.internalScrollers) {
               current_cell.onclick = function() {
                  var calid = this.id.substring(0,this.id.indexOf("_heading_months_lt"));
                  var test = eval('calid')+".prevMonth();";
                  eval(test);
               }
            } else {
               current_cell.onclick = function() {
                  var calid = this.id.substring(0,this.id.indexOf("prev"));
                  var test = eval('calid')+".prevMonth();";
                  eval(test);
               }
            }
         } else {
            current_cell.innerHTML= "";
            current_cell.className = "disabled";
         }
         if (this.internalScrollers) {
            current_row.appendChild(current_cell);
         }
      }
      current_cell= document.createElement("TH");
      current_cell.colSpan = ( (this.scrollable) && (this.internalScrollers) ) ? 6 : 8;
      current_cell.innerHTML = this.monthsTexts[tempdate.getMonth()]+"&nbsp;"+tempdate.getFullYear();
      current_cell.textAlign="center";
      current_cell.id = this.name+"_heading_months"+tempdate.getMonth();
      if (this.multipleSelect) {
         current_cell.className = "heading_months_enabled";
         current_cell.onclick = function() {
            var calid = this.id.substring(0,this.id.indexOf("_heading_months"));
            var month = this.id.substring(this.id.indexOf("_heading_months")+15,this.id.length);
            var test = eval('calid')+".selectMonth(month);";
            eval(test);
         }
      } else {
         current_cell.className = "heading_months_disabled";
      }
      current_row.appendChild(current_cell);
      if (this.scrollable) {
         if (this.internalScrollers) {
            current_cell = document.createElement("TH");
            current_cell.id = this.name+"_heading_months_gt";
         } else {
            current_cell = document.getElementById(this.name+"next");
         }
         var tempdate2 = new Date(tempdate);
         tempdate2.setDate(1);
         tempdate2.setMonth(tempdate2.getMonth()+1);
         tempdate2.setDate(tempdate2.getDate()-1);
         if ( (!this.useDataPeriod) ||
              (!this.dataPeriodE) ||
              (this.dataPeriodE && (tempdate2.getTime() < this.dataPeriodE.getTime() ))
            ) {
            current_cell.innerHTML=this.nextMonthHTML;
            current_cell.className = "nextMonth";
            if (this.internalScrollers) {
               current_cell.onclick = function() {
                  var calid = this.id.substring(0,this.id.indexOf("_heading_months_gt"));
                  var test = eval('calid')+".nextMonth();";
                  eval(test);
               }
            } else {
               current_cell.onclick = function() {
                  var calid = this.id.substring(0,this.id.indexOf("next"));
                  var test = eval('calid')+".nextMonth();";
                  eval(test);
               }
            }
          } else {
            current_cell.innerHTML="";
            current_cell.className = "disabled";
         }
         if (this.internalScrollers) {
            current_row.appendChild(current_cell);
         }
      }

      tbody.appendChild(current_row);
   }

   // write weekday names in first (or second) row
   var row = document.createElement("TR");

   // week numbers
   if (this.showWeekNumbers) {
      var cell = document.createElement("TH");
      cell.id = this.name+"_heading_"+d;
      cell.className = "heading_daynames";
      cell.innerHTML = this.weekNoHTML;
      row.appendChild(cell);
   }

   for (d = 0 ; d < 7 ; d++) {
      var cell = document.createElement("TH");
      cell.id = this.name+"_heading_"+d;
      cell.innerHTML = this.weekdaysTexts[d];
      if (this.multipleSelect) {
         cell.className = "enabled";
         cell.onclick = function() {
            var calid = this.id.substring(0,this.id.indexOf("_heading_"));
            var day = this.id.substring(this.id.indexOf("_heading_")+9,this.id.length);
            var test = eval('calid')+".selectDays(day);";
            eval(test);
         }
      } else {
         cell.className = "heading_daynames";
      }
      if(d == 5 || d == 6) {
         cell.className += " weekend";
      } else {
         cell.className += " workday";
      }
      row.appendChild(cell);
   }

   tbody.appendChild(row);

   // Calculate skip between first table cell and first one with content (which
   // weekday does the calendar start with)
   // if it is 0 (sunday) set to 6 as the week begins on monday
   daystoskip = (tempdate.getDay()-1 < 0) ? 6 : tempdate.getDay()-1;

   var daysdrawn = 0;
   var newmonth = false;
   var oldtempcolspan = 0;
   var colspan = 1;

   var w = -1;
   var startweek = tempdate.getWeek();
   var newWeekNeeded = true;
   while (newWeekNeeded) {
      w++;

      if (((tempdate.getDate() == 1 && newmonth) || (daysdrawn == 0)) && (tempdate.getTime() >= this.viewPeriodS.getTime())) {
         // a new month begins...

         // which weekday is the current date (e.g. 1st April 2005 is a Friday (5))?
         // if it is 0 (sunday) set to 6 as the week begins on monday
         daystoskip = (tempdate.getDay()-1 < 0) ? 6 : tempdate.getDay()-1;

         if (this.oneMonthOnly == false) {
            // create row for month name
            current_row = document.createElement("TR");
            current_cell= document.createElement("TD");
            current_cell.colSpan = 7;
            //current_cell.innerHTML = "<b>"+this.monthsTexts[tempdate.getMonth()]+" - "+tempdate.getFullYear()+"</b>";
            current_cell.innerHTML = this.monthsTexts[tempdate.getMonth()]+" - "+tempdate.getFullYear();
            current_cell.id = this.name+"_heading_months"+tempdate.getMonth();
            if (this.multipleSelect) {
               current_cell.className = "enabled";
               current_cell.onclick = function() {
                  var calid = this.id.substring(0,this.id.indexOf("_heading_months"));
                  var month = this.id.substring(this.id.indexOf("_heading_months")+15,this.id.length);
                  var test = eval('calid')+".selectMonth(month);";
                  eval(test);
               }
            } else {
               current_cell.className = "disabled";
            }
            current_row.appendChild(current_cell);

            tbody.appendChild(current_row);
         }

      }

      current_row = document.getElementById(this.name+"_row_"+w);
      if (current_row == null) {
         current_row = document.createElement("TR");
         current_row.id = this.name+"_row_"+w;
         tbody.appendChild(current_row);
      }

      if (this.showWeekNumbers) {
         cell = document.createElement("TD");
         cell.className = "weekno";
         cell.innerHTML = startweek++;
         current_row.appendChild(cell);
      }

      // draws week rows
      for (var d = 0; d < 7; d++) {

         if ((tempdate.getDate() == 1 && newmonth == false) && (daysdrawn != 0)) {
            newmonth = true;
            // append remaining empty cells
//          var td2 = new Date(tempdate);
            for (var e = d; e < 7; e++) {
               cell = document.createElement("TD");
               cell.className = "disabled";
//             cell.innerHTML = td2.getDate();
               // da anfangs schon um 1 erhoeht!
//             td2.setDate(td2.getDate()+1)
               cell.innerHTML = "&nbsp;";
               if (current_row != null) {
                  current_row.appendChild(cell);
               }
            }
            break;
         }

         cell = document.createElement("TD");

         if (daystoskip <= 0 && daysdrawn < this.howManyDays) {
            newmonth = false;
            // Change table cells id to represent current displayed date
            cell.id = this.name+"_df_"+tempdate.getFullYear()+"/"+(tempdate.getMonth())+"/"+tempdate.getDate(); //+"-"+((w*7)+d+1);

            if ((this.useDataPeriod) && (bitfieldindex+daysdrawn >= 0) && (this.dataPeriodS) && (this.dataPeriodE) && (tempdate.getTime() <= this.dataPeriodE.getTime())) {
               cell.className = (this.bitfield.charAt(bitfieldindex+daysdrawn) == "1") ? "working" : "notworking";
            } else {
               cell.className = (this.readOnly == true) ? "disabled" : "enabled";
               if (this.selectedDays.length == 1) {
                  if (tempdate.getTime() == this.selectedDays[0].getTime()) {
                     //cell.className += " active";
                     modifyClassName(cell, "active", true);
                  }
               }
               if(d == 5 || d == 6) {
                  cell.className += " weekend";
               } else {
                  cell.className += " workday";
               }
            }
            cell.innerHTML = tempdate.getDate(); //+":"+(bitfieldindex+daysdrawn)+"-"+this.bitfield.charAt(bitfieldindex+daysdrawn);
            cell.onclick = function(){
               var calid = this.id.substring(0,this.id.indexOf("_df"));
               var test = eval('calid')+".setDate(this.id);";
               eval(test);
            };
            // increase already drawn days by one
            tempdate.setDate(tempdate.getDate()+1);
            daysdrawn += 1;

            //  deactivate cell
         } else {
            cell.className = "disabled";
            //cell.innerHTML = "&nbsp;";
            var td2 = new Date(tempdate);
            td2.setDate(td2.getDate()-daystoskip)
            //cell.innerHTML = td2.getDate();
            cell.innerHTML = "&nbsp;";
            cell.onclick = null;
            daystoskip -= 1;
         }

         // quickhack
         tempdate.setDate(tempdate.getDate()-1);
         if (tempdate.getTime() < this.dataPeriodS.getTime()) {
            cell.className = "disabled";
            cell.onclick = null;
         }
         if (tempdate.getTime() > this.dataPeriodE.getTime()) {
            cell.className = "disabled";
            cell.onclick = null;
         }
         tempdate.setDate(tempdate.getDate()+1);

         current_row.appendChild(cell);
      }
      if ((tempdate > this.viewPeriodE) || (daysdrawn >= this.howManyDays)) {
         newWeekNeeded = false;
      }

   }

   if (w < 5) {
      var row = document.createElement("TR");
      for (var i=0; i <= 7; i++) {
         var cell = document.createElement("TD");
         cell.className = "disabled";
         cell.innerHTML = "&nbsp;";
         row.appendChild(cell);
      }
      tbody.appendChild(row);
   }

   // auto-correction of div size
   document.getElementById(this.name).style.width = "auto";
} // - END function Calendar_draw();

Calendar.prototype.getFromVKHEXBitfield = function(bitfield) {
   this.dataPeriodS = new Date("20"+bitfield.substr(4,2),bitfield.substr(2,2),bitfield.substr(0,2));
   this.dataPeriodS.setMonth(this.dataPeriodS.getMonth() - 1);

   this.dataPeriodE = new Date("20"+bitfield.substr(10,2),bitfield.substr(8,2),bitfield.substr(6,2));
   this.dataPeriodE.setMonth(this.dataPeriodE.getMonth() - 1);

   bitfield = bitfield.substring(12,bitfield.length);

   // convert hexadecimal to binary
   this.bitfield = "";
   var temp = "";

   for (var i=0; i < bitfield.length;i += 2) {
      temp = (parseInt(bitfield.substring(i,i+2),16)).toString(2);
      while (temp.length < 8) {
         temp = "0"+temp;
      }
      this.bitfield = this.bitfield + temp;
   }
}


// temporary place for some useful functions - due to be put somewhere else!
// ###############################################################################

// Synchronizes select "fields" with hidden date filed
function syncToHidden(calid) {
   var inputday = document.getElementById("input_day"+calid);
   var inputyear = document.getElementById("input_year"+calid);

   var day = inputday.value;
   var temp = inputyear.value;
   temp = temp.split("_");
   var month = temp[0];
   month *= 1;
   month++;
   var year = temp[1];
   var fname = "caldiv"+calid+".refReturnFormname";
   fname = eval(fname);
   var ename = "caldiv"+calid+".refReturnHiddenField";
   ename = eval(ename);
   if (ename != null) {
     temp = fname+"."+ename+".value = '"+day+"."+month+"."+year+"';";
     eval(temp);
   }
}

function getDateSelects(calid) {
   if (
        (!document.getElementById("input_day"+calid)) &&
        (!document.getElementById("input_year"+calid))
      ) {
     return;
   }
   var inputday = document.getElementById("input_day"+calid);
   var inputyear = document.getElementById("input_year"+calid);

   var day = inputday.value;
   var temp = inputyear.value;
   temp = temp.split("_");
   var month = temp[0];
   month *= 1;
   month++;
   var year = temp[1];
   var date = new Date(year,month-1,day);
   if (isDate(date)) {
      return date;
   } else {
      return null;
   }
}

function setDateSelects(calid,date,twoway) {
   var inputday = document.getElementById("input_day"+calid);
   var inputyear = document.getElementById("input_year"+calid);

   var s = date.getDate();
   if (s < 10) {
        s = "0"+s;
   }
   inputday.text = s;
   inputday.value= date.getDate();
   inputyear.value = (date.getMonth())+'_'+date.getFullYear();
   if (twoway) {
      syncToHidden(calid);
   }
}

// sets return journey date >= departure
function correctReturnSelection(calid,twoway) {
   var depdate = getDateSelects("0");
   var retdate = getDateSelects("1");

   if (calid == 0) {
      if (undefined != depdate) {

         var td = new Date(depdate);
         td.setDate(td.getDate());

         if (undefined != retdate) {

           if (depdate.getTime() >= retdate.getTime()) {
             setDateSelects("1",td,twoway);
             syncDays('input_day1',td,periodStart,periodEnd,false);
           }
           if (td.getTime() > periodEnd.getTime()) {
             setDateSelects("1",depdate,twoway);
             syncDays('input_day1',depdate,periodStart,periodEnd,false);
           }
           syncToHidden(1);
         }
      }
   }
   if (calid == 1) {
      if (undefined != retdate) {
        syncDays('input_day1',retdate,periodStart,periodEnd,false);
      }
   }
}

// synchronizes day with days of month and period.
function syncDays(field,value,periodS,periodE,firstcall) {

  if (isString(value)) {
     value = value.split("_");
     var tempdate = new Date(value[1],value[0],1);
  } else if (isDate(value)) {
     var tempdate = new Date(value);
  } else {
     return;
  }

  var input = document.getElementById(field);
  var saveit = (firstcall) ? tempdate.getDate() : input.value;

  if((periodS) && (periodE)) {
     periodS = Calendar_parseUserDateInput(periodS);
     periodE = Calendar_parseUserDateInput(periodE);

     var monthS = periodS.getMonth();
     var yearS = periodS.getFullYear();

     var monthE = periodE.getMonth();
     var yearE = periodE.getFullYear();

     var thismonth = tempdate.getMonth();
     var thisyear = tempdate.getFullYear();
     var dayS = 1;
     var dayE = tempdate.getDaysInMonth();

     var mydate = new Date(tempdate);
     mydate.setDate(1);

     // wenn der aktuelle Tag im Monat des Periodenanfangs liegt:
     if ( ( (thismonth == monthS) && (thisyear == yearS) ) && (periodS.getDate() > 1 )) {
       dayS = periodS.getDate();
     }

     // wenn der aktuelle Tag im Monat des Periodenendes liegt:
     if ( ( (thismonth == monthE) && (thisyear == yearE)) && (periodE.getDate() < mydate.getDaysInMonth() ) ) {
       dayE = periodE.getDate();
       saveit = (periodE.getDate() < saveit) ? periodS.getDate() : saveit;
     }
  }
  var d = -1;
  // empty options
  var o = input.options;
  var anz = o.length;
  for (var i = 0; i < anz;i++) {
     o[0] = null;
  }

  for (var i = 1; i <= tempdate.getDaysInMonth(); i++) {
    if( (i >= dayS) && (i <= dayE) ) {
      d++;
      var i2 = i;
      if (i2 < 10 ) {
         i2 = "0"+i2;
      }
      o[d] = new Option(i2,i);
      if (i == saveit) {
         o[d].selected = true;    }
      }
  }
}


function printMonths(field, periodS, periodE, preselection) {

  var input = document.getElementById(field);
  var dateS = new Date(periodS);
  var dateE = new Date(periodE);

  while (dateS.getTime() <= dateE.getTime()) {
    if ( (dateS.getMonth() == preselection.getMonth()) && (dateS.getFullYear() == preselection.getFullYear()) ) {
       input.options[input.options.length] = new Option(monthsTextsShort[dateS.getMonth()]+' '+dateS.getFullYear(),dateS.getMonth()+"_"+dateS.getFullYear(),true,true);
       input.options[input.options.length-1].selected = true;
    } else {
       input.options[input.options.length] = new Option(monthsTextsShort[dateS.getMonth()]+' '+dateS.getFullYear(),dateS.getMonth()+"_"+dateS.getFullYear());
    }
    dateS.setDate(1);
    dateS.setMonth(dateS.getMonth()+1);
  }
}
function getDim(el){
	for (var lx=0,ly=0;el!=null;
		lx+=el.offsetLeft,ly+=el.offsetTop,el=el.offsetParent);
	return {x:lx,y:ly}
}


function moveToBody(element) {
   var child = element.parentNode.removeChild(element);
   document.body.appendChild(child);
   return child;
}

function toggleDivCal(calid,topflip) {
   var distyle = "inline";

   // FIX: Pendlerfahrplan
   if (document.hafasform.timeselectfrom) {
      document.hafasform.timeselectfrom.style.display = (document.hafasform.timeselectfrom.style.display != "none") ? "none" : distyle;
   }

   var callink = document.getElementById("callink"+calid);

   var div = document.getElementById("calendar"+calid);
   moveToBody(div);
   div.style.position="absolute";

   var shadow = document.getElementById("calendarshadow"+calid);
   moveToBody(shadow);
   shadow.style.position="absolute";

   var iframe = document.getElementById("calendariframe"+calid);
   if (iframe == null) {
      iframe = document.createElement("iframe");
   }
   document.body.appendChild(iframe);
   iframe.id = "calendariframe"+calid;
   iframe.style.position="absolute";
   iframe.width = Element.getWidth(div)+"px";
   iframe.height = Element.getHeight(div)+"px";

   var dim = getDim(document.getElementById("callink"+calid));

   // display:
   div.style.display = (div.style.display != "none") ? "none" : distyle;
   shadow.style.display = div.style.display;
   iframe.style.display = div.style.display;

   if (!topflip) {
     div.style.top = (dim.y-1)+"px";
     div.style.left = (dim.x-1)+"px";

     shadow.style.top = (dim.y+1)+"px";
     shadow.style.left = (dim.x+1)+"px";

     iframe.style.top = (dim.y+1)+"px";
     iframe.style.left = (dim.x+1)+"px";
   } else {
      div.style.top = (dim.y+Element.getHeight(callink)-Element.getHeight(div))+"px";
      div.style.left = (dim.x-1)+"px";

      shadow.style.top = (dim.y+4+Element.getHeight(callink)-Element.getHeight(div))+"px";
      shadow.style.left = (dim.x-1)+"px";

      iframe.style.top = (dim.y+Element.getHeight(callink)-Element.getHeight(div))+"px";
      iframe.style.left = (dim.x-1)+"px";
   }

}

function formatDate(date, showShortYear) {
   // prepare for display
   if (isDate(date)) {

      var day = date.getDate();
      var month = date.getMonth() + 1;
      var year = date.getFullYear();

      if (day < 10) {
         day = "0"+day;
      }
      if (month < 10) {
         month = "0"+month;
      }

      // has to be after the previous step for interpreting purposes
      if (showShortYear) {
         year -= 2000;
         if (year < 10) {
            year = "0"+year;
         }
      }
      return day+"."+month+"."+year;
   } else {
      return null;
   }
}

function modifyClassName(element, style, activate) {
   var css = " "+element.className+" ";
   if (activate) {
      // not present -> append
      if (css.search(" "+style+" ") > -1) {
      } else {
         css = css+style;
      }
   } else {
      css = css.replace(" "+style+" ", " ");
   }
   css = css.replace(/^\s+/, "").replace(/\s+$/, "");
   element.className = css;
}


