/*****************************************************
 * Copyright (c) 2003-2009 Chris Hobden              *
 * http://code.google.com/p/isislib/                 *
 * isislib is distributed under the MIT License      *
 * see http://code.google.com/p/isislib/wiki/LICENSE *
 *****************************************************/
/**
 * isisDatePicker creates a mini calander used to select a date.
 * @class isisDatePicker creates a mini calander used to select a date.
 * @example
 * <input type="text" onclick="isis.datePicker(this, 'UK', true)">
 * @author Chris Hobden 
 * @see http://code.google.com/p/isislib/
 * @base isis
 * @version 1.0
 * @constructor
 * @param {String|Object} field either the id of the input field related to this picker or the Object its self.
 * @param {String} date_format The date format to use, either 'US' or 'UK'.
 * @default 'UK'
 * @param {Boolean} inc_time Include time in the date picker.
 * @default false
 */
function isisDatePicker(field, date_format, inc_time){
	datepicker=this;
	this.date_format=date_format?date_format:'UK';

	this.inc_time=typeof inc_time!=undefined?inc_time:false;
	this.days = new Array(7);
	this.days[0] = "Sun";
	this.days[1] = "Mon";
	this.days[2] = "Tue";
	this.days[3] = "Wed";
	this.days[4] = "Thu";
	this.days[5] = "Fri";
	this.days[6] = "Sat";

	this.months = new Array(12);
	this.months[0]  = "January";
	this.months[1]  = "February";
	this.months[2]  = "March";
	this.months[3]  = "April";
	this.months[4]  = "May";
	this.months[5]  = "June";
	this.months[6]  = "July";
	this.months[7]  = "August";
	this.months[8]  = "September";
	this.months[9]  = "October";
	this.months[10] = "November";
	this.months[11] = "December";

	this.field=field;
	if(typeof field == 'String')this.field=document.getElementById(field);
	if(typeof field!='object')throw "invalid parent";
	
	//read the value of the related field set the current date.
	this.setDate(datepicker.field.value, this.date_format);
	//get the z,y position of the field.
	var pos=isis.getPosition(this.field);

	//create a screen cover and show it
	this.cover = new this.screenCover();
	this.cover.show();

	this.holder=document.createElement('div');
	document.body.appendChild(this.holder);
	this.holder.style.position='absolute';

	this.holder.style.top=pos.y+this.field.offsetHeight+"px";
	this.holder.style.left=pos.x+"px";
	this.holder.style.zIndex=101;
	this.setBaseStyle(this.holder);
	this.holder.style.borderColor='ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight';
	this.holder.style.borderStyle='solid';
	maintable=document.createElement('table');

	maintable.appendChild(document.createElement("tbody"));
	this.holder.appendChild(maintable);
	maintable.width=this.holder.style.width;
	maintable.height=this.holder.style.height;
	
	
	close_button=document.createElement('input');
	close_button.type='button';
	close_button.value='x';
	this.setButtonStyles(close_button);
	this.addEventHandler(close_button, 'click', function(e){
		datepicker.close();
	});
	
	tr=maintable.insertRow(-1);
	td=tr.insertCell(-1);
	td.style.width="16px";
	td.appendChild(close_button);
	
	this.title_cell=tr.insertCell(-1);
	this.title_cell.style.color='CaptionText';
	this.title_cell.style.fontFamily='MS Sans Serif';
	this.title_cell.style.fontSize='8pt';
	this.title_cell.align='center';
	
	ok_button=document.createElement('input');
	ok_button.type='button';
	ok_button.value='ok';
	this.setButtonStyles(ok_button);
	td=tr.insertCell(-1);
	td.appendChild(ok_button);

	this.addEventHandler(ok_button, 'click', function(e){
		datepicker.field.value=datepicker.getCurrentDate();
		datepicker.close();		
	});
	
	
	tr=maintable.insertRow(-1);

	prev_button=document.createElement('input');
	prev_button.type='button';
	prev_button.value='<';
	td=tr.insertCell(-1);
	td.style.width="16px";
	this.setButtonStyles(prev_button);
	td.appendChild(prev_button);

	this.addEventHandler(prev_button, 'click', function(e){
		datepicker.addNMonths(-1);
		month_day_cell.replaceChild(document.createTextNode(datepicker.months[datepicker.date.getMonth()]+" "+datepicker.date.getFullYear()), month_day_cell.firstChild);
		datepicker.refresh();
	});

	month_day_cell=tr.insertCell(-1);
	month_day_cell.align='center';
	month_day_cell.appendChild(document.createTextNode(datepicker.months[datepicker.date.getMonth()]+" "+datepicker.date.getFullYear()));
	
	next_button=document.createElement('input');
	next_button.type='button';
	next_button.value='>';
	td=tr.insertCell(-1);
	td.style.width="16px";
	this.setButtonStyles(next_button);
	td.appendChild(next_button);

	this.addEventHandler(next_button, 'click', function(e){
		datepicker.addNMonths(1);
		month_day_cell.replaceChild(document.createTextNode(datepicker.months[datepicker.date.getMonth()]+" "+datepicker.date.getFullYear()), month_day_cell.firstChild);
		datepicker.refresh();
	});


	tr=maintable.insertRow(-1);

	this.calander_cell=tr.insertCell(-1);
	this.calander_cell.colSpan=3;
	this.calander_cell.appendChild(datepicker.getTable(datepicker.date.getMonth()+1, datepicker.date.getFullYear()));

	if(this.inc_time){
		tr=maintable.insertRow(-1);
		time_cell=tr.insertCell(-1);
		time_cell.colSpan=3;
		time_cell.appendChild(datepicker.getTimeTable());
	}
	this.addEventHandler(document, 'keydown', datepicker.keyHandler);
	this.addEventHandler(this.holder, 'keydown', datepicker.keyHandler);
	this.addEventHandler(this.cover.holder, 'click', function(e){datepicker.close();});
	this.updateTitle();
}
//inherit the isis class
isisDatePicker.prototype=isis;
/**
* refreshes the calander with the current values
*/
isisDatePicker.prototype.refresh=function(){
	this.calander_cell.replaceChild(this.getTable(datepicker.date.getMonth()+1, this.date.getFullYear()), this.calander_cell.firstChild);
};
/**
* Closes the calander and removes the screen cover.
*/
isisDatePicker.prototype.close=function(){
	if(this.holder.parentNode)this.holder.parentNode.removeChild(this.holder);
	this.cover.distroy();
};
/**
* Updates the title to the current selected date.
*/
isisDatePicker.prototype.updateTitle=function(){
	this.title_cell.innerHTML=this.getCurrentDate();
};
/**
* Updates the title to the current selected date.
* @return String the current date
*/
isisDatePicker.prototype.getCurrentDate=function(){
	var newdate=''
	if(this.date_format=='UK'){
		newdate=this.padNumber(this.newdate.getDate())+'/'+this.padNumber((this.newdate.getMonth()+1))+'/'+this.newdate.getFullYear();
	}else{
		newdate=this.padNumber((this.newdate.getMonth()+1))+'/'+this.padNumber(this.newdate.getDate())+'/'+this.newdate.getFullYear();
	}
	if(this.inc_time){
		newdate+=' '+this.padNumber(this.newdate.getHours())+':'+this.padNumber(this.newdate.getMinutes())+':'+this.padNumber(this.newdate.getSeconds());
	}
	return newdate;
};
/**
* sets the cell style depending on its status.
* @param {Object} cell to change
* @param {String} the status of tje cell
*/
isisDatePicker.prototype.setCellStyle=function(cell, status){
	this.setBaseStyle(cell);
	cell.style.opacity='1.00';
	cell.style.cursor='pointer';
	switch(status){
		case "over":
		cell.style.borderColor='ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight';
		cell.style.borderStyle='outset';		
		break;
		case "pressed":
		cell.style.borderColor='inset';
		cell.style.borderStyle='ButtonHighlight ButtonShadow ButtonShadow ButtonHighlight';		
		break;
		default:
		cell.style.borderColor='ButtonFace';
		cell.style.borderStyle='solid';	
		break;
	}
};
/**
* Sets the base style for the all objects.
* @param {Object} obj to change
*/
isisDatePicker.prototype.setBaseStyle=function(obj){
	obj.style.borderWidth='1px';
	obj.style.fontFamily='MS Sans Serif';
	obj.style.fontSize='8pt';
	obj.style.backgroundColor='ButtonFace';
	obj.style.color='ButtonText';
};
/**
 * Gets the number of days in a month given the month and year
 * @param {Number} month the month to check
 * @param {Number} year the year to check
 * @return {Number} number of days in the requested month
 */
isisDatePicker.prototype.daysInMonth=function(month, year){
	with (new Date(year, month, 1, 12)) {
		setDate(0);
		return getDate();
	}
};
/**
* Sets the button base style.
* @param {Object} btn button to change
*/
isisDatePicker.prototype.setButtonStyles=function(btn){
	this.setBaseStyle(btn);
	btn.style.borderColor='ButtonFace';
	btn.style.borderStyle='solid';	
	this.addEventHandler(btn, "mouseover", function(e){datepicker.setCellStyle(btn, "over");});
	this.addEventHandler(btn, "mouseout", function(e){datepicker.setCellStyle(btn);});
	this.addEventHandler(btn, "mousedown", function(e){datepicker.setCellStyle(btn, "pressed");});
	this.addEventHandler(btn, "mouseup", function(e){datepicker.setCellStyle(btn);});	
	
};
/**
* Creates a new button.
* @param {Number} day day of this button.
* @param {Number} month month of this button.
* @param {Number} year year of this button.
* @return {Object} retuns the table cell formated as a button.
*/
isisDatePicker.prototype.createButton=function(day, month, year){
	datepicker=this;
	var td=document.createElement("td");
	td.align='center';
	var tid='TT'+Math.floor(Math.random()*99999);
	td.id=tid;
	var btnDiv=document.createElement("div");


	if(this.newdate.getDate()==day&&(this.newdate.getMonth()+1)==month&&this.newdate.getFullYear()==year){
		btnDiv.innerHTML='<b>'+ i +'</b>';
	}else{
		btnDiv.appendChild(document.createTextNode(i));
	}
	this.addEventHandler(btnDiv, "click", function(e){
		datepicker.newdate.setMonth(datepicker.date.getMonth());
		datepicker.newdate.setFullYear(datepicker.date.getFullYear());
		datepicker.newdate.setDate(btnDiv.innerHTML.replace(/<\S[^>]*>/g, ''));
		datepicker.updateTitle();
		datepicker.refresh();
	});
	this.setCellStyle(btnDiv);
	this.setButtonStyles(btnDiv);
	td.appendChild(btnDiv);
	return td;
};
/**
* Pads numbers less than 9 with an extra 0.
* @param {Number} number number to pad.
* @return {Number} number padded if needed.
*/
isisDatePicker.prototype.padNumber=function(number){
     var str = '' + number;
     while (str.length < 2){
     	str = '0' + str;
     }
     return str;
};
/**
* returns the time table with hours mins ans sec cells.
* @return {Object} table.
*/
isisDatePicker.prototype.getTimeTable=function(){
	datepicker=this;
	var table=document.createElement('table');
	table.style.width='100%';
	table.appendChild(document.createElement("tbody"));
	var tr=table.insertRow(-1);
	td=tr.insertCell(-1);
	td.align='right';
	td.innerHTML='Time:';

	func=function(e, obj, max){
		if(e.wheelDelta){
			delta = e.wheelDelta/120;
		}else if(e.detail){
			delta = -e.detail/3;
		}
		if(delta>0){
			obj.value=datepicker.padNumber(parseInt(obj.value)+1);
			if(parseInt(obj.value)>max)obj.value='00';
		}else{
			obj.value=datepicker.padNumber(parseInt(obj.value)-1);
			if(parseInt(obj.value)<0)obj.value=max;
		}
	};
	
	var hour_box=document.createElement('input');
	hour_box.type='text';
	hour_box.value=this.padNumber(this.newdate.getHours());
	hour_box.size=2;
	hour_box.style.width="16px";
	hour_box.style.borderWidth="1px";
	hour_box.style.borderStyle="solid";
	hour_box.style.borderColor="#000000";
	td=tr.insertCell(-1);
	td.style.width="16px";
	td.appendChild(hour_box);

	this.addEventHandler(hour_box, 'DOMMouseScroll', function(e){func(e, hour_box, 23);datepicker.newdate.setHours(parseInt(hour_box.value));datepicker.updateTitle();});
	this.addEventHandler(hour_box, 'mousewheel', function(e){func(e, hour_box, 23);datepicker.newdate.setHours(parseInt(hour_box.value));datepicker.updateTitle();});
	this.addEventHandler(hour_box, 'blur', function(e){hour_box.value=datepicker.padNumber(parseInt(hour_box.value));datepicker.updateTitle();});

	td=tr.insertCell(-1);
	td.style.width="4px";
	td.innerHTML=':';

	var min_box=document.createElement('input');
	min_box.type='text';
	min_box.value=this.padNumber(this.newdate.getMinutes());
	min_box.size=2;
	min_box.style.width="16px";
	min_box.style.borderWidth="1px";
	min_box.style.borderStyle="solid";
	min_box.style.borderColor="#000000";
	min_box.style.width="16px";
	td=tr.insertCell(-1);
	td.style.width="16px";
	td.appendChild(min_box);

	this.addEventHandler(min_box, 'DOMMouseScroll', function(e){func(e, min_box, 59);datepicker.newdate.setMinutes(parseInt(min_box.value));datepicker.updateTitle();});
	this.addEventHandler(min_box, 'mousewheel', function(e){func(e, min_box, 59);datepicker.newdate.setMinutes(parseInt(min_box.value));datepicker.updateTitle();});
	this.addEventHandler(min_box, 'blur', function(e){min_box.value=datepicker.padNumber(parseInt(min_box.value));datepicker.updateTitle();});

	td=tr.insertCell(-1);
	td.style.width="4px";
	td.innerHTML=':';

	var sec_box=document.createElement('input');
	sec_box.type='text';
	sec_box.value=this.padNumber(this.newdate.getSeconds());
	sec_box.size=2;
	sec_box.style.width="16px";
	sec_box.style.borderWidth="1px";
	sec_box.style.borderStyle="solid";
	sec_box.style.borderColor="#000000";
	sec_box.style.width="16px";
	td=tr.insertCell(-1);
	td.style.width="16px";
	td.appendChild(sec_box);

	this.addEventHandler(sec_box, 'DOMMouseScroll', function(e){func(e, sec_box, 59);datepicker.newdate.setSeconds(parseInt(sec_box.value));datepicker.updateTitle();});
	this.addEventHandler(sec_box, 'mousewheel', function(e){func(e, sec_box, 59);datepicker.newdate.setSeconds(parseInt(sec_box.value));datepicker.updateTitle();});
	this.addEventHandler(sec_box, 'blur', function(e){sec_box.value=datepicker.padNumber(parseInt(sec_box.value));datepicker.updateTitle();});

	return table;
};
/**
* returns a table for the given month and year.
* @param {Number} month
* @param {Number} year
* @return {Object} table.
*/
isisDatePicker.prototype.getTable=function(month, year){
	datepicker=this;
	total_days=this.daysInMonth(month, year);

	var table=document.createElement('table');
	table.style.width='100%';
	table.appendChild(document.createElement("tbody"));
	var tr=table.insertRow(-1);

	for(i=0;i<this.days.length;i++){
		var td=tr.insertCell(-1);
		td.appendChild(document.createTextNode(this.days[i]));
		this.setCellStyle(td);
	}
	tdate = new Date(year, month-1, 1, 12);
	start=tdate.getDay();
	var tr=table.insertRow(-1);
	for(i=0;i<start;i++){
		tr.insertCell(-1);
	}
	for(i=1;i<=total_days;i++){
		if(start % 7 == 0){
			var tr=table.insertRow(-1);
		}
		start++;
		tr.appendChild(this.createButton(i,month, year));
	}
	return table;
};
/**
* Adds n months to the current date.
* @param {Number} months
*/
isisDatePicker.prototype.addNMonths=function(months){
	this.date.setMonth(this.date.getMonth()+months);
};
/**
* Sets the current date from a string.
* @param {String} sdate date string in the MM/DD/YYYY or DD/MM/YYYY format
* @param {String} date_format format the date is in 'UK' or 'US'
*/
isisDatePicker.prototype.setDate=function(sdate, date_format){
	if(sdate.length>0){
		if(date_format=='UK'){
			format='$3/$1/$5';
		}else{
			format='$1/$3/$5';
		}
		sdate=sdate.replace(/(\d+)(\/|-|.)(\d+)(\/|-|.)(\d+)/, format);
		this.date = new Date(sdate);
		this.newdate = new Date(sdate);

		if(isNaN(this.date))this.date = new Date();
	}else{
		this.date = new Date();
		this.newdate = new Date();
	}
};
