//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Datetime picker mixin functions.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

var months = new Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');

function DateTimePickerMixin (obj, name) { 
    obj.hidden     = document.getElementById(name);
    obj.ddQHour    = document.getElementById(obj.prefix+name+'_quarterhour');
    obj.ddAmPm     = document.getElementById(obj.prefix+name+'_amPm');
    obj.value      = new Date();   //default date if none provided

	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	obj.ZeroPad = function(hourMinOrSec)
	{
		if (parseInt(hourMinOrSec)<10)
		{   return '0' + hourMinOrSec;  }
		return hourMinOrSec;
	}
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	obj.SetDDQHour  = function(qhour)
	{
		if (!this.ddQHour) return;
		// Round the minutes to the nearest quarter hour.
		var arrVals = qhour.split(':');
		var minutes = Math.floor(parseInt(arrVals[1]) / 15) * 15;
		var hours = parseInt(arrVals[0]) % 12;
		if (hours == 0) hours = 12;
		var qhour = hours + ':' + this.ZeroPad(minutes);
		this.SetDDValue( this.ddQHour, qhour);
	}
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	obj.SetDDAmPm  = function(hour)
	{
		// Sanity check - if there's no ampm element, return immediately.
		if (!this.ddAmPm) { return; }
		
		// Parse the hour value
		hour = parseInt(hour);

		// Depends on whether the am/pm selector is a select list or set of radio buttons.
		try {
			amPmType = this.ddAmPm.getAttribute('type').toLowerCase();
		}
		catch (e) {
			amPmType = '';
		}
		var amPmElement = this.ddAmPm.nodeName.toLowerCase();
		
		if ( amPmType == "radio" ) {
			// Get the collection of elements instead of just the first one.
			var buttons = document.getElementsByName(this.ddAmPm.id); 

    		if ( hour < 12 )  {   buttons[0].setAttribute('checked', 'true'); }
    		else              {   buttons[1].setAttribute('checked', 'true'); }
		}
		else if (amPmElement == "select") {
    		if ( hour < 12 )  {   this.SetDDValue( this.ddAmPm, 'AM' ); }
    		else              {   this.SetDDValue( this.ddAmPm, 'PM' ); }
		}
	}
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	obj.IsAm  = function()
	{
		// Sanity check - if there's no ampm element, return immediately.
		if (!this.ddAmPm) { return; }
		
		// Depends on whether the am/pm selector is a select list or set of radio buttons.
		try {
			amPmType = this.ddAmPm.getAttribute('type').toLowerCase();
		}
		catch (e) {
			amPmType = '';
		}
		var amPmElement = this.ddAmPm.nodeName.toLowerCase();

		if ( amPmType == "radio" ) {
			// Get the collection of elements instead of just the first one.
			var buttons = document.getElementsByName(this.ddAmPm.id);
			return (buttons[0].checked ? true : false); 
		}
		else if (amPmElement == "select") {
			return (this.ddAmPm.selectedIndex == 0 ? true : false);
		}
	}
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	obj.GetMaxDateOfMonth = function(month, year)
	{
		var tempDate = new Date();
		tempDate.setDate(28);
		tempDate.setMonth(month);
		tempDate.setYear(year)

		while( month == tempDate.getMonth())
		{
			var maxDate = tempDate.getDate();
			tempDate.setDate( maxDate+1);
		}
		return maxDate;
	}
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	obj.GetY2kYear = function(year)
	{
		year = parseInt(year);
		if (year < 1000)    {   year += 1900;   }
		return year;
	}
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	obj.GetDateField = function(date, i)
	{   return new String(date).split(' ')[i];  }
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	obj.SetDDValue = function(dd, selectedValue)
	{
		if (!dd) return (0);
		for (i=0;i<dd.options.length;i++)
		{
			if (dd.options[i].value.toString() == selectedValue.toString())
			{   return dd.selectedIndex = i;   }
		}
	}
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	obj.GetDDValue = function(dd, defaultValue)
	{
		if (!dd) return (0);
		if (null == defaultValue)
		{   defaultValue = -1;  }
		if (dd.selectedIndex == -1)
		{   return defaultValue;  }
		return dd.options[dd.selectedIndex].value;
	}
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	obj.ChangeQuarterHour = function(blnSync)
	{   
		var qhour = this.GetDDValue( this.ddQHour, null );
		if (qhour) {
			var arrVals = qhour.split(':');
			var hour = parseInt(arrVals[0]);
			if (!this.IsAm() && hour < 12) { hour += 12; }
			else if (this.IsAm() && hour == 12) { hour = 0; }
			this.value.setHours(parseInt(hour));
			this.value.setMinutes(parseInt(arrVals[1]));
		}
		this.ChangeHidden(blnSync);
	}
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	obj.FormatDateTimeString = function (dtmDate)
	{
		//Standard Format:
		var serverDateStr = ''; //sample: '02-feb-2002 14:02:00"
		var year = dtmDate.getYear();
		if (year < 2000) { year += 1900; }
		serverDateStr += dtmDate.getDate() + '-' +  (months[dtmDate.getMonth()]) + '-' + year + ' ';
	
		// If the quarterhour element exists, then use that to determine the time instead
		// of the hours and minutes fields.
		if (this.ddQHour) {
			arrVals = this.GetDDValue(this.ddQHour, '').split(':');
			var hours = parseInt(arrVals[0]);
			if (!this.IsAm() && hours < 12) { hours += 12; }
			else if (this.IsAm() && hours == 12) { hours = 0; }
			// Quick hack - we need to store midnight on day X as 00:00 on day X + 1.
			if (hours == 24) {
				hours = 0;
				var tmpDate = new Date(dtmDate.toString());
				serverDateStr = Date.addDate(tmpDate, Date.DAY, 1).getDate() + '-' +  (months[dtmDate.getMonth()]) + '-' + year + ' ';	
			} 
			var timeStr = this.ZeroPad(hours) + ':' +  arrVals[1] + ':00'; //this.ZeroPad(d.getSeconds());
		}
		else {
			var timeStr = this.ZeroPad(dtmDate.getHours()) + ':' +  this.ZeroPad(dtmDate.getMinutes()) + ':00'; //this.ZeroPad(d.getSeconds());
		}
		
		return (serverDateStr + timeStr);
	}
	
	//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	obj.ParseDateTimeFromString = function (strDatetime, blnNoTime)
	{
		if (blnNoTime) {
			var stdDate = strDatetime.toString().match(/^([0-9]+)-(...)-([0-9]+)/);
		}
		else {
			var stdDate = strDatetime.toString().match(/^([0-9]+)-(...)-([0-9]+) ([0-9]+):([0-9]+)/);
		}
		
		// So far so good, so split the date up into components.
		if ((stdDate)&&(stdDate.length > 0))
		{
			var parsed = new Date();
			var today = new Date();

			// Simple sanity checks
			if (stdDate[1] > 31) return (null);
			if (stdDate[3] < today.getFullYear()) return (null);

			else {
				parsed.setYear(stdDate[3]);
			}
			
			// Parse the time
			if (!blnNoTime) {
				parsed.setHours(stdDate[4]);
				parsed.setMinutes(stdDate[5]);
			}
			
			// Find the month
			var month = stdDate[2].toLowerCase();
			var gotMonth = false;
			var monthNum = null;
			for (i=0; i<months.length; i++) {
				if ( month == months[i].toLowerCase() ) {
					monthNum = i;
					gotMonth = true;
					break;
				}
			}
			if (!gotMonth) return (null);
			
			// Set the date values in a date
			parsed.setFullYear(stdDate[3], monthNum, stdDate[1]);
			
			// As an extra validation, if the date components of the new date don't match
			// the components we specified, we must have provided bad components.
			if (parsed.getDate() != stdDate[1] ||
					parsed.getMonth() != monthNum ||
					parsed.getFullYear() != stdDate[3]) return (null);
					
			return (parsed);
		}
		return (null);
	}
}
