/* Objects */

//Calendar Date Pairs - Stores Check in/out pairs of Dates
var calDates = {};

//Default date field values
var calVals = {
							val: 'mm/dd/yyyy',
							cssClass: 'date_field' 
							};

/* ---------- Functions ---------- */

/* -- Utility Functions -- */

//Checks if element is defined or is string ID of element
function checkElement(el) {
	if (typeof(el) == 'string')
		return document.getElementById(el);
	else
		return el;
}

//Checks Calendar that was activated and returns reciprocal calendar
function checkCal(calObj) {
	//Get Calendar Element
	var calEl = calObj.params.inputField;
	//Find reciprocal element
	var reEl;
	if (calObj.checkType == "out") {
		//Check-out calendar was activated
		//Get Check-in calendar
		for(var i in calDates) {
			if (calDates[i] == calEl) {
				reEl = i;
				break;
			}
		} 
	} else {
			reEl = calDates[calEl.id];
	}
	reEl = checkElement(reEl);
	return (reEl != undefined) ? reEl : false;
}

/* -- Calendar Setup Functions -- */

function buildDateFormat(dVals) {
	if (typeof dVals != "object")
		return "";
	var x = 0,
		dVal = [];
	//Iterate through date order array and build format array
	for (x; x < dateOrder.length; x++) {
		if (hasProp(dVals, dateOrder[x]))
			dVal[x] = dVals[dateOrder[x]];
	}
	//Combine into string and set as default value
	if (!hasProp(dVals, 'sep'))
		dVals['sep'] = "/";
	return dVal.join(dVals.sep);
}

//Set default value based on current locale
function setDateFieldValue() {
	if (!isset(dateOrder) || hasProp(Calendar._TT, "DEF_FIELD_VALUE_SET"))
		return false;
	var fvals = Calendar._TT["FIELD_VALUES"];
	Calendar._TT["DEF_FIELD_VALUE"] = buildDateFormat(fvals);
	//Set flag showing field value has been set
	Calendar._TT["DEF_FIELD_VALUE_SET"] = true;
}

function getDateFormat() {
	if (hasProp(Calendar._TT, "DEF_DATE_FORMAT_SET"))
		return Calendar._TT["DEF_DATE_FORMAT"];
	var dFormat = {
					"m"		: '%m',
					"d"		: '%d',
					"y"		: '%Y',
					"sep"	: '/'
					};
	if (!isset(dateOrder))
		return dFormat.m + dFormat.sep + dFormat.d + dFormat.sep + dFormat.y;
	dFormat = buildDateFormat(dFormat);
	Calendar._TT["DEF_DATE_FORMAT"] = dFormat;
	Calendar._TT["DEF_DATE_FORMAT_SET"] = true;
	//Add date format to input field
	return dFormat;
}

/* Sets default values for date fields
 * Arguments:
 * val (string): Default value for date fields
 * cssClass (string): Default CSS class for date fields   
 */
function setDateFieldDefaults(val, cssClass) {
	if (typeof val != "undefined")
		calVals.val = val;
	if (typeof cssClass != "undefined")
		calVals.cssClass = cssClass;
} //END setDateFieldDefaults

/* Sets date field pairs for check-in/out dates
 * Arguments [Optional]: Objects containing date field pairs
 * 	If no arguments are supplied, then function will scan document to find and setup date field pairs 
 * Members:
 * dfIn (string/element): ID or element reference of Check-in Date field
 * dfOut (string/element): ID or element reference of Check-out Date field 
 * in_trigger (string): ID of trigger element for check-in calendar
 * out_trigger (string): ID of trigger element for check-out calendar
 * val (string): Default value of date field
 * cssClass (string): Default CSS class of date field 
 * 
 * Usage:
 * setDateFields({dfIn: 'inField', dfOut: outField, in_trigger: 'checkIn_trigger', out_trigger: 'checkOut_trigger', val: 'mm/dd/yyyy', cssClass: 'date_field'}); 
 */ 
function setDateFields() {
	var fieldsArr = new Array(),
			dfp,
			inRoot,
			dfIn,
			dfOut;
	
	//If no arguments are supplied, scan document for date field pairs
	if (arguments.length == 0) {
		//Get all input fields
		var inputs = document.getElementsByTagName('input');
		for (var x = 0; x < inputs.length; x++) {
			//Find a check-in field
			if (inputs[x].id.length >= 3 && inputs[x].id.substr(inputs[x].id.length - 3) == '_in') {
				dfIn = inputs[x];
				//Get root ID of field
				inRoot = dfIn.id.substring(0, (dfIn.id.length - 3)); 
				//Find field's corresponding check-out field
				outID = inRoot + '_out';
				dfOut = inputs[outID];
				//If both in/out date fields are valid, add to array for later processing
				if (typeof dfOut != "undefined")
					fieldsArr.push({dfIn: dfIn, dfOut: dfOut});
			}
		}
	} else {
		fieldsArr = arguments;
	}
	
	//Iterate through arguments and setup date pairs
	for(var i = 0; i < fieldsArr.length; i++) {
		dfp = fieldsArr[i];
		//Skip argument if it is not a object or if in/out are not in the object
		if (typeof dfp != "object" || (!("dfIn" in dfp) || !("dfOut" in dfp)))
			continue;
		//Validate date fields
		dfp.dfIn = checkElement(dfp.dfIn);
		dfp.dfOut = checkElement(dfp.dfOut);
		if(!dfp.dfIn || !dfp.dfOut)
			continue;
		//Add date field pair to global calendar object
		calDates[dfp.dfIn.id] = dfp.dfOut;
		//Add Default values to date fields
		//if (typeof dfp.val != "undefined") {
			//dfp.dfIn.df_val = dfp.val;
			//dfp.dfOut.df_val = dfp.val;
		//}
		if (typeof dfp.cssClass != "undefined") {
			dfp.dfIn.df_cssClass = dfp.cssClass;
			dfp.dfOut.df_cssClass = dfp.cssClass;
		}
		//Check for triggers
		if (!("in_trigger" in dfp))
			dfp.in_trigger = "";
		if (!("out_trigger" in dfp))
			dfp.out_trigger = "";
		//Setup date fields
		//In
		setDateField(dfp.dfIn, dfp.in_trigger, dfp.val, dfp.cssClass);
		//Out
		setDateField(dfp.dfOut, dfp.out_trigger, dfp.val, dfp.cssClass);
	}
}
//End setDateFields

/* Adds initial string to a date field
 * Arguments:
 * df (string/element): ID or element reference of date field to evaluate
 * trigger [Optional] (string): ID of image/element that triggers calendar popup
 * 	Default: CheckIn_trigger or CheckOut_trigger (depending on date field type) 
 * val [Optional] (string): String to insert as default text into date field
 * 	Default: mm/dd/yyyy  
 * cssClass [Optional] (string): CSS class to apply to date field upon page load
 * 	Default: date_field      
 */
function setDateField(df, trigger, val, cssClass) {
	//Set default date field values based on current locale
	setDateFieldValue();
	
	if (typeof df != "undefined")
		df = checkElement(df);
	//Exit function if date field is not valid
	if (!df || (typeof df == "undefined"))
		return false;
	//Set default values
	if (typeof val == "undefined") val = ("DEF_FIELD_VALUE" in Calendar._TT) ? Calendar._TT["DEF_FIELD_VALUE"] : calVals.val;
	if (typeof cssClass == "undefined") cssClass = calVals.cssClass;
	
	//Check if date field is check-in or check-out
	var dfIn = (df.id in calDates) ? true : false;
	
	//Set default trigger for calendar display
	if ((typeof trigger == "undefined") || trigger == "") {
		trigger = df.id + '_trigger';
	}
	
	//Get date format for current locale
	dFormat = getDateFormat();
	df['dateFormat'] = dFormat;
	
	//Create Calendar Setup objects (modify for check-in/out fields)
	var rangeDate = new Date();
	var calObj = {
				inputField     :    df.id,     // id of the input field
				ifFormat       :    dFormat,      // format of the input field
				align          :    "Br",           // alignment (defaults to "Bl")
				singleClick    :    true,
				weekNumbers		 :		false,
				showOthers		 :		true,
				range					 :		[rangeDate.getFullYear(), rangeDate.getFullYear() + 2]
				};
	if (dfIn) {
		//Field is Check-in
		//Add function
		calObj.dateStatusFunc = disableYesterday;
	} else {
		//Field is assumed to be Check-out (Faster than iterating through object for value)
		calObj.dateStatusFunc = disableCheckIn;
		calObj.checkType = 'out';
	}
	//Setup Calendars
  Calendar.setup(calObj);
  //Add Trigger for Calendar
	calObj.button = trigger;
	Calendar.setup(calObj);
	
	if (df.value == "") {
		//Set Field Class
		df.className += ' ' + cssClass;
		//Set Field Text
		df.value = val;
	}
	//Add Change Event
	df.onchange = function() {
		resetDateField(df, val);
		//If Date Field is Check-in, add Check-out setting function
		if (dfIn) {
			setCheckOut(df);
		}
	};
}

//Removes initial string/styling from date field
function resetDateField(df) {
	df = checkElement(df);
	testDate = new Date(df.value);
	if ( testDate.toString().toLowerCase() == 'invalid date' ) {
		df.value = "";
	}
	var cssClass = ("df_cssClass" in df) ? df.df_cssClass : calVals.cssClass;
	var re = new RegExp('\\b' + cssClass + '\\b');
	df.className = df.className.replace(re, '');
}

//Wrapper function to reset both Check in/out date fields
function resetDateFields(dIn, dOut) {
	resetDateField(dIn);
	resetDateField(dOut);
}

/* -- Calendar Callback Functions -- */

//Disable all past dates in popup calendar
function disableYesterday(theDate, year, month, day) {
	yesterday = new Date();
	yesterday.setDate( yesterday.getDate() - 1 ) 
	if ( theDate < yesterday )
		return true;
	else
		return false;
} //END disableYesterday

/*Disables all dates in check-out calendar that precede the corresponding check-in date 
 */
function disableCheckIn(theDate, year, month, day) {
	inDate = checkCal(this);
	inDate = new Date(Date.parseDate(inDate.value, inDate.dateFormat));
	if ( inDate.toString().toLowerCase() == 'invalid date' ) {
		//Check-in Date is not yet set, disable all previous dates starting from yesterday
		return disableYesterday(theDate, year, month, day);
	} else {
		if (theDate < inDate) {
			return true;
		}
		if (theDate.toString() == inDate.toString()) {
			return "check-in disabled";
		}
	}
} //End disableCheckIn

/* Sets check-out date when check-in date has been changed
 *
 * Arguments:
 * inField (string/element): ID or element reference of Check-in field
 * outField [Optional] (string/element): ID or element reference of Check-out field
 * diff [Optional] (int): number of days between check-in/out dates
 * 
 * Usage:
 * setCheckOut('check_in');
 */  
function setCheckOut(inField, outField, diff) {
	//Make sure inField is valid
	if (typeof inField != "undefined")
		inField = checkElement(inField);
	if (typeof outField != "undefined")
		outField = checkElement(outField);
	else {
		outField = calDates[inField.id];
	}
	
	//Exit function if in or out date fields are not valid
	if (!inField || !outField)
		return false;
		
	if (inField.value != "") {
		resetDateField(outField);
		//Get number of days between check-in/out dates
		var diffDefault = 2;
		if (typeof diff != "undefined") {
			diff = parseInt(diff);
		}
		if (isNaN(diff))
				diff = diffDefault;
		//Get Check-In Date
		var dFormat = Calendar._TT["DEF_DATE_FORMAT"];
		if (hasProp(inField, 'dateFormat')) {
			dFormat = inField.dateFormat;
		}
		var inDate = new Date(Date.parseDate(inField.value, dFormat));
		//Set Check-Out Date to diff Days AFTER Check-In Date
		var outDate = new Date(inDate.getFullYear(), inDate.getMonth(), inDate.getDate() + diff);
		//Assign Check-Out Date to Text Field
		var outDate_string = outDate.print(dFormat);
		outField.value = outDate_string;
	 } else
		outField.value = "";
} //End setCheckOut

