// JavaScript Document

/**************************************************************************************
	hsh_calendar.class.js
	date: 25/10/2004
	version: 1.1.0
	author: Ezzat A. Helal
	email: eahelal@helalsoftware.net
	web: www.helalsoftware.net
	==========================
	This software is free with only one condition do note remove the reference to the author.
	The original code is written by: Tan Ling	Wee	on 2 Dec 2001 email: 	fuushikaden@yahoo.com
	I modified the code in first version and in this last modification I converted it to a class,
	and implement a validation function used to validate the date field when entered by users.
	
	Calendar class is easly added to your code without affecting your code because of 
	the encapsulation feature of the object oriented programs.
	You need to create the calendar object in document body. new hsh_calendar();
	Call the function: objCalendar.popUpCalendar(this, txtDate, "dd/mm/yyyy")
	Where:
		The first paramater is the window object;
		txtDate: is the name of the date control (input text), and
		"dd/mm/yyyy": is the format of the date.
	The date must contain the three fields: day, month, and year separated by: space, /, ., - 
	Day format character is d or dd;
	Month format characters: m, mm, or mmm;
	year format chatacters: yyyy
	You can also call the function: objCalendar.ValidateDate(txtDate, "dd/mm/yyyy") to validate the date entered by users.
	You can also call the function: objCalendar.FormatDate(txtDate, old_format, new_formart) to reformat the date in txtDate.

	The default images directory is "include/cal_images/" it could be changed in the code variables section 
	(the variable name is this.imgDir).
	The [include] folder that contains the java script file and the sub-folder cal_images that contains the 
	images is sub folder of [html page] folder.

	The code defines a global variable (objCalendar) that holds the calendar object. 
	if you change its name, you must change all its occurances in the code.
	
	The name of the class is hsh_calendar and could be changed to any name.
	
	No other changes required to use the code safely.
***************************************************************************************/
var objCalendar = null;
function hsh_calendar() {

objCalendar = this;
// General functions =================================================================
/*********************************************************
padZero
**********************************************************/
this.padZero = function (num) {
	return (num	< 10)? '0' + num : num ;
}
/*******************************************************
Get Element Offsets
*******************************************************/
this.getOffsetLeft = function (el) {
	var ol = el.offsetLeft;
	while ((el = el.offsetParent) != null)
		ol += el.offsetLeft;
	return ol;
}
this.getOffsetTop = function (el) {
	var ot = el.offsetTop;
	while((el = el.offsetParent) != null)
		ot += el.offsetTop;
	return ot;
}
/*********************************************************
swapImage
**********************************************************/
this.swapImage = function (srcImg, destImg){
	if (this.ie) { document.getElementById(srcImg).setAttribute("src",this.imgDir + destImg); }
}
// Global Variables =========================================
this.fixedX = -1;			// x position (-1 if to appear 
this.fixedY = -1;			// y position (-1 if to appear 
this.startAt = 1;			// 0 - sunday ; 1 - monday
this.showWeekNumber = 1;	// 0 - don't show; 1 - show
this.showToday = 1;		// 0 - don't show; 1 - show

this.showWeekNumber = 1;	// 0 - don't show; 1 - show
this.weekString = "Wk";

this.today = new Date();
this.dateNow = this.today.getDate();
this.monthNow = this.today.getMonth();
this.yearNow = this.today.getYear();
this.imgDir = "include/cal_images/";

this.imgsrc = new Array("drop1.gif","drop2.gif","left1.gif","left2.gif","right1.gif","right2.gif");
this.img = new Array();
this.ie=document.all;
this.dom=document.getElementById;
this.ns4=document.layers;

this.crossobj = null;
this.crossMonthObj = null;
this.crossYearObj = null;
this.monthSelected = 0; 
this.yearSelected = 0;
this.dateSelected = 0;
this.omonthSelected = 0;
this.oyearSelected = 0;
this.odateSelected = 0;
this.monthConstructed = false;
this.yearConstructed = false;
this.intervalID1 = null;
this.intervalID2 = null;
this.timeoutID1 = 0;
this.timeoutID2 = 0;
this.ctlToPlaceValue = ""; 
this.ctlNow = null;
this.dateFormat = "";
this.nStartingYear = 0;
this.todayString = "Today is";
this.gotoString = "Go To Current Month";
this.bPageLoaded=false;
// Define Months and Days names
this.monthName = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
if (this.startAt==0)	{
	this.dayName = new Array("Sun","Mon","Tue","Wed","Thu","Fri","Sat");
}
else {
	this.dayName = new Array("Mon","Tue","Wed","Thu","Fri","Sat","Sun");
}
// ===================================================================================
this.styleAnchor="text-decoration:none;color:black;";
this.styleLightBorder="border-style:solid;border-width:1px;border-color:#a0a0a0;";

this.HolidaysCounter = 0;
this.Holidays = new Array();

this.scrollLeftMessage = "Click to scroll to previous month. Hold mouse button to scroll automatically.";
this.scrollRightMessage = "Click to scroll to next month. Hold mouse button to scroll automatically.";
this.selectMonthMessage = "Click to select a month.";
this.selectYearMessage = "Click to select a year.";
this.selectDateMessage = "Select [date] as date."; // do not replace [date], it will be replaced by date.
// ============================================================
/*********************************************************
hideCalendar
**********************************************************/
this.hideCalendar = function ()	{
	this.crossobj.visibility="hidden";
	if (this.crossMonthObj != null){this.crossMonthObj.visibility="hidden";}
	if (this.crossYearObj != null){this.crossYearObj.visibility="hidden";}
}
/************************************************************
Format Date
**************************************************************/
this.FormatDate = function (dateCtrl, old_format, new_format) {
	formatChar = " ";
	success = false;
	aFormat	= old_format.split(formatChar);
	if (aFormat.length<3) { // it must contain three parts
		formatChar = "/";
		aFormat	= old_format.split(formatChar);
		if (aFormat.length<3) {
			formatChar = ".";
			aFormat	= old_format.split(formatChar);
			if (aFormat.length<3) {
				formatChar = "-";
				aFormat	= old_format.split(formatChar);
				if (aFormat.length<3) {
					formatChar = ",";
					aFormat	= old_format.split(formatChar);
					if (aFormat.length<3) {
						// invalid date	format
						formatChar="";
					}
				}
			}
		}
	}
	tokensChanged =	0;
	if ( formatChar	!= "" && dateCtrl.value != "")	{  // Valid Date Format
		// use user's date
		aData =	dateCtrl.value.split(formatChar);
		for	(i=0;i<3;i++) {
			if ((aFormat[i]=="d") || (aFormat[i]=="dd")) {
				this.dateSelected = parseInt(aData[i], 10);
				tokensChanged ++;
			}
			else if	((aFormat[i]=="m") || (aFormat[i]=="mm")) {
				this.monthSelected = parseInt(aData[i], 10) - 1;
				tokensChanged ++;
			}
			else if	(aFormat[i]=="yyyy") {
				this.yearSelected = parseInt(aData[i], 10);
				tokensChanged ++;
			}
			else if	(aFormat[i]=="mmm")	{
				for	(j=0; j<12;	j++) {
					if (aData[i]==this.monthName[j]) {
						this.monthSelected=j;
						tokensChanged ++;
					}
				}
			}
		} // end of parsing the three date fields
		if ((tokensChanged!=3)||isNaN(this.dateSelected)||isNaN(this.monthSelected)||isNaN(this.yearSelected)) {
			tokensChanged = 0;
		}
		if (this.monthSelected < 0 || this.monthSelected > 11) {
			tokensChanged = 0;
		}
		var aNumDays = new Array (31,0,31,30,31,30,31,31,30,31,30,31);
		var endDate;
		// set endDate - end day in month
		if (this.monthSelected==1) { // February Month
			endDate	= new Date (this.yearSelected,this.monthSelected+1,1);
			endDate	= new Date (endDate	- (24*60*60*1000));
			numDaysInMonth = endDate.getDate();
		}
		else {
			numDaysInMonth = aNumDays[this.monthSelected];
		}
		if (this.dateSelected < 0 || this.dateSelected > numDaysInMonth) {
			tokensChanged = 0;
		}
		if (tokensChanged == 3) { // valid date apply new format
			formatChar = " ";
			aFormat	= new_format.split(formatChar);
			if (aFormat.length<3) { // it must contain three parts
				formatChar = "/";
				aFormat	= new_format.split(formatChar);
				if (aFormat.length<3) {
					formatChar = ".";
					aFormat	= new_format.split(formatChar);
					if (aFormat.length<3) {
						formatChar = "-";
						aFormat	= new_format.split(formatChar);
						if (aFormat.length<3) {
							formatChar = ",";
							aFormat	= new_format.split(formatChar);
							if (aFormat.length<3) {
								// invalid date	format
								formatChar="";
							}
						}
					}
				}
			}
			// =====
			if (formatChar != "") {
				new_date_value = "";
				for	(i=0;i<3;i++) {
					if (aFormat[i]=="d") {
						if (i > 0) new_date_value += formatChar;
						new_date_value += this.dateSelected;
					}
					else if (aFormat[i]=="dd") {
						if (i > 0) new_date_value += formatChar;
						new_date_value += this.padZero(this.dateSelected);
					}
					else if	(aFormat[i]=="m") {
						if (i > 0) new_date_value += formatChar;
						new_date_value += this.monthSelected + 1;
					}
					else if	(aFormat[i]=="mm") {
						if (i > 0) new_date_value += formatChar;
						new_date_value += this.padZero(this.monthSelected+1);
					}
					else if	(aFormat[i]=="yyyy") {
						if (i > 0) new_date_value += formatChar;
						new_date_value += this.yearSelected;
					}
					else if	(aFormat[i]=="mmm")	{
						if (i > 0) new_date_value += formatChar;
						new_date_value += this.monthName[this.monthSelected];
					}
				} // end of new formatting
				if (new_date_value != "") {
					dateCtrl.value = new_date_value;
					success = true;
				}
			} // end of valid new format
		} // end of valid date value
	} // end of valid date format
	return success;

}
/*************************************************************
Validate Date
***************************************************************/
this.ValidateDate = function (dateCtrl, format) {
	// Checking Date Format (dateFormat)
	// day, month, and year separated by (formatChar) which is either space, /, ., or -
	formatChar = " ";
	aFormat	= format.split(formatChar);
	if (aFormat.length<3) { // it must contain three parts
		formatChar = "/";
		aFormat	= format.split(formatChar);
		if (aFormat.length<3) {
			formatChar = ".";
			aFormat	= format.split(formatChar);
			if (aFormat.length<3) {
				formatChar = "-";
				aFormat	= format.split(formatChar);
				if (aFormat.length<3) {
					// invalid date	format
					formatChar="";
				}
			}
		}
	}
	tokensChanged =	0;
	if ( formatChar	!= "" && dateCtrl.value != "")	{  // Valid Date Format
		// use user's date
		aData =	dateCtrl.value.split(formatChar);
		for	(i=0;i<3;i++) {
			if ((aFormat[i]=="d") || (aFormat[i]=="dd")) {
				this.dateSelected = parseInt(aData[i], 10);
				tokensChanged ++;
			}
			else if	((aFormat[i]=="m") || (aFormat[i]=="mm")) {
				this.monthSelected = parseInt(aData[i], 10) - 1;
				tokensChanged ++;
			}
			else if	(aFormat[i]=="yyyy") {
				this.yearSelected = parseInt(aData[i], 10);
				tokensChanged ++;
			}
			else if	(aFormat[i]=="mmm")	{
				for	(j=0; j<12;	j++) {
					if (aData[i]==this.monthName[j]) {
						this.monthSelected=j;
						tokensChanged ++;
					}
				}
			}
		} // end of parsing the three date fields
		if ((tokensChanged!=3)||isNaN(this.dateSelected)||isNaN(this.monthSelected)||isNaN(this.yearSelected)) {
			tokensChanged = 0;
			alert("Invalid Date: missing day or month or year according to format: [" + format + "]");
		}
		if (this.monthSelected < 0 || this.monthSelected > 11) {
			tokensChanged = 0;
			alert("Invalid Date: Month should be from 1 to 12");
		}
		var aNumDays = new Array (31,0,31,30,31,30,31,31,30,31,30,31);
		var endDate;
		// set endDate - end day in month
		if (this.monthSelected==1) { // February Month
			endDate	= new Date (this.yearSelected,this.monthSelected+1,1);
			endDate	= new Date (endDate	- (24*60*60*1000));
			numDaysInMonth = endDate.getDate();
		}
		else {
			numDaysInMonth = aNumDays[this.monthSelected];
		}
		if (this.dateSelected < 0 || this.dateSelected > numDaysInMonth) {
			tokensChanged = 0;
			alert("Invalid Date: Day must be between 1 and " + numDaysInMonth);
		}
	} // end of valid date format
	return tokensChanged;
}
/*********************************************************
popUpCalendar: 
	popUpCalendar(theWindowControl(this), theTestControl, theDateFormat)
**********************************************************/
this.popUpCalendar = function (ctl, ctl2, format) {
	// not used
	var	leftpos=0;
	var	toppos=0;
	
	if (this.bPageLoaded) { // It is true after init
		if (this.crossobj.visibility ==	"hidden") {
			this.ctlToPlaceValue = ctl2;
			tokensChanged = this.ValidateDate(ctl2, format);
			this.dateFormat=format;
			// =============================
			if ((tokensChanged!=3)||isNaN(this.dateSelected)||isNaN(this.monthSelected)||isNaN(this.yearSelected)) {
				aFormat	= format.split("/");
				if (aFormat.length == 3) {
					if ((aFormat[0]=="d") || (aFormat[0]=="dd")) {
						// Invalid Date select the today date
						this.dateSelected = this.dateNow;
						this.monthSelected = this.monthNow;
						this.yearSelected = this.yearNow;
					} else {
						// Get Date From separate fields
						this.dateSelected = document.getElementById(aFormat[0]).value;
						this.monthSelected = document.getElementById(aFormat[1]).value - 1;
						this.yearSelected = document.getElementById(aFormat[2]).value;
					}
				} else {
					// Invalid Date select the today date
					this.dateSelected = this.dateNow;
					this.monthSelected = this.monthNow;
					this.yearSelected = this.yearNow;
				}
			}

			this.odateSelected=this.dateSelected;
			this.omonthSelected=this.monthSelected;
			this.oyearSelected=this.yearSelected;
			this.constructCalendar ();
			// Added by E.H
			leftpos = this.getOffsetLeft(ctl2);
			toppos = this.getOffsetTop(ctl2);
			this.crossobj.left = leftpos;
			this.crossobj.top = toppos + ctl2.offsetHeight;
			this.crossobj.visibility=(this.dom||this.ie)? "visible" : "show";
		}
		else { // Calendar not hidden
			this.hideCalendar();
			if (this.ctlNow!=ctl) {this.popUpCalendar(ctl, ctl2, format);}
		}
		this.ctlNow = ctl;
	}
}
/*********************************************************
Month and Year Functions
**********************************************************/
	/*** Month Pulldown	***/

this.StartDecMonth = function () {
	this.intervalID1=setInterval("objCalendar.decMonth()",80);
}
this.StartIncMonth = function () {
	this.intervalID1=setInterval("objCalendar.incMonth()",80);
}
this.incMonth = function () {
	this.monthSelected++;
	if (this.monthSelected>11) {
		this.monthSelected=0;
		this.yearSelected++;
	}
	this.constructCalendar();
}
this.decMonth = function () {
	this.monthSelected--;
	if (this.monthSelected<0) {
		this.monthSelected=11;
		this.yearSelected--;
	}
	this.constructCalendar();
}
this.constructMonth = function () {
	this.popDownYear();
	if (!this.monthConstructed) {
		sHTML =	"";
		for	(i=0; i<12;	i++) {
			sName =	this.monthName[i];
			if (i==this.monthSelected){
				sName =	"<B>" +	sName +	"</B>";
			}
			sHTML += "<tr><td id='m" + i + "' onmouseover='this.style.backgroundColor=\"#FFCC99\"' onmouseout='this.style.backgroundColor=\"\"' style='cursor:pointer' onclick='objCalendar.monthConstructed=false;objCalendar.monthSelected=" + i + ";objCalendar.constructCalendar();objCalendar.popDownMonth();event.cancelBubble=true'>&nbsp;" + sName + "&nbsp;</td></tr>";
		}
		document.getElementById("selectMonth").innerHTML = "<table width=70	style='font-family:arial; font-size:11px; border-width:1; border-style:solid; border-color:#a0a0a0;' bgcolor='#FFFFDD' cellspacing=0 onmouseover='clearTimeout(objCalendar.timeoutID1)'	onmouseout='clearTimeout(objCalendar.timeoutID1);objCalendar.timeoutID1=setTimeout(\"objCalendar.popDownMonth()\",100);event.cancelBubble=true'>" +	sHTML +	"</table>";
		this.monthConstructed=true;
	}
}
this.popUpMonth = function () {
	this.constructMonth();
	this.crossMonthObj.visibility = (this.dom||this.ie)? "visible"	: "show";
	this.crossMonthObj.left = parseInt(this.crossobj.left) + 50;
	this.crossMonthObj.top =	parseInt(this.crossobj.top) + 26;
}

this.popDownMonth = function ()	{

	this.crossMonthObj.visibility= "hidden";
}
/*** Year Pulldown ***/

this.incYear = function () {
	for	(i=0; i<7; i++){
		newYear	= (i+this.nStartingYear)+1;
		if (newYear==this.yearSelected)
			{ txtYear =	"&nbsp;<B>"	+ newYear +	"</B>&nbsp;"; }
		else
			{ txtYear =	"&nbsp;" + newYear + "&nbsp;"; }
		document.getElementById("y"+i).innerHTML = txtYear;
	}
	this.nStartingYear ++;
}
this.decYear = function () {
	for	(i=0; i<7; i++){
		newYear	= (i+this.nStartingYear)-1;
		if (newYear==this.yearSelected)
			{ txtYear =	"&nbsp;<B>"	+ newYear +	"</B>&nbsp;"; }
		else
			{ txtYear =	"&nbsp;" + newYear + "&nbsp;"; }
		document.getElementById("y"+i).innerHTML = txtYear;
	}
	this.nStartingYear --;
}
this.selectYear = function (nYear) {
	this.yearSelected=parseInt(nYear+this.nStartingYear);
	this.yearConstructed=false;
	this.constructCalendar();
	this.popDownYear();
}
this.constructYear = function () {
	this.popDownMonth();
	sHTML =	"";
	if (!this.yearConstructed) {
		sHTML =	"<tr><td align='center'	onmouseover='this.style.backgroundColor=\"#FFCC99\"' onmouseout='clearInterval(objCalendar.intervalID1);this.style.backgroundColor=\"\"' style='cursor:pointer'	onmousedown='clearInterval(objCalendar.intervalID1);objCalendar.intervalID1=setInterval(\"objCalendar.decYear()\",30)' onmouseup='clearInterval(objCanlendar.intervalID1)'>-</td></tr>";
		j =	0;
		this.nStartingYear = this.yearSelected-3;
		var last_year = parseInt(this.nStartingYear)+6;
		for	(i=this.nStartingYear; i<=last_year; i++) {
			sName =	i;
			if (i==this.yearSelected){
				sName =	"<B>" +	sName +	"</B>";
			}
			sHTML += "<tr><td id='y" + j + "' onmouseover='this.style.backgroundColor=\"#FFCC99\"' onmouseout='this.style.backgroundColor=\"\"' style='cursor:pointer' onclick='objCalendar.selectYear("+j+");event.cancelBubble=true'>&nbsp;" + sName + "&nbsp;</td></tr>";
			j ++;
		}
		sHTML += "<tr><td align='center' onmouseover='this.style.backgroundColor=\"#FFCC99\"' onmouseout='clearInterval(objCalendar.intervalID2);this.style.backgroundColor=\"\"' style='cursor:pointer' onmousedown='clearInterval(objCalendar.intervalID2);objCalendar.intervalID2=setInterval(\"objCalendar.incYear()\",30)'	onmouseup='clearInterval(objCalendar.intervalID2)'>+</td></tr>";
		document.getElementById("selectYear").innerHTML	= "<table width=44 style='font-family:arial; font-size:11px; border-width:1; border-style:solid; border-color:#a0a0a0;'	bgcolor='#FFFFDD' onmouseover='clearTimeout(objCalendar.timeoutID2)' onmouseout='clearTimeout(objCalendar.timeoutID2);objCalendar.timeoutID2=setTimeout(\"objCalendar.popDownYear()\",100)' cellspacing=0>"	+ sHTML	+ "</table>";
		this.yearConstructed = true;
	}
}
this.popDownYear = function () {
	clearInterval(this.intervalID1);
	clearTimeout(this.timeoutID1);
	clearInterval(this.intervalID2);
	clearTimeout(this.timeoutID2);
	this.crossYearObj.visibility= "hidden";
}
this.popUpYear = function () {
	var	leftOffset;

	this.constructYear();
	this.crossYearObj.visibility = (this.dom||this.ie)? "visible" : "show";
	leftOffset = parseInt(this.crossobj.left) + document.getElementById("spanYear").offsetLeft;
	if (this.ie)	{
		leftOffset += 6;
	}
	this.crossYearObj.left = leftOffset;

	this.crossYearObj.top = parseInt(this.crossobj.top) + 26;
}

/*********************************************************
constructDate
**********************************************************/
this.constructDate = function (d,m,y) {

	sTmp = this.dateFormat
	sTmp = sTmp.replace	("dd","<e>")
	sTmp = sTmp.replace	("d","<d>")
	sTmp = sTmp.replace	("<e>",this.padZero(d))
	sTmp = sTmp.replace	("<d>",d)
	sTmp = sTmp.replace	("mmm","<o>")
	sTmp = sTmp.replace	("mm","<n>")
	sTmp = sTmp.replace	("m","<m>")
	sTmp = sTmp.replace	("<m>",m+1)
	sTmp = sTmp.replace	("<n>",this.padZero(m+1))
	sTmp = sTmp.replace	("<o>",this.monthName[m])
	return sTmp.replace ("yyyy",y)
}
/*********************************************************
closeCalendar
**********************************************************/
this.closeCalendar = function () {
	var	sTmp = true;

	this.hideCalendar();
	aFormat	= this.dateFormat.split("/");
	if (aFormat.length == 3) {
		if ((aFormat[0]!="d") && (aFormat[0]!="dd")) {
			// Get Date From separate fields
			sTmp = false;
			document.getElementById(aFormat[0]).value = this.dateSelected;
			document.getElementById(aFormat[1]).value = this.monthSelected + 1;
			document.getElementById(aFormat[2]).value = this.yearSelected;
		}
	}
	if (sTmp)
	this.ctlToPlaceValue.value = this.constructDate(this.dateSelected,this.monthSelected,this.yearSelected);
}
/*** calendar ***/
/***************************************************************
WeekNbr
***************************************************************/
this.WeekNbr = function (today)    {
	Year = this.takeYear(today);
	Month = today.getMonth();
	Day = today.getDate();
	now = Date.UTC(Year,Month,Day+1,0,0,0);
	var Firstday = new Date();
	Firstday.setYear(Year);
	Firstday.setMonth(0);
	Firstday.setDate(1);
	then = Date.UTC(Year,0,1,0,0,0);
	var Compensation = Firstday.getDay();
	if (Compensation > 3) Compensation -= 4;
	else Compensation += 3;
	NumberOfWeek =  Math.round((((now-then)/86400000)+Compensation)/7);
	return NumberOfWeek;
}
/***********************************************************************
takeYear
***********************************************************************/
this.takeYear = function (theDate)	{
	x = theDate.getYear();
	var y = x % 100;
	y += (y < 38) ? 2000 : 1900;
	return y;
}
/*********************************************************
constructCalendar
**********************************************************/
this.constructCalendar = function () {
	var aNumDays = new Array (31,0,31,30,31,30,31,31,30,31,30,31);
	var dateMessage;
	var	startDate =	new	Date (this.yearSelected,this.monthSelected,1);
	var endDate;
	// set endDate - end day in month
	if (this.monthSelected==1) { // February Month
		endDate	= new Date (this.yearSelected,this.monthSelected+1,1);
		endDate	= new Date (endDate	- (24*60*60*1000));
		numDaysInMonth = endDate.getDate();
	}
	else {
		numDaysInMonth = aNumDays[this.monthSelected];
	}

	datePointer	= 0;
	dayPointer = startDate.getDay() - this.startAt;
	if (dayPointer<0) {
		dayPointer = 6;
	}
	// Construct Days table
	sHTML =	"<table	border=0 style='font-family:verdana;font-size:10px;'><tr>";
	// Weeks Numbers column
	if (this.showWeekNumber==1)	{
		sHTML += "<td width=27><b>" + this.weekString + "</b></td><td width=1 rowspan=7 bgcolor='#d0d0d0' style='padding:0px'><img src='"+this.imgDir+"divider.gif' width=1></td>";
	}
	// Days Names columns
	for	(i=0; i<7; i++)	{
		sHTML += "<td width='27' align='right'><B>"+ this.dayName[i]+"</B></td>";
	}
	sHTML +="</tr><tr>";
	// Second Row Weeks Numbers and Days numbers

	if (this.showWeekNumber==1) {
		sHTML += "<td align=right>" + this.WeekNbr(startDate) + "&nbsp;</td>";
	}
	// Days before the start month day
	for	( var i=1; i<=dayPointer;i++ ) {
		sHTML += "<td>&nbsp;</td>";
	}
	// Month days
	for	( datePointer=1; datePointer<=numDaysInMonth; datePointer++ ) {
		dayPointer++;
		sHTML += "<td align=right>";
		sStyle=this.styleAnchor;
		if ((datePointer==this.odateSelected) && (this.monthSelected==this.omonthSelected) && (this.yearSelected==this.oyearSelected))
			{ sStyle+=this.styleLightBorder; }
		sHint = "";
		// Holidays
		for (k=0;k<this.HolidaysCounter;k++)	{
			if ((parseInt(this.Holidays[k].d)==datePointer)&&(parseInt(this.Holidays[k].m)==(this.monthSelected+1))) {
				if ((parseInt(this.Holidays[k].y)==0)||((parseInt(this.Holidays[k].y)==this.yearSelected)&&(parseInt(this.Holidays[k].y)!=0))) {
					sStyle+="background-color:#FFDDDD;";
					sHint+=sHint==""?this.Holidays[k].desc:"\n"+this.Holidays[k].desc;
				}
			}
		}

		var regexp= /\"/
		sHint=sHint.replace(regexp,"&quot;")
		dateMessage = "onmousemove='window.status=\""+this.selectDateMessage.replace("[date]",this.constructDate(datePointer,this.monthSelected,this.yearSelected))+"\"' onmouseout='window.status=\"\"' ";
		if ((datePointer==this.dateNow)&&(this.monthSelected==this.monthNow)&&(this.yearSelected==this.yearNow)) {
			sHTML += "<b><a "+dateMessage+" title=\"" + sHint + "\" style='"+sStyle+"' href='javascript:objCalendar.dateSelected="+datePointer+";objCalendar.closeCalendar();'><font color=#ff0000>&nbsp;" + datePointer + "</font>&nbsp;</a></b>";
		}
		else if	(dayPointer % 7 == (this.startAt * -1)+1) {
			sHTML += "<a "+dateMessage+" title=\"" + sHint + "\" style='"+sStyle+"' href='javascript:objCalendar.dateSelected="+datePointer + ";objCalendar.closeCalendar();'>&nbsp;<font color=#909090>" + datePointer + "</font>&nbsp;</a>";
		}
		else {
			sHTML += "<a "+dateMessage+" title=\"" + sHint + "\" style='"+sStyle+"' href='javascript:objCalendar.dateSelected="+datePointer + ";objCalendar.closeCalendar();'>&nbsp;" + datePointer + "&nbsp;</a>";
		}

		sHTML += "";
		if ((dayPointer+this.startAt) % 7 == this.startAt) { 
			sHTML += "</tr><tr>";
			if ((this.showWeekNumber==1)&&(datePointer<numDaysInMonth)) {
				sHTML += "<td align=right>" + (this.WeekNbr(new Date(this.yearSelected,this.monthSelected,datePointer+1))) + "&nbsp;</td>";
			}
		}
	}
	document.getElementById("content").innerHTML   = sHTML;
	document.getElementById("spanMonth").innerHTML = "&nbsp;" +	this.monthName[this.monthSelected] + "&nbsp;<IMG id='changeMonth' SRC='"+this.imgDir+"drop1.gif' WIDTH='12' HEIGHT='10' BORDER=0>";
	document.getElementById("spanYear").innerHTML =	"&nbsp;" + this.yearSelected + "&nbsp;<IMG id='changeYear' SRC='"+this.imgDir+"drop1.gif' WIDTH='12' HEIGHT='10' BORDER=0>";
}


// define the calendar body ==========================================================
if (this.dom) {
	for (i=0;i<this.imgsrc.length;i++) {
		this.img[i] = new Image;
		this.img[i].src = this.imgDir + this.imgsrc[i];
	}
	document.write ("<div id='calendar'	style='position:absolute;visibility:hidden;'>");
	document.write ("<table	width="+((this.showWeekNumber==1)?250:220)+" style='font-family:arial;font-size:11px;border-width:1;border-style:solid;border-color:#a0a0a0;font-family:arial; font-size:11px}' bgcolor='#ffffff'>");
	// first row
	document.write ("<tr bgcolor='#0000aa'><td>");
	document.write ("<table width='"+((this.showWeekNumber==1)?248:218)+"'>");
	document.write ("<tr><td style='padding:2px;font-family:arial; font-size:11px;'>");
	document.write ("<font color='#ffffff'><B><span id='caption'></span></B></font></td>");
	document.write ("<td align=right><a href='javascript:objCalendar.hideCalendar()'><IMG SRC='"+this.imgDir+"close.gif' WIDTH='15' HEIGHT='13' BORDER='0' ALT='Close the Calendar'></a></td></tr>");
	document.write ("</table></td></tr>");
	// second row
	document.write ("<tr><td style='padding:5px' bgcolor=#ffffff><span id='content'></span></td></tr>");
			
	if (this.showToday==1) {
		// third row
		document.write ("<tr bgcolor=#f0f0f0><td style='padding:5px' align=center><span id='lblToday'></span></td></tr>");
	}
			
	document.write ("</table></div>");
	// select month
	document.write ("<div id='selectMonth' style='position:absolute;visibility:hidden;'></div>");
	// Select Year
	document.write ("<div id='selectYear' style='position:absolute;visibility:hidden;'></div>");
}
// ===================================================================================
	if (!this.ns4) {
		if (!this.ie) { this.yearNow += 1900 }
			this.crossobj=(this.dom)?document.getElementById("calendar").style : this.ie? document.all.calendar : document.calendar;
			this.hideCalendar();
			this.crossMonthObj=(this.dom)?document.getElementById("selectMonth").style : this.ie? document.all.selectMonth : document.selectMonth;
			this.crossYearObj=(this.dom)?document.getElementById("selectYear").style : this.ie? document.all.selectYear : document.selectYear;
			this.monthConstructed=false;
			this.yearConstructed=false;
			if (this.showToday==1) {
				sHTML1 = this.todayString + " <a onmousemove='window.status=\""+this.gotoString+"\"'";
				sHTML1 += " onmouseout='window.status=\"\"' title='"+this.gotoString+"'";
				sHTML1 += " style='"+this.styleAnchor+"'";
				sHTML1 += " href='javascript:objCalendar.monthSelected=objCalendar.monthNow;objCalendar.yearSelected=objCalendar.yearNow;objCalendar.constructCalendar();'>";
				sHTML1 += this.dayName[(this.today.getDay()-this.startAt==-1)?6:(this.today.getDay()-this.startAt)]+", " + this.dateNow + " " + this.monthName[this.monthNow].substring(0,3) + "	" +	this.yearNow + "</a>";
				document.getElementById("lblToday").innerHTML = sHTML1;
			}

			sHTML1="<span id='spanLeft' style='border-style:solid;border-width:1;border-color:#3366FF;cursor:pointer'";
			sHTML1 += " onmouseover='objCalendar.swapImage(\"changeLeft\",\"left2.gif\");this.style.borderColor=\"#88AAFF\";window.status=\""+this.scrollLeftMessage+"\"' onclick='javascript:objCalendar.decMonth()' onmouseout='clearInterval(objCalendar.intervalID1);objCalendar.swapImage(\"changeLeft\",\"left1.gif\");this.style.borderColor=\"#3366FF\";window.status=\"\"' onmousedown='clearTimeout(objCalendar.timeoutID1);objCalendar.timeoutID1=setTimeout(\"objCalendar.StartDecMonth()\",500)' onmouseup='clearTimeout(objCalendar.timeoutID1);clearInterval(objCalendar.intervalID1)'>&nbsp<IMG id='changeLeft' SRC='"+this.imgDir+"left1.gif' width=10 height=11 BORDER=0>&nbsp</span>&nbsp;";
			sHTML1+="<span id='spanRight' style='border-style:solid;border-width:1;border-color:#3366FF;cursor:pointer'	onmouseover='objCalendar.swapImage(\"changeRight\",\"right2.gif\");this.style.borderColor=\"#88AAFF\";window.status=\""+this.scrollRightMessage+"\"' onmouseout='clearInterval(objCalendar.intervalID1);objCalendar.swapImage(\"changeRight\",\"right1.gif\");this.style.borderColor=\"#3366FF\";window.status=\"\"' onclick='objCalendar.incMonth()' onmousedown='clearTimeout(objCalendar.timeoutID1);objCalendar.timeoutID1=setTimeout(\"StartIncMonth()\",500)'	onmouseup='clearTimeout(objCalendar.timeoutID1);clearInterval(objCalendar.intervalID1)'>&nbsp<IMG id='changeRight' SRC='"+this.imgDir+"right1.gif'	width=10 height=11 BORDER=0>&nbsp</span>&nbsp";
			sHTML1+="<span id='spanMonth' style='border-style:solid;border-width:1;border-color:#3366FF;cursor:pointer'	onmouseover='objCalendar.swapImage(\"changeMonth\",\"drop2.gif\");this.style.borderColor=\"#88AAFF\";window.status=\""+this.selectMonthMessage+"\"' onmouseout='objCalendar.swapImage(\"changeMonth\",\"drop1.gif\");this.style.borderColor=\"#3366FF\";window.status=\"\"' onclick='objCalendar.popUpMonth()'></span>&nbsp;";
			sHTML1+="<span id='spanYear' style='border-style:solid;border-width:1;border-color:#3366FF;cursor:pointer' onmouseover='objCalendar.swapImage(\"changeYear\",\"drop2.gif\");this.style.borderColor=\"#88AAFF\";window.status=\""+this.selectYearMessage+"\"' onmouseout='objCalendar.swapImage(\"changeYear\",\"drop1.gif\");this.style.borderColor=\"#3366FF\";window.status=\"\"'	onclick='objCalendar.popUpYear()'></span>&nbsp;";
			document.getElementById("caption").innerHTML  =	sHTML1;
			this.bPageLoaded=true;
	}

// End of class ===================================================================
}
