
/***************************************
 *           datepicker.js             *
 ***************************************
 * Date Picker class manager.          *
 ***************************************
 * History														 *
 *																		 *
 *  26/04/2005: v2.5									 *
 * Switch calendars   								 *
 *																		 *
 * 30/12/2004: v1.27                   *
 * Changed event handling for					 *
 * Firefox compatibility. 						 *
 *																		 *
 *  29/04/2003: v1.26									 *
 ***************************************
 * (c) Gabriel Zerbib,                 *
 *   gabriel@bumpt.net                 *
 *   http://www.bumpt.net              *
 *                                     *
 * It is strictly forbidden to use or  *
 * reproduce all or parts of this      *
 * program without author's explicit   *
 * permission.                         *
 * Commercial use of this program is   *
 * subject to purchase. Please contact *
 * the author.                         *
 ***************************************/


function computeLeft(o)
{
	var obj = o;
	var x = 0;
	while(obj)
	{
		x += obj.offsetLeft;
		obj = obj.offsetParent;
	}
	return x;
}
function computeTop(o)
{
	var obj = o;
	var y = 0;
	while(obj)
	{
		y += obj.offsetTop;
		obj = obj.offsetParent;
	}
	return y;
}

DatePicker.invoke = function (id, func, arg)
{
	var picker = DatePicker.ids[id];
	var command = "picker." + func + "(" + (arg ? arg : "") + ")";
	eval(command);
}

DatePicker.currentlyOpen = null;
DatePicker.ids = [];

function DatePicker()
{
	this.onchoosedate = null;
	this.onhoverdate = null;
	this.oncancel = null;
	this.onhovercancel = null;
	this.onhelp = null;


	this.inited = false;
	this.date = null;
	this.tempDate = null;
	this.div = null;
	this.spanCurrentMonth = null;
	this.spanCurrentYear = null;
	this.hidden = true;
	this.img = null;
	this.imgSrc = "";
	this.imgPushedSrc = "";

	this.getDate = function () { return new (this.date.Class)(this.date); };

	this.hovercancel = function()
	{
		var fn = this.onhovercancel;
		if(fn) fn();
	}
	this.hover = function (n)
	{
		this.tempDate.setDay(n);
		var eDate = new (this.tempDate.Class)(this.tempDate);
		var fn = this.onhoverdate;
		if(fn) fn(eDate);
	}

	this.chooseDate = function (d)
	{
		if(! d) d = this.tempDate.getDay();
		this.date.setDate(d, this.tempDate.getMonth(), this.tempDate.getYear());
		var fn = this.onchoosedate;
		if(fn) fn(new (this.date.Class)(this.date));
	}

	this.checkYear = function (y)
	{
		var y = parseInt(y);
		if(isNaN(y)) return;
		this.tempDate.setYear(y);
		this.refresh(true);
		var fn = this.onhoverdate;
		if(fn) fn(new (this.tempDate.Class)(this.tempDate));
	}

	this.editYear = function ()
	{
		var input;
		this.spanCurrentYear.innerHTML = "";
		this.spanCurrentYear.onclick_ = this.spanCurrentYear.onclick;
		this.spanCurrentYear.onclick = null;
		input = document.createElement("INPUT");
		input.size = 4;
		input.maxLength = 4;
		input.picker = this;
		input.value = this.tempDate.getYear();
		input.style.borderStyle = "none";
		input.style.fontSize = "8pt";

		input.onkeypress = function (evt)
		{
			evt = new Event(evt);
			if(evt.keyCode == 13)
			{
				evt.src.picker.checkYear(evt.src.value);
				try { evt.stopPropagation(); } catch(exc) { }
			}
		};

		input.onblur = function(evt)
		{
			evt = new Event(evt);
			evt.src.picker.checkYear(evt.src.value);
		};

		this.spanCurrentYear.appendChild(input);
		input.select();
		input.focus();
	}

	this.toggleVisible = function ()
	{
		if(this.hidden) this.show();
		else this.cancel();
	}

	this.hide = function(store)
	{
		DatePicker.currentlyOpen = null;
		if(this.div) this.div.style.display = "none";
		this.hidden = true;
		if(this.img) this.img.src = this.imgSrc;
		if(store) this.chooseDate();
	}

	this.cancel = function()
	{
		this.hide();
		var fn = this.oncancel;	//secure object by not calling this.oncancel()
		if(fn) fn();
	}

	this.help = function()
	{
		var fn = this.onhelp;
		if(fn) fn();
	}
	
	this.switchCalendar = function()
	{
		var fn = this.onswitchCalendar;
		if(fn) fn(new (this.date.Class) (this.tempDate) );
	}

	this.show = function(initDate)
	{
		var imgTop, imgLeft;

		if(typeof(initDate) != "undefined")
			this.tempDate = new (this.date.Class)(initDate);
		else
			this.tempDate = new (this.date.Class)(this.date);

		if(DatePicker.currentlyOpen)
			DatePicker.currentlyOpen.hide();
		DatePicker.currentlyOpen = this;

		if(! this.inited)
		{
			this.init();
			this.refresh(true);
		}
		else
			this.refresh();

		if(this.img)
		{
			imgTop = computeTop(this.img);
			imgLeft = computeLeft(this.img);
		}
		this.div.style.display = "inline";

		if(this.img)
		{
			this.div.style.left = imgLeft - this.div.clientWidth + this.img.width;
			this.div.style.top = imgTop + this.img.height;
			if(this.div.childNodes[0].clientHeight + parseInt(this.div.style.top) > this.div.offsetParent.clientHeight)
				this.div.style.top = imgTop - this.div.childNodes[0].clientHeight - 5;
		}

		this.hidden = false;
		if(this.img) this.img.src = this.imgPushedSrc;
	}

	this.nextMonth = function()
	{
		this.tempDate.nextMonth();
		this.refresh();
		var fn = this.onhoverdate;
		if(fn) fn(new (this.tempDate.Class)(this.tempDate));
	}
	this.prevMonth = function()
	{
		this.tempDate.prevMonth();
		this.refresh();
		var fn = this.onhoverdate;
		if(fn) fn(new (this.tempDate.Class)(this.tempDate));
	}
	this.prevYear = function()
	{
		this.tempDate.setYear(this.tempDate.getYear() - 1);
		this.refresh();
		var fn = this.onhoverdate;
		if(fn) fn(new (this.tempDate.Class)(this.tempDate));
	}
	this.nextYear = function()
	{
		this.tempDate.setYear(this.tempDate.getYear() + 1);
		this.refresh();
		var fn = this.onhoverdate;
		if(fn) fn(new (this.tempDate.Class)(this.tempDate));
	}


	this.attach = function(div, img, imgPushedSrc, stringHelpPicker, stringCancelPicker)
	{
		this.div = div;
		this.img = img;
		this.imgPushedSrc = imgPushedSrc;
		if(this.img) this.imgSrc = img.src;
		this.stringCancelPicker = stringCancelPicker;
		this.stringHelpPicker = stringHelpPicker;
		div.picker = this;
	}

	this.init = function init()
	{
		var table, tbody, tr, td, trHeader, tbodyGlobal;

		this.id = "DatePicker." + Math.random();
		DatePicker.ids[this.id] = this;
		this.inited = true;

		this.div.style.cursor = "default";

		/*
		 * table générale
		 */
		this.div.appendChild(table = document.createElement("TABLE"));
		table.width = "100%";
		table.cellSpacing = 0;
		table.cellPadding = 1;
		table.style.fontFamily = "Arial";
		table.style.fontSize = "8pt";
		table.style.textAlign = "center";

		table.appendChild(tbodyGlobal = document.createElement("TBODY"));
		tbodyGlobal.appendChild(trHeader = document.createElement("TR"));
		trHeader.appendChild(td = document.createElement("TD"));


		/*
		 * table header
		 */
		td.appendChild(table = document.createElement("TABLE"));

		table.width = "100%";
		table.border = 0;
		table.cellSpacing = 1;
		table.style.textAlign = "center";

		table.appendChild(tbody = document.createElement("TBODY"));
		tbody.appendChild(tr = document.createElement("TR"));


		tr.appendChild(td = document.createElement("TD"));
		tr.picker = this;

		with(td)
		{
			width = 1;
			style.backgroundColor = "silver";
			style.border = "solid 1px black";
			style.cursor = "hand";
			innerHTML = '<A style="font-weight: bold; text-decoration: none; color: gray;" href="javascript:DatePicker.invoke(\'' + this.id + '\', \'prevYear\')">&lt;&lt;</A>';
		}

		tr.appendChild(td = document.createElement("TD"));
		with(td)
		{
			width = 1;
			style.backgroundColor = "silver";
			style.border = "solid 1px black";
			style.cursor = "hand";
			innerHTML = '<A style="font-weight: bold; text-decoration: none; color: gray;" href="javascript:DatePicker.invoke(\'' + this.id + '\', \'prevMonth\')">&lt;</A>';
		}

		tr.appendChild(td = document.createElement("TD"));
		with(td)
		{
			style.color ="white";
			style.backgroundColor = "silver";
			style.border = "solid 1px black";
			style.fontWeight = "bold";
			style.color = "gray";
			style.fontSize = "9pt";
			appendChild(this.spanCurrentMonth = document.createElement("SPAN"));
			appendChild(this.spanCurrentYear = document.createElement("SPAN"));
		}
		this.spanCurrentYear.style.cursor = "hand";


		tr.appendChild(td = document.createElement("TD"));
		with(td)
		{
			width = 1;
			style.backgroundColor = "silver";
			style.border = "solid 1px black";
			innerHTML = '<A style="font-weight: bold; text-decoration: none; color: gray;" href="javascript:DatePicker.invoke(\'' + this.id + '\', \'nextMonth\')">&gt;</A>';
		}


		tr.appendChild(td = document.createElement("TD"));
		with(td)
		{
			width = 1;
			style.color ="white";
			style.backgroundColor = "silver";
			style.border = "solid 1px black";
			innerHTML = '<A style="font-weight: bold; text-decoration: none; color: gray;" href="javascript:DatePicker.invoke(\'' + this.id + '\', \'nextYear\')">&gt;&gt;</A>';
		}


		/*
		 * table jours
		 */

		tbodyGlobal.appendChild(tr = document.createElement("TR"));
		tr.appendChild(td = document.createElement("TD"));
		td.appendChild(table = document.createElement("TABLE"));
		with(table)
		{
			width = "100%";
			border = 0;
			cellSpacing = 0;
			style.fontFamily = "Arial";
			style.fontSize = "8pt";
			style.textAlign = "center";
		}

		table.appendChild(tbody = document.createElement("TBODY"));
		tbody.appendChild(tr = document.createElement("TR"));

		for(var i = 0; i < 7; i ++)
		{
			tr.appendChild(td = document.createElement("TD"));
			td.style.borderBottomStyle = "solid";
			td.style.borderColor = "black";
			td.style.borderWidth = "1px";
			td.innerHTML = this.date.Class.WeekdayNameShortest(i);
		}

		table.appendChild(tbody = document.createElement("TBODY"));
		this.tbodyDays = tbody;


		for(var i = 0; i < 6; i ++)
		{
			tbody.appendChild(tr = document.createElement("TR"));
			for(var j = 0; j < 7; j ++)
			{
				tr.appendChild(td = document.createElement("TD"));
				td.style.fontWeight = "bold";
				td.innerHTML = "&nbsp;";
			}
		}



		/*
		 * table footer
		 */
		tbodyGlobal.appendChild(tr = document.createElement("TR"));
		tr.appendChild(td = document.createElement("TD"));
		with(td.style)
		{
			borderTopStyle = "solid";
			borderWidth = "1px";
			borderColor = "black";
		}
		td.appendChild(table = document.createElement("TABLE"));
		table.width = "100%";
		table.border = 0;
		table.cellSpacing = 1;
		table.style.textAlign = "center";
		table.appendChild(tbody = document.createElement("TBODY"));
		tbody.appendChild(tr = document.createElement("TR"));

		tr.appendChild(td = document.createElement("TD"));
		td.style.fontSize = "8pt";
		td.style.textAlign = "left";
		if(this.onswitchCalendar)
			td.innerHTML = '<a href="javascript:DatePicker.invoke(\'' + this.id + '\', \'switchCalendar\')">' + "G<>H" + "</a>";

		tr.appendChild(td = document.createElement("TD"));
		td.style.fontSize = "8pt";
		td.style.textAlign = "left";
		td.innerHTML = '<A href="javascript:DatePicker.invoke(\'' + this.id + '\', \'help\')">' + (this.stringHelpPicker ? this.stringHelpPicker : '?') + '</A>';

		tr.appendChild(td = document.createElement("TD"));
		td.style.fontSize = "8pt";
		td.style.textAlign = "right";
		td.innerHTML = '<A ' + (this.onhovercancel ? 'onmouseover="DatePicker.invoke(\'' + this.id + '\', \'hovercancel\')"' : '') + ' href="javascript:DatePicker.invoke(\'' + this.id + '\', \'cancel\')">' + (this.stringCancelPicker ? this.stringCancelPicker : 'X') + '</A>';

	}



	this.refresh = function (bSetFocusYear)
	{
		var g, tbody, td, i, j, n;
		var dow, ml;

		tbody = this.tbodyDays;

		g = new (this.tempDate.Class)(this.tempDate);
		g.setDay(1);
		m = g.getMonth();
		y = g.getYear();

		dow = g.getDayOfWeek();
		ml = g.getMonthLength();

		for(i = 0; i < 6; i ++)
		{
			for(j = 0; j < 7; j ++)
			{
				td = tbody.rows[i].cells[j];
				n = 7 * i + j + 1 - dow;
				if( (n <= 0) || (n > ml) )
					td.innerHTML = "&nbsp;";
				else
					td.innerHTML = '<A style="text-decoration: none; color: black;" href="javascript:DatePicker.invoke(\'' + this.id + '\', \'chooseDate\', '+ n + ')" onmouseover="DatePicker.invoke(\'' + this.id + '\', \'hover\', ' + n + '); return true;">' + n + '</A>';
			}
		}


		this.spanCurrentMonth.innerHTML = g.MonthNameShort() + " ";
		this.spanCurrentYear.innerHTML = '<A style="text-decoration: none; color: gray;" href="javascript:DatePicker.invoke(\'' + this.id + '\', \'editYear\')">' + g.getYear() + '</A>';

		if( bSetFocusYear && (this.spanCurrentYear.childNodes.length > 1) )
			this.spanCurrentYear.childNodes[0].focus();

	}

}



GDatePicker.prototype = new DatePicker;
function GDatePicker()
{
	this.date = new GDate();
}

HDatePicker.prototype = new DatePicker;
function HDatePicker()
{
	this.date = new HDate();
}
