/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/* cnsCalendar v2.0: Insertion de calendriers JavaScript
/* cnsCalendar is (c) 2007 Clair et Net
/* http://www.www.clair-et-net.com
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar = function (thisCalendarId) {

	this.scriptName		= 'cnsCalendar.js';
	this.isHidden 		= false;
	this.isDestroyed 	= false;
	this.minYear 		= 1970;
	this.maxYear 		= 2050;
	this.isPopup 		= false;
	this.FirstDayOfWeek 	= 1;
	this.showWeekNumbers 	= true;
	this.showMonthNav 	= true;
	this.showOtherMonths 	= true;
	this.showTime 		= false;
	this.showToolTips	= false;
	this.hiliteToday 	= true;
	this.hiliteSelected 	= true;
	this.element 		= null;
	this.tbody 		= null;
	this.SelectedCell	= null;
	this.CalendarId		= (thisCalendarId) ? thisCalendarId : null;
	this.DateFormat		= 'DD/MM/YYYY';
	this.TargetInput	= null;
	this.baseURL 		= this.getBaseURL();
	this.Functions		= {};

	this.Params 			= {};
	this.Params['SEL_DATE'] 	= "Sélectionnez une date";
	this.Params['PREV_YEAR'] 	= "Année préc.";
	this.Params['PREV_MONTH'] 	= "Mois préc.";
	this.Params['GO_TODAY'] 	= "Atteindre la date du jour";
	this.Params['NEXT_MONTH'] 	= "Mois suiv.";
	this.Params['NEXT_YEAR'] 	= "Année suiv.";
	this.Params['DRAG_TO_MOVE'] 	= "Déplacer";
	this.Params['PART_TODAY'] 	= " (Aujourd'hui)";
	this.Params['WEEKEND'] 		= "0,6";
	this.Params['CLOSE'] 		= "Fermer";
	this.Params['TODAY'] 		= "Aujourd'hui";
	this.Params['CLOSE'] 		= "Fermer";
	this.Params['TODAY'] 		= "Aujourd'hui";
	this.Params['WEEK'] 		= "Sem.";
	this.Params['TIME'] 		= "Heure :";

	if (!window.popupWindowIndex) { window.popupWindowIndex = 0; }

	if (this.CalendarId == null) {
		this.CalendarId = 'cnsCalendar-' + popupWindowIndex;
		popupWindowIndex++;
	}

	//this.loadCSS();
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.is_ie 			= ( /msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent) );
Calendar.is_ie5 		= ( Calendar.is_ie && /msie 5\.0/i.test(navigator.userAgent) );
Calendar.is_opera 		= /opera/i.test(navigator.userAgent);
Calendar.is_khtml 		= /Konqueror|Safari|KHTML/i.test(navigator.userAgent);

Calendar.DaysInMonths 		= new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
Calendar.MonthNames 		= new Array ("Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre");
Calendar.ShortMonthNames	= new Array ("Jan", "Fev", "Mar", "Avr", "Mai", "Juin", "Juil", "Aout", "Sep", "Oct", "Nov", "Dec");
Calendar.DayNames		= new Array ("Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche");
Calendar.ShortDayNames		= new Array ("Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam", "Dim");
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.isClicked = function (thisEvent) {

	var myElement = Calendar.is_ie ? window.event.srcElement : thisEvent.target;
	var CalendarObj = window.cnsPopUpCalendar;

	isClicked = false;
	while (myElement.parentNode != null) {
		if (myElement.id == CalendarObj.element.id) {
			isClicked = true;
			break;
		}
		myElement = myElement.parentNode;
	}

	return isClicked;
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.doClick = function (thisEvent) {

	var myElement = Calendar.is_ie ? window.event.srcElement : thisEvent.currentTarget;

	var CalendarObj	= myElement.CalendarObj;
	var myDate 	= new Date(CalendarObj.CalendarDate);

	var myYear 	= myDate.getFullYear();
	var myMonth 	= myDate.getMonth();
	var myDay 	= myDate.getDate();

	var getMonthDays = function (thisDate, thisMonth) {

		var myYear = thisDate.getFullYear();

		if (typeof thisMonth == 'undefined') {
			var myMonth = this.getMonth();
		} else {
			var myMonth = thisMonth;
		}

		if (myMonth == 1) {
			return ((myYear % 4 == 0 && myYear % 100 != 0) || myYear % 400 == 0 ? 29 : 28);
		} else {
			return Calendar.DaysInMonths[myMonth];
		}
	}

	switch (myElement.ActionType) {
		case -2:
			if (myYear > CalendarObj.minYear) {
				myDate.setFullYear(myYear - 1);
			}
		break;
		case -1:
			if (myMonth > 0) {
				var thisMaxDays = getMonthDays(myDate, myMonth - 1);
				if (myDay > thisMaxDays) myDate.setDate(thisMaxDays);
				myDate.setMonth(myMonth - 1);
			} else if (myYear-- > CalendarObj.minYear) {
				myDate.setFullYear(myYear);
				myDate.setMonth(11);
			}
		break;
		case 0:
			myDate = new Date();
		break;
	    	case 1:
			if (myMonth < 11) {
				var thisMaxDays = getMonthDays(myDate, myMonth + 1);
				if (myDay > thisMaxDays) myDate.setDate(thisMaxDays);
				myDate.setMonth(myMonth + 1);
			} else if (myYear < CalendarObj.maxYear) {
				myDate.setFullYear(myYear + 1);
				myDate.setMonth(0);
			}
		break;
	    	case 2:
			if (myYear < CalendarObj.maxYear) {
				myDate.setFullYear(myYear + 1);
			}
		break;
		case 200:
			myElement.className = myElement.oClassName;
			CalendarObj.hide();
			return;
		break;
		case 999:
			if (CalendarObj.TargetInput != null) {
				CalendarObj.TargetInput.value = Calendar.formatDate(myElement.Date, CalendarObj.DateFormat);
			}
			if (CalendarObj.isPopup) {
				CalendarObj.hide();
			} else {
//				if (myElement.CalendarObj.SelectedCell.isOtherMonth) {
//					CalendarObj.draw(myElement.Date);
//				}

				myElement.className += ' Selected';
				myElement.oClassName = myElement.className;
				myElement.CalendarObj.SelectedCell.className = 'DayName';
				if (myElement.CalendarObj.SelectedCell.isOtherMonth) {
					myElement.CalendarObj.SelectedCell.className += ' OtherMonth';
				}

				if (myElement.CalendarObj.SelectedCell.isWeekEndDay) {
					myElement.CalendarObj.SelectedCell.className += ' WeekEnd';
				}
			}
			myElement.CalendarObj.SelectedCell = myElement;
			
			if (CalendarObj.Functions) {
				for (var i in CalendarObj.Functions) {
					eval(CalendarObj.Functions[i]);
				}
			}

			return;
		break;
	}

	if (!CalendarObj.isDateEqual(myDate, CalendarObj.CalendarDate)) {
		CalendarObj.draw(myDate);
	}
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.doMouseOver = function(thisEvent) {

	var myElement = Calendar.is_ie ? window.event.srcElement : thisEvent.currentTarget;

	myElement.oClassName = myElement.className;

	if (myElement.parentNode) {
		myElement.oParentClassName = myElement.parentNode.className;
	}

	if (myElement.ToolTip) {
		myElement.CalendarObj.ToolTips.innerHTML = myElement.ToolTip;
	}

	myElement.className += ' hilite';

	if (myElement.isDateCell) {
		myElement.parentNode.className += ' rowhilite';
	}
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.doMouseOut = function(thisEvent) {

	var myElement = Calendar.is_ie ? window.event.srcElement : thisEvent.currentTarget;

	myElement.className = myElement.oClassName;

	if (myElement.isDateCell) {
		myElement.parentNode.className = myElement.oParentClassName;
	}

	if (myElement.CalendarObj && myElement.CalendarObj.showToolTips) {
		myElement.CalendarObj.ToolTips.innerHTML = myElement.CalendarObj.Params['SEL_DATE'];
	}
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.doCheck = function(thisEvent) {

	var CalendarObj = window.cnsPopUpCalendar;
	var isClicked = Calendar.isClicked(thisEvent);
	if (!isClicked && !CalendarObj.isHidden) {
		CalendarObj.hide();
	}
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.setClock = function (thisElement) {
	if (!Calendar.Timers) { Calendar.Timers = new Array(); }
	this.updateClock(thisElement.id);

}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.updateClock = function (thisElementId) {

	var tid = new Date();
	var h = tid.getHours();
	var m = tid.getMinutes();
	var s = tid.getSeconds();

	hrs = (h >= 10) ? h : ('0' + h);
	mns = (m >= 10) ? (':' + m) : (':0' + m);
	scs = (s >= 10) ? (':' + s):(':0' + s);

	var myClock = document.getElementById(thisElementId);

	if (!myClock) {
		clearTimeout(Calendar.Timers[thisElementId]);
	} else {
		myClock.innerHTML = hrs + mns + scs;
		Calendar.Timers[thisElementId] = setTimeout('Calendar.updateClock(\'' + thisElementId + '\')', 1000);
	}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.formatDate = function (thisDate, thisFormat) {

	var myFormat 	= new String(thisFormat);
	var myDate 	= '';
	var c 		= '';
	var Y 		= thisDate.getYear()+"";
	var M		= thisDate.getMonth()+1;
	var D		= thisDate.getDate();
	var E		= thisDate.getDay();
	var h		= thisDate.getHours();
	var m		= thisDate.getMinutes();
	var s		= thisDate.getSeconds();
	var value 	= new Object();

	myFormat.toUpperCase;

	if (Y.length < 4) {
		Y = '' + (Y - 0 + 1900);
	}
	value['Y'] 	= '' + Y;
	value['YYYY']	= Y;
	value['YY'] 	= Y.substring(2, 4);
	value['M']	= M;
	value['MM'] 	= (M < 0 || M > 9) ? M : '0' + M;
	value['MMM'] 	= Calendar.MonthNames[M - 1];
	value['NNN']	= Calendar.MonthNames[M + 11];
	value['D']	= D;
	value['DD']	= (D < 0 || D > 9) ? D : '0' + D;;
	value['E']	= Calendar.DayNames[E + 7];
	value['EE']	= Calendar.DayNames[E];
	value['h']	= h;
	value['hh'] 	= (h < 0 || h > 9) ? h : '0' + h;
	value['m']	= m;
	value['mm']	= (m < 0 || m > 9) ? m : '0' + m;
	value['s']	= s;
	value['ss'] 	= (s < 0 || s > 9) ? s : '0' + s;

	i = 0;
	while (i < myFormat.length) {
		c = myFormat.charAt(i);
		token = '';
		while ((myFormat.charAt(i) == c) && (i < myFormat.length)) {
			token += myFormat.charAt(i++);
		}
		if (value[token] != null) {
			myDate = myDate + value[token];
		} else {
			myDate = myDate + token;
		}
	}
	return myDate;
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.prototype.addFunction = function(fn) {

	this.Functions[this.Functions.length] = fn;

}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.prototype.getBaseURL = function () {

	var scripts = document.getElementsByTagName('script');

	for (var i = 0; i < scripts.length; i++) {
		if (scripts[i].src && (scripts[i].src.indexOf(this.scriptName) != -1)) {

			var src = scripts[i].src;

			if (src.lastIndexOf(document.location.host) != -1) {
				src = src.substring(src.lastIndexOf(document.location.host) + document.location.host.length);
			}

			baseURL = src.substring(0, src.lastIndexOf(this.scriptName));

			if (baseURL.substring(0, 2) == './') {
				baseURL = document.location.pathname.substring(0, document.location.pathname.lastIndexOf('/')) + '/' + this.baseURL.substring(2);
			} else if (baseURL.substring(0, 1) != '/') {
				baseURL = document.location.pathname.substring(0, document.location.pathname.lastIndexOf('/')) + '/' + this.baseURL;
			}

			if (baseURL.substring(baseURL.length - 1) == '/') {
				baseURL = baseURL.substring(0, baseURL.length - 1);
			}

		}
	}
	return baseURL

}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.prototype.loadCSS = function () {

	var element;

	element 	= document.createElement('link');
	element.rel	= 'stylesheet';
	element.type	= 'text/css';
	element.href 	= this.baseURL + '/css/cnsCalendar.css';

	document.getElementsByTagName('head')[0].appendChild(element);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.prototype.createPopup = function () {

	this.isPopup = true;
	this.create();
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.prototype.create = function () {

	if (this.TargetInput != null && this.TargetInput.value != '') {
		this.Date 		= Calendar.getDateFromFormat(this.TargetInput.value, this.DateFormat);
		this.CalendarDate 	= this.Date;
	} else {
		this.Date 		= new Date();
		this.CalendarDate 	= this.Date;
	}

	var myDiv 		= this.createElement('div', document.body);
	this.element 		= myDiv;
	myDiv.id		= Calendar.CalendarId = this.CalendarId;
	myDiv.className 	= 'cnsCalendar';
	myDiv.style.display 	= 'none';
	this.isHidden 		= true;

	if (this.isPopup) {
		myDiv.style.position = 'absolute';
	}

	var myTable = this.createElement('table', myDiv);

	myTable.cellSpacing = 0;
	myTable.cellPadding = 0;

	var myThead 	= this.createElement('thead', myTable);
	var myCell 	= null;
	var myRow 	= null;

	var CalendarObj	= this;

	myRow = this.createElement('tr', myThead);

	var TitleColspan = 7;
	if (this.isPopup) --TitleColspan;
	if (this.showWeekNumbers) ++TitleColspan;

	this.title 		= this.createButton(myRow, '', TitleColspan, 300);
	this.title.className 	= 'CalendarTitle';

	if (this.isPopup) {
		this.createButton(myRow, '&#x00d7;', 1, 200);
	}

	myRow 		= this.createElement('tr', myThead);
	myRow.className = 'CalendarNav';

	if (this.showMonthNav) {
		this.createButton(myRow, '&#x00ab;', 1, -2);
		this.createButton(myRow, '&#x2039;', 1, -1);
	}

	colSpan = (this.showWeekNumbers ? 4 : 3) + (this.showMonthNav ? 0 : 4);

	this.createButton(myRow, this.Params['TODAY'], colSpan, 0);

	if (this.showMonthNav) {
		this.createButton(myRow, '&#x203a;', 1, 1);
		this.createButton(myRow, '&#x00bb;', 1, 2);
	}

	myRow 			= this.createElement('tr', myThead);
	myRow.className 	= 'DayNames';

	if (this.showWeekNumbers) {
		myCell 			= this.createElement('td', myRow);
		myCell.className 	= 'DayName';
		myCell.innerHTML 	= this.Params['WEEK'];
	}

	this.FirstDayName 	= (this.showWeekNumbers) ? myRow.firstChild.nextSibling : myRow.firstChild;
	var FirstDayOfWeek 	= this.FirstDayOfWeek;
	var myCell 		= this.FirstDayName;

	for (var i = 0; i < 7; ++i) {
		myCell 			= this.createElement('td', myRow);
		var thisWeekDay 	= (i + FirstDayOfWeek) % 7;
		myCell.className 	= (thisWeekDay == 0 || thisWeekDay == 6) ? 'DayName WeekEnd' : 'DayName';
		myCell.innerHTML 	= Calendar.ShortDayNames[thisWeekDay];
	}

	var tbody 	= this.createElement('tbody', myTable);
	this.tbody 	= tbody;

	for (i = 6; i > 0; --i) {
		myRow = this.createElement('tr', tbody);

		if (this.showWeekNumbers) {
			myCell = this.createElement('td', myRow);
		}

		for (var j = 7; j > 0; --j) {
			myCell = this.createElement('td', myRow);
			myCell.CalendarObj = this;

			this.addEvent(myCell, 'onmouseover', Calendar.doMouseOver);
			this.addEvent(myCell, 'onmouseout', Calendar.doMouseOut);
			this.addEvent(myCell, 'onclick', Calendar.doClick);
		}
	}

	if (this.showTime) {

		myRow 			= this.createElement('tr', tbody);

		myCell 			= this.createElement('td', myRow);
		myCell.className 	= 'TimeCell';
		myCell.colSpan 		= 2;
		myCell.innerHTML 	= this.Params['TIME'] || '&nbsp;';

		myCell 			= this.createElement('td', myRow);
		myCell.className 	= 'TimeCell';
		myCell.colSpan 		= this.showWeekNumbers ? 4 : 3;

		var span 		= this.createElement('span', myCell);
		span.className 		= 'Time';
		span.id			= this.CalendarId + '-clock';

		Calendar.setClock(span);

		myCell 			= this.createElement('td', myRow);
		myCell.className 	= 'TimeCell';
		myCell.colSpan 		= 2;
		myCell.innerHTML 	= '&nbsp;';

	}

	if (this.showToolTips) {
		var myTfoot 		= this.createElement('tfoot', myTable);
		myRow 			= this.createElement('tr', myTfoot);

		myCell 			= this.createButton(myRow, this.Params['SEL_DATE'], this.showWeekNumbers ? 8 : 7, 300);
		myCell.className 	= 'ToolTips';

		this.ToolTips 		= myCell;
	}

	this.draw(this.CalendarDate);
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.prototype.createButton = function (thisRow, Text, colSpan, ActionType) {

	var myCell = this.createElement('td', thisRow);

	myCell.colSpan 		= colSpan;
	myCell.className 	= 'Button';
	myCell.ActionType	= ActionType;
	myCell.CalendarObj 	= this;
	myCell.innerHTML 	= Text;
	myCell.style.cursor 	= (ActionType != 300) ? ((Calendar.is_ie5) ? 'hand' : 'pointer') : '';

	switch(ActionType) {
		case -2 :
			if (this.showToolTips) { myCell.ToolTip = this.Params['PREV_YEAR']; };
			this.addEvent(myCell, 'onclick', Calendar.doClick);
			this.addEvent(myCell, 'onmouseover', Calendar.doMouseOver);
			this.addEvent(myCell, 'onmouseout', Calendar.doMouseOut);
		break;
		case -1 :
			if (this.showToolTips) { myCell.ToolTip = this.Params['PREV_MONTH']; };
			this.addEvent(myCell, 'onclick', Calendar.doClick);
			this.addEvent(myCell, 'onmouseover', Calendar.doMouseOver);
			this.addEvent(myCell, 'onmouseout', Calendar.doMouseOut);
		break;
		case 0 :
			if (this.showToolTips) { myCell.ToolTip = this.Params['TODAY']; };
			this.addEvent(myCell, 'onclick', Calendar.doClick);
			this.addEvent(myCell, 'onmouseover', Calendar.doMouseOver);
			this.addEvent(myCell, 'onmouseout', Calendar.doMouseOut);
		break;
		case 1 :
			if (this.showToolTips) { myCell.ToolTip = this.Params['NEXT_MONTH']; };
			this.addEvent(myCell, 'onclick', Calendar.doClick);
			this.addEvent(myCell, 'onmouseover', Calendar.doMouseOver);
			this.addEvent(myCell, 'onmouseout', Calendar.doMouseOut);
		break;
		case 2 :
			if (this.showToolTips) { myCell.ToolTip = this.Params['NEXT_YEAR']; };
			this.addEvent(myCell, 'onclick', Calendar.doClick);
			this.addEvent(myCell, 'onmouseover', Calendar.doMouseOver);
			this.addEvent(myCell, 'onmouseout', Calendar.doMouseOut);
		break;
		case 200 :
			if (this.showToolTips) { myCell.ToolTip = this.Params['CLOSE']; };
			this.addEvent(myCell, 'onclick', Calendar.doClick);
			this.addEvent(myCell, 'onmouseover', Calendar.doMouseOver);
			this.addEvent(myCell, 'onmouseout', Calendar.doMouseOut);
		break;
	}

	return myCell;
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.prototype.draw = function (thisDate) {

	thisDate		= (thisDate) ? new Date(thisDate) : new Date();
	this.CalendarDate 	= thisDate;

	var Today 		= new Date();
	var TodayYear 		= Today.getFullYear();
	var TodayMonth 		= Today.getMonth();
	var TodayDay		= Today.getDate();

	var myCurrentDate 	= new Date(thisDate);
	var myCurrentYear 	= myCurrentDate.getFullYear();
	var myCurrentMonth 	= myCurrentDate.getMonth();
	var myCurrentDay	= myCurrentDate.getDate();
	var myDate		= myCurrentDate;

	if (myCurrentYear < this.minYear) {
		myCurrentYear = this.minYear;
		myDate.setFullYear(myCurrentYear);
	} else if (myCurrentYear > this.maxYear) {
		myCurrentYear = this.maxYear;
		myDate.setFullYear(myCurrentYear);
	}

	myDate.setDate(1);
	var DayOffset = (myDate.getDay() - this.FirstDayOfWeek) % 7;
	if (DayOffset < 0) DayOffset += 7;
	myDate.setDate(-DayOffset);
	myDate.setDate(myDate.getDate() + 1);

	var myRow = this.tbody.firstChild;

	for (var i = 0; i < 6; ++i) {

		var myCell = myRow.firstChild;

		if (this.showWeekNumbers) {
			myCell.className = 'WeekNumber';
			myCell.oClassName = myCell.className;
			myCell.innerHTML = this.getWeekNumber(myDate);
			myCell = myCell.nextSibling;
		}

		var hasdays = false;

		for (var j = 0; j < 7; ++j) {

			myDay 		= myDate.getDate();
			myWeekDay 	= myDate.getDay();
			myMonth		= myDate.getMonth();
			myYear		= myDate.getFullYear();

			myCell.className 	= 'DayName';

			var isCurrentMonth = (myMonth == myCurrentMonth);

			if (!isCurrentMonth) {
				myCell.isOtherMonth = true;
				if (this.showOtherMonths) {
					myCell.className 		+= ' OtherMonth';
					myCell.isCellDisabled 	= true;
				} else {
					myCell.className 		= 'emptycell';
					myCell.innerHTML 		= '&nbsp;';
					myCell.isCellDisabled 	= true;
				}
			} else {
				myCell.isCellDisabled 	= false;
				myCell.isOtherMonth 	= false;
				hasdays 		= true;
			}

			myCell.innerHTML 	= myDay;
			myCell.CalendarObj 	= this;

			if (!myCell.isCellDisabled) {
				myCell.ActionType 	= 999;
				myCell.style.cursor 	= (Calendar.is_ie5) ? 'hand' : 'pointer';
			} else {
				myCell.style.cursor 	= 'default';
			}

			myCell.isDateCell 	= true;
			myCell.isWeekEndDay 	= (myWeekDay == 0 || myWeekDay == 6) ? true : false;
			myCell.Date 		= new Date(myDate);


			if (this.showToolTips) {
				myCell.ToolTip = Calendar.DayNames[myWeekDay] + ' ' + myDay + ' ' + Calendar.MonthNames[myMonth] + ' ' + myYear;
			}

			if (myYear == TodayYear && myMonth == TodayMonth && myDay == TodayDay) {
				if (this.hiliteToday) {
					myCell.className += ' Today';
				}

				if (this.showToolTips) {
					myCell.ToolTip += this.Params['PART_TODAY'];
				}
			}

			if (myCell.isWeekEndDay) {
				myCell.className += ' WeekEnd';
			}

			if (this.hiliteSelected && this.Date) {
				mySelectedDate = new Date(this.Date);
				if (mySelectedDate.getDate() == myDay && mySelectedDate.getMonth() == myMonth && mySelectedDate.getFullYear() == myYear) {
					myCell.className += ' Selected';
					this.SelectedCell = myCell;
				}
			}

			myDate.setDate(myDay + 1);
			myCell = myCell.nextSibling
		}

		if (!(hasdays || this.showOtherMonths)) {
			myRow.className = 'emptyrow';
		}

		myRow = myRow.nextSibling

	}

	this.title.innerHTML = Calendar.MonthNames[myCurrentMonth] + ' ' + myCurrentYear;
//	this.ToolTips.innerHTML = 'Generated in ' + ((new Date()) - Today) + ' ms';
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.prototype.createElement = function(type, parent) {
	var myElement = null;
	if (document.createElementNS) {
		myElement = document.createElementNS('http://www.w3.org/1999/xhtml', type);
	} else {
		myElement = document.createElement(type);
	}
	if (typeof parent != 'undefined') {
		parent.appendChild(myElement);
	}
	return myElement;
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.prototype.addEvent = function(thisElement, thisEvent, thisFunction) {

	if (thisElement.attachEvent) {
		thisElement.attachEvent(thisEvent, thisFunction);
	} else if (thisElement.addEventListener) {
		thisElement.addEventListener(thisEvent.substr(2, thisEvent.length), thisFunction, true);
	} else {
		thisElement[thisEvent] = thisFunction;
	}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.prototype.delEvent = function(thisElement, thisEvent, thisFunction) {

	if (thisElement.detachEvent) {
		thisElement.detachEvent(thisEvent, thisFunction);
	} else if (thisElement.removeEventListener) {
		thisElement.removeEventListener(thisEvent.substr(2, thisEvent.length), thisFunction, true);
	} else {
		thisElement[thisEvent] = null;
	}
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.prototype.refresh = function () {
	this.draw(this.Date);
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.prototype.setRange = function (a, z) {
	this.minYear = a;
	this.maxYear = z;
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.prototype.reparent = function (new_parent) {
	var el = this.element;
	el.parentNode.removeChild(el);
	new_parent.appendChild(el);
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.prototype.show = function (thisElement) {

	var parentHandler = null;

	if (!thisElement) {
		parentHandler = document.getElementsByTagName('body')[0];
	} else {
		parentHandler = document.getElementById(thisElement);
	}

	if (this.isPopup) {
		this.addEvent(document, 'onmouseup', Calendar.doCheck);
		window.cnsPopUpCalendar = this;
	} else {
		parentHandler.appendChild(this.element);
	}

	this.element.style.display 	= 'block';
	this.element.style.visibility 	= 'visible';
	this.isHidden 			= false;
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.prototype.showAtPosition = function (x, y) {
	this.element.style.left = x + 'px';
	this.element.style.top = y + 'px';
	this.show();
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.prototype.showAtElement = function (thisElement) {

	if (document.getElementById(thisElement)) {
		var myElement = document.getElementById(thisElement);
	} else if (document.getElementsByName(thisElement)) {
		var myElements = document.getElementsByName(thisElement);
		if (myElements.length == 0 || myElements.length > 1) {
			return;
		}
		var myElement = myElements.item(0);
	} else {
		return;
	}

	var pos = this.getAbsolutePos(myElement);
	this.showAtPosition(pos.x + myElement.offsetWidth, pos.y);

	return true;
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.prototype.hide = function () {

	this.element.style.visibility 	= 'hidden';
	this.isHidden 			= true;

	if (this.isPopup) {
		this.delEvent(document, 'onmouseup', Calendar.doCheck);
		this.destroy();
		popupWindowIndex--;
	}
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.prototype.destroy = function(){
	var myElement = this.element.parentNode;
	myElement.removeChild(this.element);
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.prototype.setTargetInput = function(thisElement) {

	if (document.getElementById(thisElement)) {
		var myElement = document.getElementById(thisElement);
	} else if (document.getElementsByName(thisElement)) {
		var myElements = document.getElementsByName(thisElement);
		if (myElements.length == 0 || myElements.length > 1) {
			return;
		}
		var myElement = myElements.item(0);
	} else {
		return;
	}

	if (myElement.type != 'text' && myElement.type != 'hidden' && myElement.type != 'textarea') {
		this.TargetInput = null;
		return;
	}

	this.TargetInput = myElement;
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.prototype.getAbsolutePos = function(thisElement) {

	var SL = 0, ST = 0;
	var is_div = /^div$/i.test(thisElement.tagName);
	if (is_div && thisElement.scrollLeft)
		SL = thisElement.scrollLeft;
	if (is_div && thisElement.scrollTop)
		ST = thisElement.scrollTop;
	var r = { x: thisElement.offsetLeft - SL, y: thisElement.offsetTop - ST };
	if (thisElement.offsetParent) {
		var tmp = this.getAbsolutePos(thisElement.offsetParent);
		r.x += tmp.x;
		r.y += tmp.y;
	}
	return r;
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.prototype.getWeekNumber = function(thisDate) {

	var myDate = new Date(thisDate.getFullYear(), thisDate.getMonth(), thisDate.getDate(), 0, 0, 0);
	var thisDayOfWeek = myDate.getDay();
	myDate.setDate(myDate.getDate() - (thisDayOfWeek + 6) % 7 + 3);
	var ms = myDate.valueOf();
	myDate.setMonth(0);
	myDate.setDate(4);
	return Math.round((ms - myDate.valueOf()) / (7 * 864e5)) + 1;
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.prototype.isDateEqual = function(thisDate, thisOtherDate) {
	return ((thisDate.getFullYear() == thisOtherDate.getFullYear()) && (thisDate.getMonth() == thisOtherDate.getMonth()) && (thisDate.getDate() == thisOtherDate.getDate()));
};
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.getDateFromFormat = function (thisDate, thisFormat) {


	var myFormat 	= new String(thisFormat);
	var myDate 	= new String(thisDate);
	var myToken 	= new String();
	var myKey 	= new String();
	var myValue 	= new Object();

	if (!Calendar.isDate(thisDate)) {
		return null;
	}

	myFormat.toUpperCase;

	i = 0;
	j = 0;
	while (i < myFormat.length) {
		var c = myFormat.charAt(i);

		var myFormatToken = new String();
		while ((myFormat.charAt(i) == c) && (i < myFormat.length)) {
			myFormatToken += myFormat.charAt(i++);
		}

		var getValue = false;
		if (myFormatToken == 'YYYY' || myFormatToken == 'YY' || myFormatToken == 'Y') {
			myKey 	= 'Y';
			if (myTokenValue = myDate.substr(j, myFormatToken.length)) {
				myValue[myKey] = myTokenValue;
			} else {
				myValue[myKey] = 0;
			}
		}
		if (myFormatToken == 'MM' || myFormatToken == 'M') {
			myKey 	= 'M';
			if (myTokenValue = myDate.substr(j, myFormatToken.length)) {
				myValue[myKey] = myTokenValue;
			} else {
				myValue[myKey] = 0;
			}
		}
		if (myFormatToken == 'DD' || myFormatToken == 'D') {
			myKey 	= 'D';
			if (myTokenValue = myDate.substr(j, myFormatToken.length)) {
				myValue[myKey] = myTokenValue;
			} else {
				myValue[myKey] = 0;
			}
		}

		j += myFormatToken.length;
	}

	var myNewDate = new Date(myValue['Y'], myValue['M'] - 1, myValue['D'], 0, 0, 0);

	return myNewDate;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
Calendar.isDate = function (dateStr) {

	var datePat = /^(\d{1,2})(\/|-)(\d{1,2})(\/|-)(\d{4})$/;
	var matchArray = dateStr.match(datePat); // is the format ok?

	if (matchArray == null) {
		return false;
	}

	month = matchArray[1];
	day = matchArray[3];
	year = matchArray[5];

	if (month < 1 || month > 12) {
		return false;
	}

	if (day < 1 || day > 31) {
		return false;
	}

	if ((month==4 || month==6 || month==9 || month==11) && day==31) {
		return false;
	}

	if (month == 2) {
		var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
		if (day > 29 || (day==29 && !isleap)) {
			return false;
		}
	}

	return true;
}

/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/