// requires calendar.css
// requires tools.js

tools = window["tools"] || {
	getObjectCoords : function( htmlEl){
	   var aY = htmlEl.offsetTop, aX = htmlEl.offsetLeft;
	   while((htmlEl = htmlEl.offsetParent)){
	      aY += htmlEl.offsetTop;
	      aX += htmlEl.offsetLeft;
	   }
	   return [aX, aY];
	},

	trim : function( str){
		return str.replace(/(^\s*) | \s*$/g, "");
	}
};

Calendar = function(){
	var _this = this;
	var selectedDate;
	var calMonths;
	var curDate; // current date pointing to the first day of the currently selected month and year
	var selectedCell;

	this.show = function(){
		this.holder.style.display = "block";
	}

	this.hide = function(){
		this.holder.style.display = "none";
	}

	this.close = function(){
		this.holder.parentNode.removeChild(_this.holder);
	}

	this.moveTo = function(x,y){
		this.holder.style.left = x;
		this.holder.style.top = y;
	}

	this.init = function(initVal, callback){
		this.callback = callback;
		this.initValue = initVal;
		setCalendar( getDate(this.initValue));
	}

	function Months(year){
		this.name 	= ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
		var febDay 	= (year % 4 == 0) ? 29 : 28;
		this.index 	= [31, febDay, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
	}

	function setLayout(){
		calMonths = new Months(Calendar.getYear2(curDate));
		_this.headerTable.rows[0].cells[2].innerHTML = calMonths.name[curDate.getMonth()] + " " + Calendar.getYear2(curDate);
		var c = 1;
		var cell;
		for(var i=0; i<7; i++){
			_this.tableHolder.rows[1].cells[i].className = "day_head";
		}
		for(var i=2; i < 8; i++){
			for(var j=0; j < 7; j++){
				cell = _this.tableHolder.rows[i].cells[j]
				cell.className = "day_normal";
				if(i == 2 && j < curDate.getDay() || c > calMonths.index[curDate.getMonth()]){
					cell.innerHTML 	= "";
					cell.onmouseover 	= null;
					cell.onmouseout 	= null;
					cell.onmousedown 	= null;
					cell.onclick 		= null;
					cell.style.cursor = "default";
				}
				else if(selectedDate && c == selectedDate.getDate(_this.initValue) && curDate.getMonth() == selectedDate.getMonth() && curDate.getYear() == selectedDate.getYear()){
					cell.innerHTML 	= c++;
					setupAsSelected(cell);
					selectedCell = cell;
				}
				else{
					cell.innerHTML 	= c++;
					setupAsNormal(cell);
				}
			}
		}
	}

	function setupAsSelected( cell){
		cell.onmouseover 	= function(){_this.tableHolder.rows[1].cells[this.cellIndex].className='day_head_on'}
		cell.onmouseout 	= function(){_this.tableHolder.rows[1].cells[this.cellIndex].className='day_head'}
		cell.onmousedown 	= null;
		cell.onclick 		= function(){selectDate(this)};
		cell.style.cursor = "pointer";
		cell.className 	= "day_down";
	}

	function setupAsNormal(cell){
		cell.onmouseover 	= function(){this.className = 'day_up'; _this.tableHolder.rows[1].cells[this.cellIndex].className='day_head_on'}
		cell.onmouseout 	= function(){this.className = 'day_normal'; _this.tableHolder.rows[1].cells[this.cellIndex].className='day_head'}
		cell.onmousedown 	= function(){this.className = 'day_down';};
		cell.onclick 		= function(){selectDate(this)};
		cell.style.cursor = "pointer";
		cell.className 	= "day_normal";
	}

	function selectDate( cell){
		_this.callback(
			(curDate.getMonth() + 1) + Calendar.DELIMITER + cell.innerHTML + Calendar.DELIMITER + Calendar.getYear2(curDate),
			(new Date(Calendar.getYear2(curDate), curDate.getMonth(), parseInt(cell.innerHTML))).getTime()
		);
	}

	function incCurDate(isY, isM){
		if(isY){
			curDate = new Date(Calendar.getYear2(curDate) + 1, curDate.getMonth(), 1);
		}
		if(isM){
			if(curDate.getMonth() == 11)
				curDate = new Date(Calendar.getYear2(curDate) + 1, 0, 1);
			else
				curDate = new Date(Calendar.getYear2(curDate), curDate.getMonth() + 1, 1);
		}
		setLayout();
	}

	function decCurDate(isY, isM){
		if(isY){
			if(Calendar.getYear2(curDate) < 1901)
				return;
			curDate = new Date(Calendar.getYear2(curDate) - 1, curDate.getMonth(), 1);
		}
		if(isM){
			if(curDate.getMonth() == 0){
				if(Calendar.getYear2(curDate) > 1900)
					curDate = new Date(Calendar.getYear2(curDate) - 1, 11, 1);
				else
					return;
			}
			else{
				curDate = new Date(Calendar.getYear2(curDate), curDate.getMonth() - 1, 1);
			}
		}
		setLayout();
	}

	function setCalendar(date){
		if(!date){
			curDate = new Date( Calendar.getYear2(new Date()), (new Date()).getMonth(), 1);
			selectedDate = null;
		}
		else{
			curDate = new Date(Calendar.getYear2(date), date.getMonth(), 1);
			selectedDate = date;
		}
		setLayout();
	}

	function getDate( str){
		var index1 = 0, index2 = 0;
		var t;
		var delimiter = "";
		var mm = "", dd = "", yy = "";

		tools.trim(str);
		if(str == "")
			return null;

		if(str.indexOf("/") != -1)
			delimiter = "/";
		else if(str.indexOf("-") != -1)
			delimiter = "-";
		else
			return null;

		if((index1 = str.indexOf(delimiter)) == -1)
			return null;
		else if((index2 = str.indexOf(delimiter, index1 + 1)) == -1)
			return null;

		mm = str.substring(0, index1);
		dd = str.substring(index1 + 1, index2);
		yy = str.substring(index2 + 1, str.length);

		if(mm > 12 || mm < 1)
			return null;
		if(dd > 32 || dd < 1)
			return null;
		if(yy < 1900 && yy > 2100)
			return null;

		return new Date(yy, mm - 1, dd);
	}

	var template = '\
		<table style="cursor:default;-moz-user-select:none;" width=175 onselectstart="return false;" cellspacing=0 cellpadding=0>\
			<tr>\
				<td colspan=7>\
					<table width=175>\
						<tr>\
							<td class=day_normal align=center valign=middle style="cursor:pointer" onmouseover="this.className=\'day_up\'" onmouseout="this.className=\'day_normal\'" onmousedown="this.className=\'day_down\'" onmouseup="this.className=\'day_up\'">&lt;&lt;</td>\
							<td class=day_normal align=center valign=middle style="cursor:pointer" onmouseover="this.className=\'day_up\'" onmouseout="this.className=\'day_normal\'" onmousedown="this.className=\'day_down\'" onmouseup="this.className=\'day_up\'">&lt;</td>\
							<td class=cal_head valign=middle width=100%></td>\
							<td align=center  valign=middle class=day_normal style="cursor:pointer" onmouseover="this.className=\'day_up\'" onmouseout="this.className=\'day_normal\'" onmousedown="this.className=\'day_down\'" onmouseup="this.className=\'day_up\'">&gt;</td>\
							<td align=center  valign=middle class=day_normal style="cursor:pointer" onmouseover="this.className=\'day_up\'" onmouseout="this.className=\'day_normal\'" onmousedown="this.className=\'day_down\'" onmouseup="this.className=\'day_up\'">&gt;&gt;</td>\
						</tr>\
					</table>\
				</td>\
			</tr>\
			<tr><td height=30 class=day_head>S</td><td class=day_head>M</td><td class=day_head>T</td><td class=day_head>W</td><td class=day_head>T</td><td class=day_head>F</td><td class=day_head>S</td></tr>\
			<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>\
			<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>\
			<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>\
			<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>\
			<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>\
			<tr><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>\
		</table>';

	this.setup = function(){
		if(!this.holder){
			this.holder = document.createElement("DIV");
			this.holder.className = "calendarBody";
			this.holder.style.display = "none";
			document.body.appendChild(this.holder);
			this.holder.innerHTML = template;

			this.tableHolder = this.holder.getElementsByTagName("table")[0]
			this.headerTable = this.holder.getElementsByTagName("table")[1];

			this.headerTable.rows[0].cells[0].onclick = function(){decCurDate(true, false)};
			this.headerTable.rows[0].cells[1].onclick = function(){decCurDate(false, true)};
			this.headerTable.rows[0].cells[3].onclick = function(){incCurDate(false, true)};
			this.headerTable.rows[0].cells[4].onclick = function(){incCurDate(true, false)};
		}
	}
}

Calendar.DELIMITER = "/";
Calendar.getYear2 = function(date){
	if(document.all && !window.opera) // if IE
		return date.getYear();
	else
		return date.getYear() + 1900;
}

ButtonCalendar = function(){
	ButtonCalendar.items.push(this);
	var _this = this;
	this.msDate = 0; // current date in mils
	this.but = null;
	this.mirrorField = null;
	this.calendar = new Calendar();
	this.calendar.setup();
	this.onchange = function(){}

	this.bindButton = function(butID){
		if(typeof butID == "string")
			this.but = document.getElementById(butID);
		else
			this.but = butID;

		this.but.state = "off";
		if(this.mirrorField && this.mirrorField.value != ""){
			this.but.value = this.mirrorField.value;
		}

		this.but.onmousedown = function(){
			//hide all other calendar instances
			for(var i=0; i < ButtonCalendar.items.length; i++){
				if(ButtonCalendar.items[i] != _this){
					ButtonCalendar.items[i].hide();
				}
			}

			if(this.state == "off"){
				_this.calendar.init( 
					this.value, 
					function( val, val_ms){ // callback function
						if(_this.mirrorField){
							_this.mirrorField.value = val;
						}
						_this.but.value = val;
						_this.hide();
						_this.msDate = val_ms;
						_this.onchange();
					}
				);
			}
		}
		this.but.onclick = function(){
			if(this.state == "on")
				_this.hide();
			else
				_this.show();
		}
		return this;
	}

	this.hide = function(){
		this.but.state = "off";
		this.but.className = 'buttonOff';
		this.calendar.hide();
		return this;
	}

	this.show = function(){
		this.but.state = "on";
		this.but.className = 'buttonOn';
		var coords = tools.getObjectCoords(this.but);
		this.calendar.moveTo(coords[0], coords[1] + this.but.offsetHeight);
		this.calendar.show();
		return this;
	}
	
	this.bindMirrorField = function(fieldId){
		if(typeof fieldId == "string")
			this.mirrorField = document.getElementById(fieldId);
		else
			this.mirrorField = fieldId;
		if(this.but && this.mirrorField.value != ""){
			this.but.value = this.mirrorField.value;
		}
		return this;
	}
}

ButtonCalendar.items = [];

