/*
Requires prototype 1.6
date parser take format dd/mm/yyyy HH:mm this should be modified or extended

usage:
you can either provide a config object or use default

e.g.:
var config = {
	container:null,
	allowdatenull:true,
	allowtime:false};
	
var alcassoftDatePicker = new AlcassoftDatePicker( $('date'),configs );

OR

var alcassoftDatePicker = new AlcassoftDatePicker( $('date') );
to use default config
*/

AlcassoftDatePicker=function(dateelement,configs)
{
	//global obj vars
	this.date = new Date();
	this.months = ["JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"];
	this.dateelement = dateelement;
	
	
	this.epoch = new Date();
	this.epoch.setMilliseconds(0);
	this.epoch.setMinutes(0);
	this.epoch.setHours(0);
	this.epoch.setDate(0);
	this.epoch.setMonth(0);
	//this.epoch.setYear(0);
	this.epoch.setYear(new Date().getFullYear());
	
	this.firstrun = true;
	
	
	//alert(this.epoch);
	
	//day
	this.dayTextbox;
	//month
	this.monthSelectBox;
	//year
	this.yearTextbox;
	//hour
	this.hourSelectbox;
	//minute
	this.minuteSelectbox;
	//resetbutton
	this.resetButton;
	
	//default params
	this.container = null;//optionally if the date object is in a container
	this.allowdatenull=true;
	this.allowtime=true;
	this.showresetbutton=true;
	this.removetimeformat=false;
	
	for(var config in configs)
	{
		this[config] = configs[config];
	}
	
	if(dateelement)
	{
		//if dateelement has a value use it
		//if allows null then set to null
		//else use now()
		if(dateelement.value.trim()!="")
		{
			this.date = this.stringToDate(dateelement.value);
			this.firstrun = false;
		}
		else if(this.allowdatenull){
			//then set date object to null EXCEPT MONTH which is JAN
			this.date.setTime( this.epoch.getTime() );//close clone
			//this.date = this.epoch;
		}
		
		//we may need more fine grained control but for now we always init
		this.init();
	}
}

//gathers nessesary info from DOM
AlcassoftDatePicker.prototype.init=function()
{
	//hide dateelement form field
	Element.setStyle(this.dateelement,{display:'none'});
	
	//put the newly created date picker into the same position as the dateelement
	var datePicker = this.createDatePicker(this.months,this.allowtime,this.showresetbutton);
	
	//check if there is a target to render the date picker in,
	var targetElement;
	if(this.container){
		targetElement = $(this.container);
	}
	else{//else we just attach it in the targets ancestor
		targetElement = Element.ancestors(this.dateelement)[0];
	}
	
	targetElement.appendChild(datePicker);
	
	//update the date picker to the backing obj date
	this.refreshDatePicker();
	this.refreshDateElement();
}

//renders the data picker object based on config e.g. has time/time
AlcassoftDatePicker.prototype.createDatePicker=function(months,allowtime,showresetbutton)
{
	//returns a din with date pickers with attached events
	var dateContainerDiv = new Element('div');
	
	var dayTextbox = new Element('input', { 'type': 'text','size':'2','maxlength':'2','name':this.dateelement.name+'_day'});
	var monthSelectBox = new Element('select',{'name':this.dateelement.name+'_month'});
	var hourSelectBox = new Element('select',{'name':this.dateelement.name+'_hour'});
	var minuteSelectBox = new Element('select',{'name':this.dateelement.name+'_min'});
	var resetButton = new Element('input',{ 'type':'button','value':'Clear' });
	
	//months
	
	var len=months.length;
	for(var i=0;i<len;i++)
	{
		var monthSelectOption = new Element('option', {'value':i}).update(months[i]);
		monthSelectBox.appendChild(monthSelectOption);
	}
	
	
	//hours
	for(var i=0;i<24;i++)
	{
		var hourSelectOption = new Element('option', {'value':i}).update(this.pad('0',i.toString(),2,true));
		hourSelectBox.appendChild(hourSelectOption);
	}
	
	//minutes
	for(var i=0;i<60;i++)
	{
		var minuteSelectOption = new Element('option', {'value':i}).update(this.pad('0',i.toString(),2,true));
		minuteSelectBox.appendChild(minuteSelectOption);
	}
	
	var yearTextbox = new Element('input', { 'type': 'text','size':'4','maxlength':'4','name':this.dateelement.name+'_year'});
	
	dateContainerDiv.appendChild(dayTextbox);
	dateContainerDiv.appendChild(monthSelectBox);
	dateContainerDiv.appendChild(yearTextbox);
	if(allowtime)
	{
		dateContainerDiv.appendChild(hourSelectBox);
		dateContainerDiv.appendChild(minuteSelectBox);
	}
	
	if(showresetbutton)
	{
		dateContainerDiv.appendChild(resetButton);
	}
	
	//update global reference
	this.dayTextbox = dayTextbox;
	this.monthSelectBox = monthSelectBox;
	this.yearTextbox = yearTextbox;
	this.hourSelectBox = hourSelectBox;
	this.minuteSelectBox = minuteSelectBox;
	this.resetButton = resetButton;
	
	
	//Events
	var jonsobj = new Object();
	jonsobj['mythis'] = this;
	
	//functions
	var dayTextboxBlur = function(e,jonsobj){
		jonsobj['mythis'].firstrun = false;
		
		var dayField = Event.element(e);
		
		if(dayField.value.trim()=="")
		{
			jonsobj['mythis'].reset();
			return false;
		}
		
		jonsobj['mythis'].date.setDate( dayField.value.getNumeric() );
		
		//updates date picker
		jonsobj['mythis'].refreshDatePicker();
		jonsobj['mythis'].refreshDateElement();
	}
	
	var monthSelectBoxChange = function(e,jonsobj){
		jonsobj['mythis'].firstrun = false;
		
		var monthField = Event.element(e);
		jonsobj['mythis'].date.setMonth( monthField.value.getNumeric());
		//updates date picker
		jonsobj['mythis'].refreshDatePicker();
		jonsobj['mythis'].refreshDateElement();
	}
	
	var yearTextboxBlur = function(e,jonsobj){
		jonsobj['mythis'].firstrun = false;
		
		var yearField = Event.element(e);
		if(yearField.value.trim()=="")
		{
			jonsobj['mythis'].reset();
			return false;
		}
		
		jonsobj['mythis'].date.setFullYear( yearField.value.getNumeric() );
		//updates date picker
		jonsobj['mythis'].refreshDatePicker();
		jonsobj['mythis'].refreshDateElement();
	}
	
	var hourSelectBoxChange = function(e,jonsobj){
		jonsobj['mythis'].firstrun = false;
		
		var hourField = Event.element(e);
		jonsobj['mythis'].date.setHours( hourField.value.getNumeric() );
		//updates date picker
		jonsobj['mythis'].refreshDatePicker();
		jonsobj['mythis'].refreshDateElement();
	}
	
	var minuteSelectBoxChange = function(e,jonsobj){
		jonsobj['mythis'].firstrun = false;
		
		var minuteField = Event.element(e);
		jonsobj['mythis'].date.setMinutes( minuteField.value.getNumeric() );
		//updates date picker
		jonsobj['mythis'].refreshDatePicker();
		jonsobj['mythis'].refreshDateElement();
	}
	
	var resetButtonClick = function(e,jonsobj)
	{
		jonsobj['mythis'].reset();
	}
		
	//day
	Event.observe(dayTextbox,'blur',function(e){
		dayTextboxBlur(e,jonsobj)}
	);
	//month
	Event.observe(monthSelectBox,'change',function(e){
		monthSelectBoxChange(e,jonsobj)}
	);
	//year
	Event.observe(yearTextbox,'blur',function(e){
		yearTextboxBlur(e,jonsobj)}
	);
	//hour
	Event.observe(hourSelectBox,'blur',function(e){
		hourSelectBoxChange(e,jonsobj)}
	);
	//minute
	Event.observe(minuteSelectBox,'blur',function(e){
		minuteSelectBoxChange(e,jonsobj)}
	);
	//reset button
	Event.observe(resetButton,'click',function(e){
		resetButtonClick(e,jonsobj)}
	);
	
	return dateContainerDiv;
}

AlcassoftDatePicker.prototype.reset=function()
{
	this.firstrun = true;
	Element.writeAttribute(this.dateelement,'value','');//updates the element 'attribute'
	this.dateelement.value='';//updates the element 'value'
	this.date.setTime( this.epoch.getTime() );
	//due to epoch time the display and dateelement should be blank
	this.refreshDatePicker();
	this.refreshDateElement();
}

AlcassoftDatePicker.prototype.getDate=function()
{
	return this.date;
}

AlcassoftDatePicker.prototype.setDate=function(date)
{
	this.date = date;
}

//refreshes the date picker based on internal date object
AlcassoftDatePicker.prototype.refreshDatePicker=function()
{
	if(this.firstrun){
		this.dayTextbox.value = '';
		this.monthSelectBox.selectedIndex = 0;
		this.yearTextbox.value = '';
		
		if(this.allowtime)
		{
			this.hourSelectBox.selectedIndex = 0;
			this.minuteSelectBox.selectedIndex = 0;
		}
	}
	else{
		this.dayTextbox.value = this.pad( '0',this.date.getDate().toString(),2, true );
		this.monthSelectBox.selectedIndex = this.date.getMonth();
		this.yearTextbox.value = this.pad( '0',this.date.getFullYear().toString(),4, true );
		
		if(this.allowtime)
		{
			this.hourSelectBox.value = this.date.getHours();
			this.minuteSelectBox.value = this.date.getMinutes();
		}
	}
	/*
	if(this.date.getTime()==this.epoch.getTime())
	{
		alert('epoch1');
		//epoch
		this.dayTextbox.value = '';
		this.monthSelectBox.selectedIndex = 0;
		this.yearTextbox.value = '';
		
		if(this.allowtime)
		{
			this.hourSelectBox.selectedIndex = 0;
			this.minuteSelectBox.selectedIndex = 0;
		}
		
	}
	else{
		alert('epoch2');
		this.dayTextbox.value = this.pad( '0',this.date.getDate().toString(),2, true );
		this.monthSelectBox.selectedIndex = this.date.getMonth();
		this.yearTextbox.value = this.pad( '0',this.date.getFullYear().toString(),4, true );
		
		if(this.allowtime)
		{
			this.hourSelectBox.value = this.date.getHours();
			this.minuteSelectBox.value = this.date.getMinutes();
		}
	}
	*/
}

//converts a string to a date object format of string dd/mm/yyyy HH:mm
AlcassoftDatePicker.prototype.stringToDate=function(datestring)
{
	//alert(datestring)
	var resultDate = new Date();
	
	if(datestring.trim()==""){
		return new Date();
	}
	
	//alert(datestring);
	//TODO: be smart and have different date configs passes as param
	//currently has dd/mm/yyyy HH:mm
	try{
		var month = datestring.split('/')[1].getNumeric()-1;
		var day = datestring.split('/')[0].getNumeric();
		var year = datestring.split('/')[2].getNumeric();
		
		//alert(datestring.split('/')[1])
		//alert(day);
		//alert(month);
		//alert(year);
		
		
		var hour = 0;
		var minute = 0;
		//has time
		if(datestring.trim().split(' ').length > 1)
		{
			//has time
			hour = datestring.split('/')[2].split(' ')[1].split(':')[0].getNumeric();
			minute = datestring.split('/')[2].split(' ')[1].split(':')[1].getNumeric();
			year = datestring.split('/')[2].split(' ')[0].getNumeric();
		}
		
		//update lowest denominator first
		//resultDate.setMonth(month);
		resultDate.setFullYear(year,month,day);
		resultDate.setMinutes(minute);
		resultDate.setHours(hour);
		//resultDate.setDate(day);
		
		//alert(resultDate)
		return resultDate;
	}catch(e){
		//fails so uses default now()
		return new Date();
	}
	
	return resultDate;
}

//refreshes the dateelement with the current internal date
AlcassoftDatePicker.prototype.refreshDateElement=function(){
	if(this.firstrun){
		Element.writeAttribute(this.dateelement,'value','');
		this.dateelement.value='';
	}
	else{
		Element.writeAttribute(this.dateelement,'value',this.getFormattedDate());
		this.dateelement.value = this.getFormattedDate();
	}
	/*
	if(this.date.getTime()==this.epoch.getTime()){
		Element.writeAttribute(this.dateelement,'value','');
		this.dateelement.value='';
	}
	else{
		Element.writeAttribute(this.dateelement,'value',this.getFormattedDate());
		this.dateelement.value = this.getFormattedDate();
	}
	*/
}

//depreciated? or we could expand it to display dates with different formatters?
AlcassoftDatePicker.prototype.getFormattedDate=function(){
	return this.dateToString(this.date);
}

//converts a date object to string dd/mm/yyyy HH:mm
AlcassoftDatePicker.prototype.dateToString=function(date){
	var _date = this.pad( '0',date.getDate().toString(),2, true );
	var _month = this.pad( '0',(date.getMonth()+1).toString(),2, true );;
	var _year = this.pad( '0',date.getFullYear().toString(),4, true );
	var _hour = this.pad( '0',date.getHours().toString(),2, true );
	var _minute = this.pad( '0',date.getMinutes().toString(),2, true );
	
	var dateString;
	
	if(this.removetimeformat)
	{
		dateString = _date+'/'+_month+'/'+_year;
	}
	else
	{
		dateString = _date+'/'+_month+'/'+_year+' '+_hour+':'+_minute;
	}
	
	return dateString; 
}

//pads the beginning / end of a value with given characters to fit expected length
AlcassoftDatePicker.prototype.pad=function(char,value,expectedlength,isprefix){
	var result = '';
	var padding = '';
		
	if(value.toString().length<expectedlength)
	{
		var chardiff = expectedlength-value.toString().length;
		for(var i=0;i<chardiff;i++)
		{
			padding+=char;
		}
	}
	
	if(isprefix)
		result = padding+value.toString();
	else{
		result = value.toString()+padding;
	}
		
	return result; 
}

String.prototype.trim=function(){
	return this.replace(/^\s+|\s+$/, '');
}

String.prototype.getNumeric=function(){
	var result = this.trim().replace(/[^0-9]*/, '');
	if(result=='')
	{
		result = 0;
	}
	else
	{
		result = parseInt(result,10);
	}
	return result;
}