SearchForm = function(config) {
	/**
	 * The last active date in the calendar.
	 */
	this.mindate = config.mindate || null;
	
	/**
	 * The start date for the calendar.
	 */
	this.maxdate = config.maxdate || null;
	
	/**
	 * The date to initialise the calendar view for.
	 */
	this.initdate = config.initdate || null;
	
	/**
	 * Instance of the YAHOO calendar.
	 */
	this.calendar ;
	
	/**
	 * Updates the calendar to match the date supplied.
	 * 
	 * @param d {Date} The date.
	 */ 
	function setDate(cal, d) {
		if(d instanceof Date) {
			var year = d.getFullYear();
			var month = d.getMonth();
			var day = d.getDate();
			
			var date = month + "/" + day + "/" + year;
			
			cal.cfg.setProperty("selected", date, false);
			cal.cfg.setProperty("pagedate", month + "/" + year);
			cal.render();
		}
	};
		
	/**
	 * Toggle the calendar visibility.
	 */
	function toggleCalendar(container) {		
		var display = YAHOO.util.Dom.getStyle(container, "display");
		
		if(display != 'none') {
			// hide the calendar
			YAHOO.util.Dom.setStyle(container, "display", "none");
		}
		else {
			// show the calendar
			YAHOO.util.Dom.setStyle(container, "display", "");
		}
	};
	
	/**
	 * Handler for click events that toggle calendar
	 */
	function onShowEvent() {
		toggleCalendar(this.calendar.oDomContainer);
	}
	
	/**
	 * Handles a select from the calendar and
	 * maps the date selected to a collection
	 * of select lists.
	 */
	function updateDateFields(type, args, obj) {
		var dates = args[0];
		var date = dates[0];
		var year = date[0], month = date[1], day = date[2];
		
		var dateStr = padNumber(day) + "/" + padNumber(month) + "/" + year ;
		
		// set the value of the date field to
		// match the selected calendar date
		document.getElementById('date').value = dateStr;
		
		// update the hidden field to contain the value as the
		// disabled outbound_date field will not be sent on the
		// form submission 
		document.getElementById('outbound_date').value = dateStr;
		
		// toggle the calendar off
		toggleCalendar(obj.oDomContainer);
		
		setSearchDisabled(false);
	};
	
	/**
	 * Format a number according to a mask specfication.
	 * 
	 * @param num {Int} The number to format
	 * @param mask {String} The format mask for the number.
	 * @param prefix {String} Any charaters to prefix to the returned string. (Optional)
	 * @return {String} The formatted number.
	 */
	function padNumber(num) {
		if(num) {
			if(num.toString().length == 1) 
				return "0" + num;
			else 
				return "" + num;		
		}
		else {
			return "" + num;
		}
	};
	
	/**
	 * Disable the search panel submit button.
	 * 
	 * @param <Boolean> Disable the search button.
	 * @return void
	 */
	function setSearchDisabled(bDisable) {
		document.getElementById('search-submit').disabled = bDisable;
	}
	
	/**
	 * Create Calendar Object.
	 */
	this.calendar = new YAHOO.widget.Calendar("calendar", {
		navigator: true,
		mindate:this.mindate || "", 
		maxdate:this.maxdate || ""
	});
		
	/**
	 * Listen for a calendar selection event.
	 */
	this.calendar.selectEvent.subscribe(updateDateFields, this.calendar, true);
	
	/**
	 * Click listener for the date field.
	 */
	YAHOO.util.Event.addListener("calbtn", "click", onShowEvent, null, this);
	YAHOO.util.Event.addListener("date", "click", onShowEvent, null, this);
	
	/**
	 * Render the calendar to the page
	 */
	this.calendar.render();
	
	/**
	 * Set the start date for the calendar
	 */
	setDate(this.calendar, this.initdate) ;
		
	/**
	 * Dont let the user search without a date selected.
	 */
	setSearchDisabled(this.calendar.getSelectedDates().length == 0 ? true : false);
	
	/**
	 * Block the outbound date field from being edited manually by
	 * the user.
	 */
	document.getElementById('date').disabled = true ;
	
	/**
	 * If the initdate is null (not populated by FORM scope)
	 * then we can set the string
	 */
	if(!this.initdate) {
		document.getElementById('date').value = 'Click here to select date';
	}
}

/**
 * Disable a selection of days on the calendar widget.
 * Each day must be supplied as an integer i.e. 0-6 (Sun-Sat)
 * 
 * @param dates {Array} Array of DOTW to disable
 * @return false
 */
SearchForm.prototype.disableDays = function(days) {
	if(!days) {
		return ;
	}
	
	// start at today
	var d = new Date();
	
	// for every available date in the calendar
	while(Date.parse(d) < Date.parse(this.maxdate)) {
		
		// get the current date parts
		var month = d.getMonth() + 1;
		var day = d.getDate();
		var year = d.getFullYear();
		
		// build a YUI calendar date string
		var dStr = month + "/" + day + "/" + year;
		
		// if the current date falls on a disabled
		// day, then add a disabled cell renderer
		if(days.indexOf(d.getDay()) ==  -1) {
            this.calendar.addRenderer(dStr, this.calendar.renderOutOfBoundsDate);
        }
	    
		// increase the date by one day for the
		// next iteration of the loop
		d.setDate(d.getDate()+1);
	};
	
	// re-render the calendar
	this.calendar.render();
};