function CalendarRange(returnWindow, returnForm, returnTextField, instancename, startday, startmonth, startyear, howmanydays) {
   //  methods
   //  ~~~
   this.setHowManyDays         = CalendarRange_setHowManyDays;
   this.setHowManyMonths       = CalendarRange_setHowManyMonths;
   this.setFullMonthsOnly      = CalendarRange_setFullMonthsOnly;
   this.setScrollable          = CalendarRange_setScrollable;
   this.nextMonth              = CalendarRange_nextMonth;
   this.prevMonth              = CalendarRange_prevMonth;
   this.draw                   = CalendarRange_draw;
   this.setDate                = CalendarRange_setDate;
   this.getStartDateFromString = CalendarRange_getStartDateFromString;
   this.getStartDateFrom       = CalendarRange_getStartDateFrom;
   this.getEndDateFromString   = CalendarRange_getEndDateFromString;
   this.getEndDateFrom         = CalendarRange_getEndDateFrom;
   this.parseUserDateInput     = CalendarRange_parseUserDateInput;
   this.refReturnField         = CalendarRange_refReturnField;

   this.minDate = new Date(2006,11,10);
   this.maxDate = new Date(2007,11,8);
   //  fields
   //  ~~~

   this.returnWindow = returnWindow;
   this.name = instancename;
   this.returnForm = returnForm;
   this.returnTextfield = returnTextField;

   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);
        }
   }

   if (this.refReturnField())
     {
      temp = eval(this.refReturnField()+".value;");
      startyear = '20'+temp.substr(0,2);
      startmonth = temp.substr(3,2);
      startday = temp.substr(6,2);
     }

   this.startday   = startday*1;
   this.startmonth = startmonth-1;
   this.startyear  = startyear*1;
   // check start date parameters - default: today
   if ((!this.startday) || ((!this.startmonth)&&(this.startmonth != 0)) || (!this.startyear)) {
      var tempstartdate = new Date();
      this.startday = tempstartdate.getDate();
      this.startmonth = tempstartdate.getMonth();
      this.startyear = tempstartdate.getFullYear();
   }

   this.endday     = null;
   this.endmonth   = null;
   this.endyear    = null;

   this.lastdrawstartday   = null;
   this.lastdrawstartmonth = null;
   this.lastdrawstartyear  = null;
   this.lastdrawendday     = null;
   this.lastdrawendmonth   = null;
   this.lastdrawendyear    = null;

   this.howmanydays = 1;
   this.howmanymonths = 1;
   this.howmanymonthsmax = 4;

   this.selectedDay = this.name+"_df_"+this.startyear+"/"+this.startmonth+"/"+this.startday;
   this.multipleSelect = false;

   this.fullMonthsOnly = true;
   this.oneMonthOnly = true;
   this.scrollable = false;

   this.monthsTexts = new Array();
   this.weekdaysTexts = new Array();
   this.prevMonthHTML = "&lt;";
   this.nextMonthHTML = "&gt;";

   this.closeOnSetDate = false;
   this.showShortYear = false;


   //  initializations
   //  ~~~
   this.setHowManyDays(howmanydays);

   // calc enddate
   var tempdate = new Date(this.startyear, this.startmonth, this.startday);
   var daycount = 0;
   while (daycount <= this.howmanydays) {
      daycount++;
      tempdate.setDate(tempdate.getDate()+1);
   }
   this.endday = tempdate.getDate();
   this.endmonth = tempdate.getMonth();
   this.endyear = tempdate.getFullYear();

   // try to auto-detect parent window (which ultimately holds the inputfield)
   // ~~
   if (this.returnWindow == null) {
     if (window.opener != null) {
       this.returnWindow = "window.opener.document";
     } else {
       this.returnWindow = "window.document";
     }
   }
}

function CalendarRange_prevMonth() {
   this.startmonth--;
   this.selectedDay = null;
   this.setHowManyDays(90);
   this.draw();
}

function CalendarRange_nextMonth() {
   this.startmonth++;
   this.selectedDay = null;
   this.setHowManyDays(90);
   this.draw();
}

function CalendarRange_setFullMonthsOnly(truefalse) {
  this.fullMonthsOnly = truefalse;
  // recalculate enddate
  this.setHowManyDays(90);
}

function CalendarRange_setScrollable(truefalse) {
   this.scrollable = truefalse;
}

function CalendarRange_setHowManyDays(howmanydays) {
   if (this.fullMonthsOnly == true) {
      // show only full months
      this.startday = 1;
      var tempstartdate = new Date(this.startyear, this.startmonth, this.startday);
      this.howmanydays = 0;
      var savemonth = -1;
      var monthcount = 0;

      while (monthcount <= this.howmanymonths) {
         this.howmanydays++;
         if (tempstartdate.getMonth() != savemonth) {
            savemonth = tempstartdate.getMonth();
            monthcount++;
         }
         tempstartdate.setDate(tempstartdate.getDate()+1);
      }
      tempstartdate.setDate(tempstartdate.getDate()-2);
      this.endyear = tempstartdate.getFullYear();
      this.endmonth= tempstartdate.getMonth();
      this.endday  = tempstartdate.getDate();

   } else {
      // show minimal 14 days and max 4 months
      if (howmanydays < 14) {
         howmanydays = 14;
      }
      this.howmanydays = howmanydays;
      var tempstartdate = new Date(this.startyear, this.startmonth, this.startday);
      var tempenddate   = new Date(this.endyear, this.endmonth, this.endday);
      var prevmonth = tempstartdate.getMonth();
      var savemonth = -1;
      var monthcount = 0;

      if ((tempstartdate != null) && (tempenddate != null)) {
         while ((tempstartdate.getTime() < tempenddate.getTime()) && (howmanydays >= 0) && (tempstartdate.getMonth()-prevmonth < this.howmanymonths))
         {
            tempstartdate.setDate(tempstartdate.getDate()+1);
            howmanydays--;
         }
         while (monthcount <= this.howmanymonths) {
            if (tempstartdate.getMonth() != savemonth) {
               savemonth = tempstartdate.getMonth();
               monthcount++;
            }
           tempstartdate.setDate(tempstartdate.getDate()-1);
         }
         // change enddate to new enddate according to howmanydays
         if (tempstartdate.getTime() <= tempenddate.getTime()) {
            this.endyear = tempstartdate.getFullYear();
            this.endmonth= tempstartdate.getMonth();
            this.endday  = tempstartdate.getDate();
         }
      }
   }
}

function CalendarRange_setHowManyMonths(howmanymonths) {
   if (howmanymonths > this.howmanymonthsmax) {
      howmanymonths = this.howmanymonthsmax;
   }
   this.howmanymonths = howmanymonths;
}

function CalendarRange_getStartDateFrom(ioField) {
   eval("userInput = "+this.returnWindow+"."+this.returnForm+"."+ioField+".value;");
   this.getStartDateFromString(userInput);
}

function CalendarRange_getStartDateFromString(datestring) {
   var startdate = this.parseUserDateInput(datestring);
   this.startday   = startdate.getDate();
   this.startmonth = startdate.getMonth();
   this.startyear  = startdate.getFullYear();

   var enddate = new Date(this.endyear,this.endmonth,this.endday);
   if ((startdate != null) && (enddate != null)) {
      var daycount = 0;
      while (startdate.getTime() <= enddate.getTime()) {
        startdate.setDate(startdate.getDate()+1);
        daycount++;
      }
      // enddate after startdate
      if (daycount == 0) {
         this.endyear = this.startyear;
         this.endmonth= this.startmonth;
         this.endyear = this.startyear;
         this.setHowManyDays(1);
      } else {
         this.setHowManyDays(daycount);
      }
   }
}

function CalendarRange_getEndDateFrom(ioField) {
   eval("userInput = "+this.returnWindow+"."+this.returnForm+"."+ioField+".value;");
   this.getEndDateFromString(userInput);
}


function CalendarRange_getEndDateFromString(datestring) {
   var enddate = this.parseUserDateInput(datestring);
   this.endday   = enddate.getDate();
   this.endmonth = enddate.getMonth();
   this.endyear  = enddate.getFullYear();

   var startdate = new Date(this.startyear,this.startmonth,this.startday);
   if (startdate != null && enddate != null) {
      var daycount = 0;
      while (startdate.getTime() <= enddate.getTime()) {
        startdate.setDate(startdate.getDate()+1);
        daycount++;
      }
      // enddate after startdate
      if (daycount == 0) {
         this.startyear = this.endyear;
         this.startmonth= this.endmonth;
         this.startyear = this.endyear;
         this.setHowManyDays(1);
      } else {
         this.setHowManyDays(daycount);
      }
   }
}


function CalendarRange_parseUserDateInput(userInput){
   wDay = this.weekdaysTexts.join("|");
   reg_exp = eval("/^ *("+wDay+")\, */");
   clearedUserInput = userInput.replace(reg_exp,"");
   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;
   // 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;
        }
     }
   }
   return new Date(userInput_year, userInput_month, userInput_day);
}

function CalendarRange_refReturnField() {
   return this.returnWindow+"."+this.returnForm+"."+this.returnTextfield;
}

//
// This function toggles the given date's style
//
function CalendarRange_setDate(cell) {
   // set the colors by style
   if (this.multipleSelect == true) {
      var tempday = document.getElementById(cell);
      tempday.className = (tempday.className == "s") ? "n" : "s";
   } else {
      // select only ONE day
      if (this.selectedDay != null) {
        tempday = document.getElementById(this.selectedDay);
        tempday.className = (tempday.className == "s") ? "n" : "s";
      }
      this.selectedDay = cell;
      tempday = document.getElementById(cell);
      tempday.className = (tempday.className == "s") ? "n" : "s";

      date = cell.substring((this.name.length)+4,cell.length);
      temp = date.split("/");
      year = temp[0];
      month = temp[1];
      day = temp[2];
      //  implicit typecasting...
      day *= 1; month *= 1; year *= 1;

      // prepare for display
      month = month + 1;
      if (day < 10) {
        day = "0"+day;
      }
      if (month < 10) {
        month = "0"+month;
      }

      // has to be after the previous step for interpreting purposes
      if (this.showShortYear == true) {
         year -= 2000;
         if (year < 10) {
           year = "0"+year;
         }
      }


//VZs date = day+"."+month+"."+year;
      date = year+"."+month+"."+day;

      // calculate weekday & begin week with monday
      weekday = (new Date(year,month-1,day)).getDay()-2;
      if (weekday == -1) weekday = 6;
      if (weekday == -2) weekday = 5;

//VZs      temp = this.refReturnField()+".value = this.weekdaysTexts[weekday]+\", \"+date;";
      temp = this.refReturnField()+".value = date;";
      eval(temp);

      if (this.closeOnSetDate == true) {
        if (window.opener) {
          window.opener.focus();
          window.close();
        }
      }
   }
}


//
// This function fills the calendar table with the days of
// the selected month and year.
//
function CalendarRange_draw() {
   // saving some time - only redraw if inputs have changed
   if ((this.lastdrawstartday   != this.startday) ||
       (this.lastdrawstartmonth != this.startmonth) ||
       (this.lastdrawstartyear  != this.startyear) ||
       (this.lastdrawendday     != this.endday) ||
       (this.lastdrawendmonth   != this.endmonth) ||
       (this.lastdrawendyear    != this.endyear))
   {
      this.lastdrawstartday   = this.startday;
      this.lastdrawstartmonth = this.startmonth;
      this.lastdrawstartyear  = this.startyear;
      this.lastdrawendday     = this.endday;
      this.lastdrawendmonth   = this.endmonth;
      this.lastdrawendyear    = this.endyear;

      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";
      }

      // 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.startyear,this.startmonth,this.startday);
	  
         // show month name above weekdays
         if (this.oneMonthOnly == true) {
            // create row for month name
            current_row = document.createElement("TR");
            if (this.scrollable == true) {
               mycurrent_cell= document.createElement("TH");
			   if (this.minDate >= tempdate) {
	               mycurrent_cell.innerHTML='&nbsp;';
	               mycurrent_cell.className = "w";
	               mycurrent_cell.id = this.name+"_heading_months_lt";
	               mycurrent_cell.onclick = null;
			   }
			   else {
	               mycurrent_cell.innerHTML='<input type="button" value="'+this.prevMonthHTML+'"/>';
	               mycurrent_cell.className = "w";
	               mycurrent_cell.id = this.name+"_heading_months_lt";
	               mycurrent_cell.onclick = function() {
	                  var calid = this.id.substring(0,this.id.indexOf("_heading_months_lt"));
	                  var test = eval('calid')+".prevMonth();";
	                  eval(test);
	               }
			   }
			   
			   
               current_row.appendChild(mycurrent_cell);
            }
            mycurrent_cell= document.createElement("TH");
            mycurrent_cell.colSpan = 5;
            mycurrent_cell.innerHTML = tempdate.getFullYear()+".&nbsp;"+this.monthsTexts[tempdate.getMonth()];
          //mycurrent_cell.setAttribute("align","center");
            mycurrent_cell.textAlign="center";
            mycurrent_cell.id = this.name+"_heading_months"+tempdate.getMonth();
            if (this.multipleSelect == true) {
               mycurrent_cell.className = "y";
               mycurrent_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 {
               mycurrent_cell.className = "y";
            }
            current_row.appendChild(mycurrent_cell);

            if (this.scrollable == true) {
			   if (this.maxDate.getYear()==tempdate.getYear() && this.maxDate.getMonth()==tempdate.getMonth()) {
	               mycurrent_cell = document.createElement("TH");
	               mycurrent_cell.id = this.name+"_heading_months_gt";
	               mycurrent_cell.innerHTML='&nbsp;';
	               mycurrent_cell.className = "w";
	               mycurrent_cell.onclick = null;
			   }
			   else {
               mycurrent_cell = document.createElement("TH");
               mycurrent_cell.id = this.name+"_heading_months_gt";
               mycurrent_cell.innerHTML='<input type="button" value="'+this.nextMonthHTML+'" />';
               mycurrent_cell.className = "w";
               mycurrent_cell.onclick = function() {
                  var calid = this.id.substring(0,this.id.indexOf("_heading_months_gt"));
                  var test = eval('calid')+".nextMonth();";
                  eval(test);
				}
			   }
               current_row.appendChild(mycurrent_cell);
			   
            }

            tbody.appendChild(current_row);
         }

         // write weekday names in first (or second) row
         var row = document.createElement("TR");

         for (d = 0 ; d < 7 ; d++) {
            var cell = document.createElement("TH");
            cell.id = this.name+"_heading_"+d;
            //cell.innerHTML = "<b>"+this.weekdaysTexts[d]+"</b>";
            cell.innerHTML = this.weekdaysTexts[d];
            if (this.multipleSelect == true) {
               cell.className = "d";
               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 = "d";
            }
            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 newWeekNeeded = true;
        while (newWeekNeeded == true) {
           w++;

           if ((tempdate.getDate() == 1 && newmonth == true) || (daysdrawn == 0)) {
              // 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");
                    mycurrent_cell= document.createElement("TD");
                    mycurrent_cell.colSpan = 7;
                    mycurrent_cell.innerHTML = "<b>"+this.monthsTexts[tempdate.getMonth()]+" - "+tempdate.getFullYear()+"</b>";
                    mycurrent_cell.id = this.name+"_heading_months"+tempdate.getMonth();
                    if (this.multipleSelect == true) {
                       mycurrent_cell.className = "enabled";
                       mycurrent_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 {
                       mycurrent_cell.className = "y";
                    }
                    current_row.appendChild(mycurrent_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);
            }
               // draws week rows
            for(var d = 0; d < 7; d++) {

                 if ((tempdate.getDate() == 1 && newmonth == false) && (daysdrawn != 0)) {
                    newmonth = true;
                    // append remaining empty cells
                    for (var e = d; e < 7; e++) {
                       cell = document.createElement("TD");
                       cell.className = (d==6)?"v":"n";
                       cell.innerHTML = "&nbsp;";
                       if (current_row != null) {
                          current_row.appendChild(cell);
                       } else {
//                          cell.className = "active";
                       }
                    }
                    break;
                 }

              cell = document.createElement("TD");

// VZs              if(daystoskip <= 0 && daysdrawn < this.howmanydays) {
              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);
                // increase already drawn days by one
                daysdrawn += 1;

				if ( tempdate >= this.minDate && tempdate <= this.maxDate) {
	                cell.innerHTML = tempdate.getDate();
//VZs                cell.innerHTML = '<a>'+tempdate.getDate()+'</a>';
	                cell.className = "n";
	                cell.onclick = function(){
	                   var calid = this.id.substring(0,this.id.indexOf("_df"));
	                   var test = eval('calid')+".setDate(this.id);";
	                   eval(test);
					};
				}
				else {
	                cell.className = "n";
	                cell.innerHTML = "&nbsp;";
	                cell.onclick = null;
				};
				
                tempdate.setDate(tempdate.getDate()+1);
			  }

                //  deactivate cell
              else {
                cell.className = "n";
                cell.innerHTML = "&nbsp;";
                cell.onclick = null;
                daystoskip -= 1;
              }

              current_row.appendChild(cell);
            }
            var tempenddate   = new Date(this.endyear, this.endmonth, this.endday);
            if ((tempdate > tempenddate) || (daysdrawn >= this.howmanydays)) {
              newWeekNeeded = false;
            }

        }


    // auto-correction of div size
    document.getElementById(this.name).style.width = "auto";
   }
   // select initial date
   tempday = document.getElementById(this.selectedDay);
   if (tempday != null) {
      tempday.className = "s";
   }
} // - END function Calendar_draw();

function isLeapYear(y){if((y%4)==0 && (y%100)!=0 || (y%400)==0) return true;}

