/* 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 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 -- */

/* 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  
 * in_funcExt (function pointer): additional function for check-in calendar
 * out_funcExt (function pointer): additional function for check-out calendar 
 * Usage:
 * setDateFields({dfIn: 'inField', dfOut: outField, in_trigger: 'checkIn_trigger', out_trigger: 'checkOut_trigger', val: 'mm/dd/yyyy', cssClass: 'date_field'}); 
 */ 
function setDateFields(opts) {
	var fieldsArr = new Array(),
			dfp,
			inRoot,
			dfIn,
			dfOut,
			inSuffix = '_in';
			outSuffix = '_out';
	//If no arguments are supplied, scan document for date field pairs
	if (arguments.length == 0 || typeof(opts) != 'object') {
		//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 >= inSuffix.length && inputs[x].id.substr(inputs[x].id.length - 3) == inSuffix) {
				dfIn = inputs[x];
				//Get root ID of field
				inRoot = dfIn.id.substring(0, (dfIn.id.length - inSuffix.length)); 
				//Find field's corresponding check-out field
				outID = inRoot + outSuffix;
				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
		addProp(dfp, 'in_trigger', '', false);
		addProp(dfp, 'out_trigger', '', false);
		/*
		if (!("in_trigger" in dfp))
			dfp.in_trigger = "";
		if (!("out_trigger" in dfp))
			dfp.out_trigger = "";
		*/
		//Check for additional functions
		addProp(dfp, 'in_funcExt', null, false);
		addProp(dfp, 'out_funcExt', null, false);
		//Setup date fields
		//In
		setDateField(dfp.dfIn, dfp.in_trigger, dfp.val, dfp.cssClass, dfp.in_funcExt);
		//Out
		setDateField(dfp.dfOut, dfp.out_trigger, dfp.val, dfp.cssClass, dfp.out_funcExt);
	}
}
//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
 * funcExt [Optional] (function pointer): Extra function to run for calendar 
 */
function setDateField(df, trigger, val, cssClass, funcExt) {
	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 = 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';
	}
	
	//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       :    "%m/%d/%Y",      // format of the input field
				align          :    "Br",           // alignment (defaults to "Bl")
				singleClick    :    true,
				weekNumbers		 :		false,
				showOthers		 :		true,
				range					 :		[rangeDate.getFullYear() - 10, rangeDate.getFullYear() + 2]
				};
	if (dfIn) {
		//Field is Check-in
		//Add function
		if (isFunction(funcExt)) {
			calObj.dateStatusFunc = funcExt;
		}
	} else {
		//Field is assumed to be Check-out (Faster than iterating through object for value)
		calObj.checkType = 'out';
		calObj.dateStatusFunc = disableCheckIn;
	}
	if (isFunction(funcExt))
		df.funcExt = funcExt;
	//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 (typeof onDateChanged != "undefined")
	        onDateChanged();

	    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

function disableTomorrow(theDate, year, month, day) {
	tomorrow = new Date();
	//tomorrow.setDate(tomorrow.getDate() + 1);
	if (theDate >= tomorrow)
		return true;
	else
		return false;
} //END disableTomorrow

/*Disables all dates in check-out calendar that precede the corresponding check-in date 
 */
function disableCheckIn(theDate, year, month, day) {
	var retVal = false,
		df = this.params.inputField;
	inDate = checkCal(this);
	inDate = new Date(inDate.value);
	if ( inDate.toString().toLowerCase() == 'invalid date' ) {
		//Check-in Date is not yet set, disable all previous dates starting from yesterday
		retVal = disableYesterday(theDate, year, month, day);
	} else {
		if (theDate < inDate) {
			retVal = true;
		}
		else if (theDate.toString() == inDate.toString()) {
			retVal = "check-in disabled";
		}
	}
	if (!retVal && hasProp(df, 'funcExt') && isFunction(df.funcExt)) {
		retVal = df.funcExt(theDate, year, month, day);
	}
	return retVal;
		
} //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 = 0;
		if (typeof diff != "undefined") {
			diff = parseInt(diff);
		}
		if (isNaN(diff))
				diff = diffDefault;
		//Get Check-In Date
		var inDate = new Date(inField.value);
		//Set Check-Out Date to diff Days AFTER Check-In Date
		var outDate = new Date(inDate.getFullYear(), inDate.getMonth(), inDate.getDate() + diff);
		//Format Check-out date
		var outDate_string = (outDate.getMonth() + 1) + '/' + outDate.getDate() + '/' + outDate.getFullYear();
		//Assign Check-Out Date to Text Field (if field does not already have a valid date)
		 //Valid date: A date that is >= selected Check-in date
		if (outField.value != "") {
			//Get current Check-out field value
			outOrig = outField.value;
			outOrigDate = Date.parse(outOrig);
			if (!isNaN(outOrigDate) && (outOrigDate > inDate))
				outDate_string = outOrig;
		}
		outField.value = outDate_string;
	 }
} //End setCheckOut


