/**********************************************************************************************
 * 	DATE PICKER CONTROL
 *
 * 	Converts an html input into a calendar date picker
 **********************************************************************************************

PARAMETERS: 
	1.	The id of the input element to use
	2.	a YAHOO.widget.Calendar configuration object
	3.	a tsi.datePicker configuration object

SAMPLE USAGE:

/**********************************************************************************************

<script type="text/javascript">
	function() {
		var arrival = new tsi.datePicker('arrival', { title:"Arrival date:", close:true, mindate:new Date() }, {maxlink: { input: 'departure', offset: -1 }});
		var departure = new tsi.datePicker('departure', { title:"Departure date:", close:true, mindate:new Date() }, {minlink: { input: 'arrival', offset: 1 }});
	}
);
</script>

<input type="text" id="arrival" size="12"> <label for="arrival">Arrival Date (mm/dd/yyyy)</label><br />
<input type="text" id="departure" size="12"> <label for="departure">Departure Date (mm/dd/yyyy)</label><br />

************************************************************************************************

tsi.datePicker configuration object 

	minlink: { 
		input: id of input to obtain min date from, 
		offset: # days to offset inputs value 
	}
	maxlink: { 
		input: id of element to obtain max date from, 
		offset: # days to offset inputs value 
	}
	icon: the url for the icon to use (default: calendar-icon.gif)
	TODO: format: string date format to return (default 'mm/dd/yyyy')


*************************************************************************************************/





/* make sure tsi namespace is created */
if (!tsi) { var tsi = {}; }

tsi.datePicker = function(el, calConfig, dpConfig) {
	
	// handler for a date selected in the calendar
	this.dateSelected = function(type,args,obj) {
		// store locally to save repetetive lookups
		var oCal = tsi.datePicker.calendar;
		var oInput = oCal.linkedInput;
		var yuiCfg = oCal.cfg;
	
		// hide the calendar
		oCal.hide();
	
		var dates = args[0]; 
		var date = dates[0];
	
		// zero pad single digit values
		for (var i=0;i<date.length;i++) {
			if (date[i] < 10) { date[i] = '0' + date[i]; }
		}
	
		// format output according to calendar controls config
		var aDates = [];
		aDates[yuiCfg.getProperty('MDY_YEAR_POSITION') - 1] = date[0];
		aDates[yuiCfg.getProperty('MDY_MONTH_POSITION') - 1] = date[1];
		aDates[yuiCfg.getProperty('MDY_DAY_POSITION') - 1] = date[2];
		oInput.value = aDates.join(yuiCfg.getProperty('DATE_FIELD_DELIMITER'));
	
		// set focus to the control
		oInput.focus();
	
		// move cursor to end in ie (defaults to end in ffx)
		if (oInput.createTextRange) {
			var v = oInput.value;
			var r = oInput.createTextRange();
			r.moveStart('character', v.length);
			r.select();
		}
	}
	
	
	
	// handler for show calendar button click
	this.show = function(e) {
		// store to locally to save repetetive lookups
		var yuiDom = YAHOO.util.Dom;
		var oCal = tsi.datePicker.calendar;
		oCal.linkedInput = this.input;
	
		// apply the calConfig options
		oCal.cfg.applyConfig( calConfig , true );
		
		var mindate;
		var pagedate;
		// then override mindate/maxdates with the linked input values
		if (calConfig['mindate']) { mindate = calConfig['mindate']; }
		if (dpConfig.minlink && dpConfig.minlink.input) {
			var oInput = document.getElementById(dpConfig.minlink.input);
			if (oInput) {
				var offsetDays = dpConfig.minlink.offset || 0;
				if (oInput.value.match(/^((0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])[- /.]((19|20)\d\d))$/)) {
					var oDate = new Date(oInput.value);
					var offsetDate = new Date(oDate.getTime() + offsetDays*(24*60*60*1000));
					if (mindate) {
						if (offsetDate > mindate) { 
							mindate = offsetDate; 
							pagedate = offsetDate;
						}
					} else {
						mindate = offsetDate;
						pagedate = offsetDate;
					}
				}
			}
		}
		// reset doesnt seem to work, so instead we set it to an invalid date
		oCal.cfg.setProperty('mindate', mindate);
		
		var maxdate;
		if (calConfig['maxdate']) { maxdate = calConfig['maxdate']; }
		if (dpConfig.maxlink && dpConfig.maxlink.input) {
			var oInput = document.getElementById(dpConfig.maxlink.input);
			if (oInput) {
				var offsetDays = dpConfig.maxlink.offset || 0;
				if (oInput.value.match(/^((0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])[- /.]((19|20)\d\d))$/)) {
					var oDate = new Date(oInput.value);
					var offsetDate = new Date(oDate.getTime() + offsetDays*(24*60*60*1000));
					if (maxdate) {
						if (offsetDate < maxdate) { 
							maxdate = offsetDate; 
							pagedate = offsetDate;
						}
					} else {
						maxdate = offsetDate;
						pagedate = offsetDate;
					}
				}
			}
		} 
		// reset doesnt seem to work, so instead we set it to an invalid date
		oCal.cfg.setProperty('maxdate', maxdate);
		
		
		// update the calendar to display the currently entered date (if valid)
		if (oCal.linkedInput.value.match(/^((0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])[- /.]((19|20)\d\d))$/)) {
			pagedate = oCal.linkedInput.value;
		} else if (!pagedate) { 
			pagedate = new Date(); 
		}
		oCal.select(pagedate);
		var firstDate = oCal.getSelectedDates()[0];
		pagedate = (firstDate.getMonth()+1) + "/" + firstDate.getFullYear();
		oCal.cfg.setProperty("pagedate", pagedate);
	
		
		oCal.render();
	
	
		// position the calendar beneath the correct control (this)
		var rgnInput = yuiDom.getRegion(oCal.linkedInput);
		yuiDom.setStyle(oCal.oDomContainer, 'left', rgnInput.left + "px");
		yuiDom.setStyle(oCal.oDomContainer, 'top', rgnInput.bottom + 1 + "px");
	
		// display the calendar
		oCal.show();
	}
	
	
	
	this.init = function() {
		// store locally to save repetetive lookups
		var yuiEvent = YAHOO.util.Event;
		var yuiDom = YAHOO.util.Dom;
		var yuiCalendar = YAHOO.widget.Calendar;
		var yuiSetStyle = yuiDom.setStyle;
	
		this.input = document.getElementById(el);
		if (!this.input) { return };
		
		this.format = dpConfig['format'] || 'mm/dd/yyyy';

		// create the icon button
		this.container = document.createElement('SPAN');
		yuiDom.addClass(this.container, 'datePicker');
		
		this.icon = document.createElement('IMG');
		this.icon.src = dpConfig['icon'] || 'datepicker-icon.png';
		
		// first we swap the input for the new span
		this.input.parentNode.replaceChild(this.container, this.input);
	
		// insert input back as a child of the span
		this.container.appendChild(this.input);
		
		// and add the icon right after that
		this.container.appendChild(this.icon);

		// sets up the function we want called when the show calendar button is clicked
		// here we will pass the input control to our event handler
		yuiEvent.addListener(this.icon, "click", this.show, this, true);



		// create the global calendar control
		if (!tsi.datePicker.calendar) {
			var oCal = document.createElement('DIV');
			oCal.id = 'tsiDatePicker';
			yuiSetStyle(oCal, 'display', 'none');
			yuiSetStyle(oCal, 'position', 'absolute');
			yuiSetStyle(oCal, 'zIndex', '1');
			document.body.appendChild(oCal);
			
			tsi.datePicker.calendar = new yuiCalendar("yuiCalendar1","tsiDatePicker", { title:"Choose a date:", close:true } );
	
			// sets up the function we want called when the user clicks selects a date
			// changed the passed object here from cal1 to oInput
			tsi.datePicker.calendar.selectEvent.subscribe(this.dateSelected);
			
			// tells it to draw with the above configuration
			tsi.datePicker.calendar.render();
		}
	}

	this.init();
	return this;
}
