/*
	A Bot is a search form.
	A product is a travel vertical which may or may not have a bot on a page.
*/

var botMgr = new function () {
	this.initialized = false;
	this.botBoxIds = new Array();
	this.locTypeIds = new Array();
	this.bookTypeIds = new Array();
	this.componentDateIds = new Array();
	this.savedLocationIds = new Array();
	this.bId = ''; // same id that is in botBoxIds[i]
	this.pId = '';
	this.navProductSelected = null;
	this.botRefs = new Array(); //array of references to bots.
	this.tabCount = 1;
	this.cookie = new Cookie('bot');
	this.PRODUCTID_WITH_CHILDRENAGE = "aph";
	this.PRODUCTID2_WITH_CHILDRENAGE = "ahc";
	this.PRODUCTID3_WITH_CHILDRENAGE = "apc";
	this.CHILDRENAGE_MAX_AMOUNT = 3;
	this.CHILDRENAGE_INFANT_VALUE = '1';
	this.CHILDRENAGE_YOUTH_MIN_VALUE = 12;
	this.FORM_NAME = 'botForm';
	this.airOriginValue = '';

	this.fieldsInit = [{name:'Origin',value:''}, {name:'Destination',value:''}, {name:'Target',value:''}, {name:'AddressOrIntersection',value:''}, {name:'City',value:''}, {name:'StateProvince',value:''}, {name:'PostalCode',value:''}, {name:'StartMonth',value:''}, {name:'StartDay',value:''}, {name:'EndMonth',value:''}, {name:'EndDay',value:''}, {name:'StartTime',value:''}, {name:'StartTimeType',value:''}, {name:'EndTime',value:''}, {name:'EndTimeType',value:''}, {name:'Guests',value:''}, {name:'Passengers',value:''}, {name:'adults',value:''}, {name:'seniors',value:''}, {name:'youths',value:''}, {name:'children',value:''}, {name:'infantsWithoutSeat',value:''}, {name:'infantsWithSeat',value:''}, {name:'Rooms',value:''}, {name:'DriversAge',value:''}  ];
	this.fields = this.fieldsInit;

	this.travelerTypes = ['adults','seniors','youths','children','infantsWithoutSeat','infantsWithSeat'];

	this.addBotBox = function(botBoxId) {
		dlog.alert("addBotBox('"+botBoxId+"') <");
		this.botBoxIds[this.botBoxIds.length] = botBoxId;
	}

	this.addArrayTypeId = function(bId,arrTypeId,arrTypeArray) {
		// This function builds a 2 dimensional array of the location types within a bId
		dlog.alert("addArrayTypeId('"+bId+","+arrTypeId+","+arrTypeArray+"') <");
		if (!this[arrTypeArray]) {
			this[arrTypeArray] = new Array();
		}
		var j = arrayIndexOf(this[arrTypeArray],bId);
		if (j == -1) {
			// if we haven't yet encountered this bId before, make a new innerArray for it...
			var k = this[arrTypeArray].length;
			this[arrTypeArray][k] = new Array();
			// ...and insert the arrTypeId
			this[arrTypeArray][k][0] = bId;
			this[arrTypeArray][k][1] = arrTypeId;
		} else {
			// otherwise insert the arrTypeId at the end of that innerArray
			this[arrTypeArray][j][this[arrTypeArray][j].length] = arrTypeId;
		}
	}

	// Changing the active product/bot.
	this.setProduct = function (newBotId)
	{
		if (!newBotId) return;
		var activeProductId = newBotId;
		var oldBotId = this.getActiveBotId();
		dlog.alert("setProduct() from "+oldBotId+" to "+newBotId);
		this.hideElement(getRef(oldBotId));
		this.setActiveBotId(newBotId);
		this.showElement(getRef(newBotId));
		this.setFormFocus();
	}


	this.getActiveBotId = function() {
		return this.bId;
	}
	this.setActiveBotId = function (newBotId) {
		this.bId = newBotId;
	}

	// Functions to extract swap, get, and set value from fields
	this.swapFields = function (prevBot, nextBot, fieldName) {
		this.setFieldValue (nextBot, fieldName, this.getFieldValue(prevBot, fieldName));
	}
	this.getFieldValue = function (bot, fieldName) {
		dlog.alert("getFieldValue('"+bot+"', '"+fieldName+"')");
		var elemRef = getRef(bot + fieldName)
		if (elemRef)
		{
			switch (elemRef.type)
			{
				case "radio":
					//only handles single radio fields, default case has multiple radio implementation
					if (elemRef.checked) { return elemRef.value; } else { return ""; }
					break;
				case "checkbox":
					return elemRef.checked;
					break;
				case "select-one":
					return elemRef.options[elemRef.options.selectedIndex].value;
				break;
				default:

					if(elemRef[0].type == "radio") {
            			for (i = 0; i < elemRef.length; i++) {
               				if (elemRef[i].checked) {
                  				return elemRef[i].value;
							}
						}

            			return "";
         			}


					return elemRef.value;
			}
		}
		return null;
	}

	this.setFieldValue = function (bId, fieldName, newValue) {

		var elemRef = getRef(bId + fieldName)
		if (elemRef)
		{
			switch (elemRef.type)
			{
				case "radio":

					//only handles single radio fields
					if (elemRef.value == newValue) {
						elemRef.checked = true;
					}

				break;
				case "checkbox":
					elemRef.checked = newValue;
				break;
				case "select-one":
					this.selectValue(elemRef, newValue);
				break;
				default:
					elemRef.value = newValue;
			}

		}
	}

	this.grabFieldValues = function() {
		var guestsCount = 0;
		var guestsIndex = -1;
		for (var i=0; i<this.fields.length; i++)
		{
			var name = this.fields[i].name;
			var newValue = this.getFieldValue(this.bId, name);
			if (newValue) {
				this.fields[i].value = newValue;
				// increment guests count if field is a travelers' type
				for (var j=0; j < this.travelerTypes.length; j++) {
					if (name==this.travelerTypes[j]) {
						guestsCount += parseInt(newValue);
						j = this.travelerTypes.length;
					}
				}
			} else {
				if (name=='Guests') guestsIndex = i;
			}
		}
		/* special case: adding values from travelers and putting into Guests. */
		if (guestsIndex >= 0) this.fields[guestsIndex].value = guestsCount;

		return this.fields;
	}

	this.putFieldValues = function() {
		if (this.fields) {
			for (var i=0; i<this.fields.length; i++)
			{
				this.setFieldValue(this.bId, this.fields[i].name, this.fields[i].value);
			}
		}
		return this.fields;
	}

	this.setFormFocus =  function() {
		if (this.bId.indexOf('chg')>0 || this.bId.indexOf('edt')>0) return;
		var formRef = getRef(this.bId + this.FORM_NAME);
		if (formRef)
		{
			dlog.alert('setFormFocus(): form='+ formRef.id);
			var fieldSelected = false
			for (var k = 0; k < formRef.elements.length && !fieldSelected; k++) {
				var elemRef = formRef.elements[k];
				if (elemRef) {
					if (elemRef.type=='text' && !elemRef.disabled) {
						if (!this.hasClass(elemRef, 'hasError')) {

							for (var j = k+1; j < formRef.elements.length && !fieldSelected; j++) {
								var eleRef = formRef.elements[j];
								if (eleRef.type=='text' && !eleRef.disabled && this.hasClass(eleRef, 'hasError')) {
									dlog.alert('setFormFocus(): select on '+eleRef.id);
									eleRef.select();
									fieldSelected = true;
								}
							}
						}

						if (this.hasClass(elemRef, 'hasError') || !fieldSelected) {
						dlog.alert('setFormFocus(): select on '+elemRef.id);
						elemRef.select();
						fieldSelected = true;
					}
					}
					if (elemRef.type=='select-one' && !elemRef.disabled) {
						dlog.alert('setFormFocus(): focus on '+elemRef.id);
						//elemRef.focus(); IE did not like this
						fieldSelected = true;
					}
				}
			}
		}
	}

	this.disableUnchanged = function() {
		var selectRef = getRef(this.bId + 'StartMonth');
		if (selectRef && !this.hasClass(selectRef, 'changed'))
			selectRef.disabled = true;
		selectRef = getRef(this.bId + 'StartDay');
		if (selectRef && !this.hasClass(selectRef, 'changed'))
			selectRef.disabled = true;
		selectRef = getRef(this.bId + 'EndMonth');
		if (selectRef && !this.hasClass(selectRef, 'changed'))
			selectRef.disabled = true;
		selectRef = getRef(this.bId + 'EndDay');
		if (selectRef && !this.hasClass(selectRef, 'changed'))
			selectRef.disabled = true;
		selectRef = getRef(this.bId + 'Origin');
		if (selectRef && !this.hasClass(selectRef, 'changed'))
			selectRef.disabled = true;
		selectRef = getRef(this.bId + 'Destination');
		if (selectRef && !this.hasClass(selectRef, 'changed'))
			selectRef.disabled = true;
		selectRef = getRef(this.bId + 'Target');
		if (selectRef && !this.hasClass(selectRef, 'changed'))
			selectRef.disabled = true;
	}

	this.loadState = function() {
		dlog.alert("loadState(): botCookie="+this.cookie.get());
		/* make sure cookie has all field names */
		if (! this.cookie.get()) {
			this.cookie.setNameValues(this.fieldsInit);
			this.fields = this.cookie.getNameValues();
		} else {
			/* retrieve cookie values */
			this.fields = this.cookie.getNameValues();
			/* Put values into fields */
			//this.putFieldValues();
		}
	}


	//Returns an array of bot references as found in the DOM
	this.getBotRefs = function() {
		return this.botRefs;
	}


	//Returns an array of bot references within the botsRef
	this.getBotArray = function(botsRef) {
		var botArray = new Array();
		if (botsRef) {
			var index = 0;
			var productElems = botsRef.childNodes;
			for (var i = 0; i < productElems.length; i++) {
				if (this.hasClass(productElems[i], 'product')) {
					botArray[index] = getRef(productElems[i].id);
					//botArray[index] = productElems;  should replace line above
					index++;
				}
			}
		}
		return botArray
	}


	//Returns true if 'currentClass' is in 'element'
	//className; returns false otherwise.
	this.hasClass = function(element, currentClass) {
		var found = false;
		if (element && element.className) { //check to see if the element even has a classname attribute
			var classes = element.className.split(" ");

			//find the class in the className
			for (var i=0; i < classes.length; i++) {
				if (classes[i] == currentClass) {
					found = true;
					break;
				}
			}
		}
		return found;
	}


	//Adds the 'newClass' to 'element' className and returns
	//true.
	this.appendClass = function (element, newClass) {
		if (!element) return false;
		var length = element.className ? element.className.length : 0;

		if (length > 0) {
			if (this.hasClass(element, newClass)) {
				//the class already exists in className
				//dlog.alert('WARNING: appendClass(): className for ' + element.id + ' already contains "' + newClass + '"');
			} else {
				//className has classes, so let's append the new class
				element.className = element.className + " " + newClass;
				dlog.alert('appendClass(): class "' + newClass + '" added to ' + element.id + "'s className");
			}
		}
		else {
			//className is empty so the new class is assigned as the only class
			element.className = newClass;
			dlog.alert('appendClass(): className for ' + element.id + ' changed to "' + newClass + '"');
		}
		return true;
	}


	//Removes 'currentClass' from the 'element' className.  If the removal was
	//successful, returns true; otherwise returns false.
	this.removeClass = function(element, currentClass) {
		dlog.alert("removeClass('"+element.className+"', '"+currentClass+"')");
		var removed = false;
		if (element){
			var classes = element.className.split(" ");
			if (classes.length == 1 && classes[0]==currentClass) {
				element.className = ""; //the element only has a single class, so set it to an empty string
			} else {
				var newClassString = "";
				for (var i = 0; i < classes.length; i++) {
					if (classes[i] == currentClass) {
						removed = true;
					} else {
						newClassString +=  ((newClassString) ? " ": "") + classes[i];
				}
				}
				element.className = newClassString;
			}
			if (removed) dlog.alert('removeClass(): class "'+currentClass+'" for ' + element.id + ' was removed: "'+element.className+'"');
		}
		return removed;
	}


	//Removes oldClass and appends newClass to elementRef
	this.swapClasses = function(elementRef, oldClass, newClass) {
		if (elementRef != null) {
			this.removeClass(elementRef, oldClass);
			this.appendClass(elementRef, newClass);
		}
	}

	//Removes the hidden class and adds the visible class
	this.showElement = function(elementRef) {
		if (elementRef) {
			this.removeClass(elementRef, 'inactive');
			if (elementRef.tagName == 'SPAN') {
				this.appendClass(elementRef, 'inline');
			} else {
				this.appendClass(elementRef, 'active');
			}
		}
	}

	//Removes the visble class and adds the hidden class
	this.hideElement = function(elementRef) {
		if (elementRef) {
			if (elementRef.tagName == 'SPAN') {
				this.removeClass(elementRef, 'inline');
			} else {
				this.removeClass(elementRef, 'active');
			}
			this.appendClass(elementRef, 'inactive');
			dlog.alert("hideElement(): "+elementRef.id+".className='"+elementRef.className+"'");
		}
	}


	/* Select option within a select element that has the given value */
	this.selectValue = function(selectRef, value) {
		if (!selectRef) return 0;
		// If passed value is greater than last value in select elem, then select last option
		//alert(value + " " + selectRef.options[selectRef.options.length-1].value);
		//if (value > selectRef.options[selectRef.options.length-1].value) {
		//	alert("greaterthan");
		//	selectRef.selectedIndex = selectRef.options.length-1;
		//} else {
			for (var i=0; i < selectRef.options.length; i++) {
				if (selectRef.options[i].value==value) {
					selectRef.selectedIndex = i;
					break;
				}
			}
		//}
		return selectRef.selectedIndex;
	}

	this.gotoFlightType = function(elemRef) {
			if (elemRef) {
				dlog.alert("gotoFlightType(): className="+elemRef.className);
				var indexRT = botMgr.hasClass(elemRef, 'roundTrip');
				var indexOW = botMgr.hasClass(elemRef, 'oneWay');
				var indexMC = botMgr.hasClass(elemRef, 'multiCity');

				if (indexRT) {
					botMgr.setProduct('air');
					getRef('airRoundTrip').checked = true;
					getRef('aowRoundTrip').checked = true;
					getRef('amcRoundTrip').checked = true;

				}
				else if (indexOW ) {
					botMgr.setProduct('aow');
					getRef('airOneWay').checked = true;
					getRef('aowOneWay').checked = true;
					getRef('amcOneWay').checked = true;
				}
				else if (indexMC) {
					botMgr.setProduct('amc');
					getRef('airMultiCity').checked = true;
					getRef('aowMultiCity').checked = true;
					getRef('amcMultiCity').checked = true;
				}
			}
	}

	this.setSearchType = function(searchType) {
		var elemRef = getRef(this.bId + 'searchType');
		if (elemRef) elemRef.value = searchType;
	}

	/* EVENTS ================== */
	// Event to save state of form fields
	this.saveState = function() {
		dlog.alert("saveState(): botCookie("+botMgr.cookie.name+")="+botMgr.cookie.get());
		botMgr.cookie.setNameValues(botMgr.grabFieldValues());
		dlog.alert("saveState(): botCookie="+botMgr.cookie.get());
	}

	// Event to change the active product/bot. redirectUrl is optional.
	this.gotoBot = function ()
	{
		dlog.alert("gotoBot()");
		var newBotId = this.getAttribute('botid');
		var redirectUrl = this.getAttribute('href');
		var targetProduct = this.getAttribute('target');
		var dpHidden = this.getAttribute('dp');
		dlog.alert("gotoBot(): attributes: botid="+newBotId+" href="+redirectUrl+" target="+targetProduct+" dp="+dpHidden);
		// redirectUrl will change the page.
		if (redirectUrl) {
			// if targetProduct or dpHidden are not set, then simply redirect
			if (!targetProduct && !dpHidden) {
				dlog.alert('gotoBot(): REDIRECT to "'+redirectUrl+'"');
				document.location = redirectUrl;
			} else {
				if (targetProduct) {
					botMgr.setSearchType(targetProduct);
					dlog.alert('gotoBot(): setting searchType to "'+targetProduct+'"');
					if (targetProduct=='car') {
						var destinationRef = getRef(botMgr.bId + 'Destination');
						var originRef = getRef(botMgr.bId + 'Origin');
						if (destinationRef && originRef)	{
							if (botMgr.bId=='air' || botMgr.bId=='aow' || botMgr.bId=='amc')
								botMgr.airOriginValue = destinationRef.value;
							originRef.value = destinationRef.value;
						}
					}
				}
				if (dpHidden) {
					var dpHiddenRef = getRef(botMgr.bId + 'dpHidden');
					if (dpHiddenRef) dpHiddenRef.value = dpHidden;
					dlog.alert('gotoBot(): setting dpHidden to "'+dpHidden+'"');
				}
				dlog.alert('gotoBot(): SUBMIT after setting searchType or dpHidden');
				clickSubmit('expand');
			}
		} else {
			dlog.alert('gotoBot(): SET PRODUCT to "'+newBotId+'"');
			botMgr.setProduct(newBotId);
		}
	}

	this.dropdownChanged = function(event) {
		dlog.alert("dropdownChanged()");
		var evt = (event) ? event : ((window.event) ? window.event : "");
		if (evt) {
			var element = (evt.target) ? evt.target : evt.srcElement;
			dlog.alert("dropdownChanged(): element.id='"+element.id+"'");
			if (element) {
				botMgr.appendClass(element, 'changed');
				//solution to bug 36335, on change set other ambiguous dropdown to same value - mduhan -  2005-10-19
				var bId = botMgr.getActiveBotId();
				var formRef = getRef(bId + botMgr.FORM_NAME);
				if (formRef) {
					if (formRef.disambiguatedOrigin != null && formRef.locationType != null) { //make sure disambiguatedOrigin and locationType are there
						for (var l=0; l<formRef.locationType.length; l++) {
							if (formRef.locationType[l].checked) {
								var locType = formRef.locationType[l].value;
								break;
							}
						}
						if (locType == 'air') {
								formRef.target.selectedIndex = formRef.origin.selectedIndex;
						} else {
							if (locType == 'std') {
								formRef.origin.selectedIndex = formRef.target.selectedIndex;
							}
						}
					}
				}
			}
		}
	}

	this.textfieldChanged = function(event) {
		dlog.alert("textfieldChanged()");
		var evt = (event) ? event : ((window.event) ? window.event : "");
		if (evt) {
			var element = (evt.target) ? evt.target : evt.srcElement;
			if (element) {
				botMgr.appendClass(element, 'changed');
				// get id w/o bId
				var coreId = element.id.substr(botMgr.bId.length, element.id.length-botMgr.bId.length);
				dlog.alert("textfieldChanged(): coreId='"+coreId+"'");
				// loop thru all bots and set those with id to value
				var elemRef;
				for (var i=0; i<botMgr.botRefs.length; i++) {
					if (botMgr.botRefs[i].id != botMgr.bId) {
						if (botMgr.bId=='air' && botMgr.botRefs[i].id=='car' && (coreId=='Destination' || coreId=='Origin') ) {
							// air to car special case
							elemRef = getRef(botMgr.botRefs[i].id + 'Origin');
							if (elemRef && (coreId=='Destination' || (coreId=='Origin' && elemRef.value=='')))
								/* replace carOrigin with airDestination value */;
							else
								elemRef = null;
						} else if (botMgr.bId=='car' && botMgr.botRefs[i].id=='air' && (coreId=='Destination' || coreId=='Origin')) {
							// car to air special case
							if (coreId=='Origin') {
							//copy carOrigin to airDestination
							elemRef = getRef(botMgr.botRefs[i].id + 'Destination');
							} else {
								elemRef = null;  //carDestination should go nowhere.
							}
						} else {
							elemRef = getRef(botMgr.botRefs[i].id + coreId);
						}
						if (elemRef) {
							elemRef.value = element.value;
							botMgr.appendClass(elemRef, 'changed');
						}
						// Give slice1 a chance
						elemRef = getRef(botMgr.botRefs[i].id + coreId + '1');
						if (elemRef) {
							elemRef.value = element.value;
							botMgr.appendClass(elemRef, 'changed');
						}
					}
				}
			}
		}
	}
	this.textfieldFocus = function(event) {
		var evt = (event) ? event : ((window.event) ? window.event : "");
		if (evt) {
			var element = (evt.target) ? evt.target : evt.srcElement;
			element.select();
		}
	}


	// event to swap flightType bots
	this.swapAir = function(event) {
		var evt = (event) ? event : ((window.event) ? window.event : "");
		if (evt) {
			var elemRef = (evt.target) ? evt.target : evt.srcElement;
			botMgr.gotoFlightType(elemRef);
		}
	}

	// Event to hide the "add another flight" link for the current
	//slice and displays the next slice.
	this.showNextSlice = function(event) {
		var evt = (event) ? event : ((window.event) ? window.event : "");
		if (evt) {
			var element = (evt.target) ? evt.target : evt.srcElement;
			if (element) {
				if (!element.tagName) { element = element.parentNode;} /*Safari*/
				var sliceNum = eval(element.id.substr(element.id.length - 1));
				botMgr.hideElement( getRef("addAnotherFlight" + sliceNum) );
				botMgr.showElement( getRef("slice" + (sliceNum + 1)) );
			}
		}
	}

	this.showHideLocations =  function(bId) {
		var elemRef = getRef(bId + 'Airport');
		if (elemRef && elemRef.checked) {
			this.showElement(getRef(bId + 'EndPointsGroup'));
			elemRef = getRef(bId + 'Origin');
			if (elemRef) elemRef.disabled = false;
			this.hideElement(getRef(bId + 'TargetGroup'));
			elemRef = getRef(bId + 'Target');
			if (elemRef) elemRef.disabled = true;
			this.hideElement(getRef(bId + 'AddressGroup'));
		} else {
			elemRef = getRef(bId + 'CityPOI');
			if (elemRef && elemRef.checked) {
				this.hideElement(getRef(bId + 'EndPointsGroup'));
				elemRef = getRef(bId + 'Origin');
				if (elemRef) elemRef.disabled = true;
				this.showElement(getRef(bId + 'TargetGroup'));
				elemRef = getRef(bId + 'Target');
				if (elemRef) elemRef.disabled = false;
				this.hideElement(getRef(bId + 'AddressGroup'));
			} else {
				elemRef = getRef(bId + 'Address');
				if (elemRef && elemRef.checked) {
					this.hideElement(getRef(bId + 'EndPointsGroup'));
					elemRef = getRef(bId + 'Origin');
					if (elemRef) elemRef.disabled = true;
					this.hideElement(getRef(bId + 'TargetGroup'));
					elemRef = getRef(bId + 'Target');
					if (elemRef) elemRef.disabled = true;
					this.showElement(getRef(bId + 'AddressGroup'));
				}
			}
		}
	}

	// Event to change the location type
	this.swapLocations =  function(event) {
		dlog.alert("swapLocations()");
		var event = (event) ? event : ((window.event) ? window.event : "");
		if (event) {
			var element = (event.target) ? event.target : event.srcElement;
			if (element.tagName != 'LABEL')
				element = element.parentNode;
			// I really don't want to have to travel up the DOM, but I can't find a better solution - mduhan 2005-09-07
			var divelem = element;
			while (divelem.tagName != 'DIV') {
				divelem = divelem.parentNode;
			}
			var pbId = divelem.id.slice(0,(divelem.id.length-"LocationTypeBox".length));
			botMgr.setActiveBotId(pbId);
			var bId = botMgr.getActiveBotId();
			var labels = getRef(pbId + 'LocationTypeBox').getElementsByTagName('label');
			for (var i = 0; i < labels.length; i++) {
				if (labels[i]==element)
					botMgr.swapClasses(labels[i], 'inactiveRadio', 'activeRadio');
				else
					botMgr.swapClasses(labels[i], 'activeRadio', 'inactiveRadio');
			}

			//solution to bug 35903 - solson 10/11/05
			var formRef = getRef(bId + botMgr.FORM_NAME);
			if (formRef) {
				if (formRef.disambiguatedOrigin != null) { //make sure disambiguatedOrigin is there
					var inputElement = element.childNodes[0]; //get the input element that is nested in the label
					if (inputElement.value == 'std' || inputElement.value == 'air') { //set the disambiguate field to true for airport/cityPOI searches
						for (var i = 0; i < formRef.disambiguatedOrigin.length; i++)
							formRef.disambiguatedOrigin[i].value = true;
					}
					else { //set the disambiguate field to false for address searches
						for (var i = 0; i < formRef.disambiguatedOrigin.length; i++)
							formRef.disambiguatedOrigin[i].value = false;
					}
				}
			}

			botMgr.showHideLocations(pbId);
		}
	}


	// Event to show address fields, hiding target field
	this.showAddress = function(bId) {
		dlog.alert("showAddress("+bId+")");
		botMgr.hideElement(getRef(bId + 'SearchByAddress'));
		botMgr.hideElement(getRef(bId + 'TargetGroup'));
		botMgr.hideElement(getRef(bId + 'EndPointsGroup'));
		botMgr.showElement(getRef(bId + 'SearchByCity'));
		botMgr.showElement(getRef(bId + 'AddressGroup'));
		var elemRef = getRef(bId + 'LocationType');
		if (elemRef) elemRef.value = 'adr';
		elemRef = getRef(bId + 'Target');
		if (elemRef) elemRef.disabled = true;
		return false;
	}

	// Event to show target field and hide address fields
	this.showTarget = function(bId) {
		dlog.alert("showTarget("+bId+")");
		botMgr.hideElement(getRef(bId + 'SearchByCity'));
		botMgr.hideElement(getRef(bId + 'AddressGroup'));
		botMgr.showElement(getRef(bId + 'SearchByAddress'));
		botMgr.showElement(getRef(bId + 'TargetGroup'));
		botMgr.showElement(getRef(bId + 'EndPointsGroup'));
		var elemRef = getRef(bId + 'LocationType');
		if (elemRef) elemRef.value = 'std';
		elemRef = getRef(bId + 'Target');
		if (elemRef) elemRef.disabled = false;
		return false;
	}

	// Event to select specific hotel or not
	this.selectSpecificHotelOrNot = function() {
		var activeRadioId = 'SpecificHotelOnly';
		var inactiveRadioId = 'AllHotels'
		var hotelNameDisabled = false;
		elemRef = getRef(botMgr.bId + 'AllHotels');
		if (elemRef && elemRef.checked) {
			activeRadioId = 'AllHotels';
			inactiveRadioId = 'SpecificHotelOnly';
			hotelNameDisabled = true;
		}
		var bots = botMgr.getBotRefs();
		for (var i=0; i<bots.length; i++) {
			elemRef = getRef(bots[i].id + activeRadioId);
			if (elemRef) {
				elemRef.checked = true;
				botMgr.swapClasses(elemRef.parentNode, 'inactiveRadio', 'activeRadio');
			}

			elemRef = getRef(bots[i].id + inactiveRadioId);
			if (elemRef) {
				elemRef.checked = false;
				botMgr.swapClasses(elemRef.parentNode, 'activeRadio', 'inactiveRadio');
			}

			elemRef = getRef(bots[i].id + 'SpecificHotelName');
			if (elemRef) elemRef.disabled = hotelNameDisabled;
			//elemRef = getRef(bots[i].id + 'Target');
			//if (elemRef) elemRef.disabled = !hotelNameDisabled;
			//elemRef = getRef(bots[i].id + 'Destination');
			//if (elemRef) elemRef.disabled = !hotelNameDisabled;
		}
	}

	// Event to show hourly fields, hiding point-to-point fields
	this.showBookByAddress = function(bId) {
		dlog.alert("showBookByAddress("+bId+")");
		botMgr.hideElement(getRef(bId + 'BookByHourly'));
		botMgr.hideElement(getRef(bId + 'EndDates'));
		botMgr.showElement(getRef(bId + 'BookByAddress'));
		//botMgr.showElement(getRef(bId + 'LocationTypeBox'));
		//botMgr.showElement(getRef(bId + 'Locations'));
		var elemRef = getRef(bId + 'bookType');
		if (elemRef) elemRef.value = 'adr';
		elemRef = getRef(bId + 'Target');
		if (elemRef) elemRef.disabled = false;
		return false;
	}

	// Event to show point-to-point fields and hide hourly fields
	this.showBookByHourly = function(bId) {
		dlog.alert("showBookByHourly("+bId+")");
		botMgr.hideElement(getRef(bId + 'BookByAddress'));
		//botMgr.hideElement(getRef(bId + 'LocationTypeBox'));
		//botMgr.hideElement(getRef(bId + 'Locations'));
		botMgr.showElement(getRef(bId + 'BookByHourly'));
		botMgr.showElement(getRef(bId + 'EndDates'));
		var elemRef = getRef(bId + 'bookType');
		if (elemRef) elemRef.value = 'hourly';
		elemRef = getRef(bId + 'Target');
		if (elemRef) elemRef.disabled = true;
		return false;
	}

	// Event to show optionally search fields
	this.showSearchOptions = function (bId) {
		dlog.alert("showSearchOptions()");
		botMgr.hideElement(getRef(bId + "OptionsExpand"));
		botMgr.showElement(getRef(bId + "SearchOptions"));
		botMgr.removeClass(getRef(bId + "ExpandSearchOptions"), 'floatedExpand');
		var e=getRef(bId + 'ExpandSearchOptionsInput');
		if (e) {
			e.value='true';
		}
		return false;
	}

	// Event to show children age dropdowns (or hide)
	this.changeChildrenAge = function(bId, skipRules) {
		dlog.alert("changeChildrenAge('"+bId+"')");
		var adultTravelersRef = getRef(bId + "adults");
		var childrenTravelersRef = getRef(bId + "children");
		var childrenAgeRef = getRef(bId + "ChildrenAge");
		if (adultTravelersRef && childrenTravelersRef && childrenAgeRef) {
			var numAdultsTotal = parseInt(adultTravelersRef.value);
			var numChildrenTotal = parseInt(childrenTravelersRef.value);
			var numYouths = 0;
			var numInfantsWithoutSeat = 0;
			var numInfantsWithSeat = 0;
			if (numChildrenTotal <= 0) {

				botMgr.hideElement(childrenAgeRef);
				//childrenAgeRef.className = 'inactive';
			} else {
				botMgr.showElement(childrenAgeRef);
				for (var i=1; i <= botMgr.CHILDRENAGE_MAX_AMOUNT; i++) {
					var childAgeGroupRef = getRef(bId+"ChildAge"+i+"Group");
					if (i <= numChildrenTotal) {
						var childAgeRef = getRef(bId+"ChildAge"+i);
						var infantTypesRef = getRef(bId+"InfantTypes"+i);
						if (childAgeRef.value==botMgr.CHILDRENAGE_INFANT_VALUE) {

							// show infant types for certain age.
							botMgr.showElement(infantTypesRef);
							// Increase infant count
							elemRef = getRef(bId+"InfantWithoutSeat"+i)
							if (elemRef && elemRef.checked) numInfantsWithoutSeat++;
							else numInfantsWithSeat++;
						} else {
							// hide infant types and increment youth count
							botMgr.hideElement(infantTypesRef);
							var childAge = parseInt(childAgeRef.value);
							if (childAge >= botMgr.CHILDRENAGE_YOUTH_MIN_VALUE) numYouths++;
						}


						botMgr.showElement(childAgeGroupRef);
					} else {
						botMgr.hideElement(childAgeGroupRef);
					}
				}
			}
			if (!skipRules) {
				// Use the childrens' age to populate other bots' youth/child/infant dropdowns
				// rule 1: If bot has youth dropdown, use individual children counts
				// rule 2: If bot only has child dropdown, then use total children count
				// rule 3: If bot has Guests, then set it to total children + total adults
				var bots = botMgr.getBotRefs();

				for (var i = 0; i < bots.length; i++) {

					elemRef = getRef(bots[i].id + "youths");
					if (elemRef) {
						botMgr.selectValue(elemRef, numYouths);
						elemRef = getRef(bots[i].id + "infantsWithoutSeat");
						if (elemRef) botMgr.selectValue(elemRef, numInfantsWithoutSeat);
						elemRef = getRef(bots[i].id + "infantsWithSeat");
						if (elemRef) botMgr.selectValue(elemRef, numInfantsWithSeat);
						elemRef = getRef(bots[i].id + "children");
						if (elemRef) botMgr.selectValue(elemRef, numChildrenTotal - (numYouths+numInfantsWithoutSeat+numInfantsWithSeat));

					} else {
						elemRef = getRef(bots[i].id + "children");
						if (elemRef) botMgr.selectValue(elemRef, numChildrenTotal);

						elemRef = getRef(bots[i].id + "Guests");
						dlog.alert("changeChildrenAge(): total="+(numChildrenTotal+numAdultsTotal));
						if (elemRef) botMgr.selectValue(elemRef, (numChildrenTotal+numAdultsTotal));


						// repopulate other bots child ages and infant types
						for (var j=1; j <= botMgr.CHILDRENAGE_MAX_AMOUNT; j++) {

							if (j <= numChildrenTotal) {

								childAgeRef = getRef(bId+"ChildAge"+j);
								elemRef = getRef(bots[i].id+"ChildAge"+j);
								numChildAge = botMgr.getFieldValue(bId,"ChildAge"+j);
								if (elemRef) botMgr.setFieldValue(bots[i].id,"ChildAge"+j,numChildAge);

								infantTypesRef = getRef(bId+"InfantWithSeat"+j);
								elemRef = getRef(bots[i].id+"InfantWithSeat"+j);
								if (elemRef) botMgr.setFieldValue(bots[i].id,"InfantWithSeat"+j,botMgr.getFieldValue(bId,"InfantWithSeat"+j));

								infantTypesRef = getRef(bId+"InfantWithoutSeat"+j);
								elemRef = getRef(bots[i].id+"InfantWithoutSeat"+j);
								if (elemRef) botMgr.setFieldValue(bots[i].id,"InfantWithoutSeat"+j,botMgr.getFieldValue(bId,"InfantWithoutSeat"+j));


							}
						}

						// show/hide other bots child ages and infant types
						botMgr.changeChildrenAge(bots[i].id, true);







					}



				}
			}

		}
	}

	// Event when changing a traveler amount
	this.changeTraveler = function(bId, travelerType, elemId) {
		dlog.alert("changeTraveler('"+bId+"','"+travelerType+"','"+elemId+"')");
		if (!elemId || !travelerType || ""==travelerType) return;
		var elemRef = getRef(elemId);
		if (!elemRef) return;
		var numValue = elemRef.value;

		var bots = botMgr.getBotRefs();
		var travCount = 0;
		// rule 1: Change every bots' traveler amount of the given type
		for (var i = 0; i < bots.length; i++) {
			elemRef = getRef(bots[i].id + travelerType);
			if (elemRef) botMgr.selectValue(elemRef, numValue);
		}
		// rule 2: Add every traveler > 17 yrs old, put amount in every adults dropdown if senior dropdown is missing in bot.
		elemRef = getRef(bId + "adults");
		if (elemRef) travCount += parseInt(elemRef.value);
		elemRef = getRef(bId + "seniors");
		if (elemRef) travCount += parseInt(elemRef.value);
		dlog.alert("changeTraveler(): adult travCount="+travCount);
		for (var i = 0; i < bots.length; i++) {
			elemRef = getRef(bots[i].id + "seniors");
			if (!elemRef) {
				elemRef = getRef(bots[i].id + "adults");
				if (elemRef) botMgr.selectValue(elemRef, ''+travCount);
			}
		}

		// rule 3: Add every traveler <= 17 yrs old, put amount in every child dropdown if youth dropdown is missing in bot.
		travCount = 0;
		elemRef = getRef(bId + "children");
		if (elemRef) travCount += parseInt(elemRef.value);
		elemRef = getRef(bId + "youths");
		if (elemRef) travCount += parseInt(elemRef.value);
		elemRef = getRef(bId + "infantsWithSeat");
		if (elemRef) travCount += parseInt(elemRef.value);
		elemRef = getRef(bId + "infantsWithoutSeat");
		if (elemRef) travCount += parseInt(elemRef.value);
		dlog.alert("changeTraveler(): child travCount="+travCount);
		for (var i = 0; i < bots.length; i++) {
			elemRef = getRef(bots[i].id + "youths");
			if (!elemRef) {
				elemRef = getRef(bots[i].id + "children");
				if (elemRef) {
					botMgr.selectValue(elemRef, ''+travCount);
					// special case for children age change
					//if (botMgr.PRODUCTID_WITH_CHILDRENAGE==bots[i].id || botMgr.PRODUCTID2_WITH_CHILDRENAGE==bots[i].id || botMgr.PRODUCTID3_WITH_CHILDRENAGE==bots[i].id) {

						botMgr.changeChildrenAge(bots[i].id, true);

					//}
				}
			}
		}

		// rule 4: Add up every traveler type, put amount in every Guests dropdown
		travCount = this.countTravelers(bId);
		for (var i = 0; i < bots.length; i++) {
			elemRef = getRef(bots[i].id + "Guests");
			if (elemRef) {
				botMgr.selectValue(elemRef, ''+travCount);
			}
		}
		this.hideShowFlightPlusHotelButton(travCount);
	}

	this.hideShowFlightPlusHotelButton = function (numTravelers) {
		var aphButton = getRef('airAPHButton');
		if (aphButton != null) {
			if (numTravelers > 4)
				botMgr.swapClasses(aphButton, 'visible', 'invisible');
			else
				botMgr.swapClasses(aphButton, 'invisible', 'visible');
		}
	}

	this.countTravelers = function(bId) {
		var travCount = 0;
		for (var k=0; k < botMgr.travelerTypes.length; k++) {
			elemRef = getRef(bId + botMgr.travelerTypes[k]);
			if (elemRef) travCount += parseInt(elemRef.value);
		}
		return travCount;
	}

	// Event for showing preferred air carriers
	this.hideShowPreferredCarriers = function(bId) {
		var elemRef = getRef(bId + 'Preferenced');
		if (elemRef) {
			if (elemRef.checked) {
				botMgr.showElement(getRef(bId + 'PreferredCarriers'));
			} else {
				botMgr.hideElement(getRef(bId + 'PreferredCarriers'));
			}
		}

	}

	// Event to expand travelers. currently a form submit.
	this.expandTravelers = function() {
		dlog.alert("expandTravelers()");
		var elemRef = getRef(botMgr.getActiveBotId() + 'ExpandTravelers');
		if (elemRef) elemRef.value = 'true';
		clickSubmit('expand');
		return false;
	}

	// Event to go to flex search page.
	this.gotoFlexSearch = function() {
		dlog.alert("gotoFlexSearch()");
		clickSubmit('fareCalendarSearch');
		return false;
	}

	// Event to go to one-way search form
	this.gotoOneWaySearch = function() {
		dlog.alert("gotoOneWaySearch()");
		var elemRef = getRef(botMgr.bId + 'OneWay');
		if (elemRef) {
			elemRef.value = "oneway"
			elemRef.checked = true;
			//elemRef = getRef(botMgr.bId + "searchType");
			//if (elemRef) elemRef.value = "oneway";
		}
		clickSubmit('expand');
		return false;
	}

	// Event to display all traveler select boxes when 'children or seniors' link is clicked
	this.showTravelers = function(event) {
		dlog.alert("showTravelers()");
		var bots = botMgr.getBotRefs();
		for (var i = 0; i < bots.length; i++) {
			var bId = bots[i].id;
			for (var n = 1; n < botMgr.travelerTypes.length; n++) {
				//Append the class 'expanded' to the travelers component, which gives it auto width
				botMgr.appendClass(getRef(bId + 'Travelers'), 'expanded');
				botMgr.showElement(getRef(bId + botMgr.travelerTypes[n] + 'Travelers'));
			}
			botMgr.hideElement(getRef(bId + 'TravelersExpand'));
			botMgr.showElement(getRef(bId + 'PassengerLimitLink'));
			var elemRef = getRef(bId + 'ExpandTravelers');

			if (elemRef) elemRef.value = 'true';
		}
	}

	// Event to show reprice alert (ICA)
	this.showRepriceAlert = function() {
		dlog.alert("showAddress()");
		botMgr.showElement(getRef('errorClickReprice'));
		return false;
	}

	// Event to reset orbot values (ICA)
	this.resetOrbotValues = function(startDate, endDate) {
		dlog.alert("resetOrbotValues('"+startDate+"','"+endDate+"')");
		var tempRepriceDatesA = [startDate, endDate];
		var repriceDatesChangedB = false;
		for (var k = 0; k < this.affectRepriceElementsInputA.length; k++) {
			var elemRef = getRef(this.affectRepriceElementsInputA[k]);
			if (elemRef) {
				if (elemRef.value!=tempRepriceDatesA[k]) {
					elemRef.value = tempRepriceDatesA[k];
					repriceDatesChangedB = true;
				}
			}
		}
		if (repriceDatesChangedB) {
			botMgr.showRepriceAlert();
		}
		/*
		for (var k = 0; k < this.affectRepriceElementsInputA.length; k++) {
			var elemRef = getRef(this.affectRepriceElementsInputA[k]);
			if (elemRef) {
				elemRef.value = this.originalRepriceValuesInputA[k];
			}
		}
		for (var k = 0; k < this.affectRepriceElementsSelectA.length; k++) {
			var elemRef = getRef(this.affectRepriceElementsSelectA[k]);
			if (elemRef) {
				elemRef.options.selectedIndex = this.originalRepriceValuesSelectA[k];
			}
		}
		*/
		return false;
	}

	// Event for calendar popups
	this.popCalendar = function(event) {
		var calendarLink = "/App/ViewCalendar?chooseDate=true";
		// See calendarPop.jsp. 'chooseDate=true' indicates that calendarPop.jsp should call function chooseDate from bot.js to update the date fields instead of function selectDate from global.js. 'selectDate' is a legacy js function. New orbot development should not use 'selectDate' from global.js
		var evt = (event) ? event : ((window.event) ? window.event : "");
		if (evt) {
			var element = (evt.target) ? evt.target : evt.srcElement;
			var calLink = element.parentNode;
			//check to see if the calendar has an index (for 'multicity' calendars)
			var index = calLink.id.substr(calLink.id.length - 1);
			if (isNaN(index)) { //if there is no index, set one based on the type of calendar (start/end)
				if (calLink.id.indexOf('StartCalendar') != -1)
					index = 1;
				else if (calLink.id.indexOf('EndCalendar') != -1)
					index = 2;
			}
			calendarRef = calLink.id;//Save the calendar id to a global variable (needed for calendar popup)

			var fieldset = calLink.parentNode;
			var selects = fieldset.getElementsByTagName('select');
			for (var i = 0; i < selects.length; i++) {
				if (selects[i].className.indexOf('Month') != -1) {
					// pbId = passed botId
					var pbId = selects[i].id.slice(0,(selects[i].id.length-selects[i].name.length));
					botMgr.setActiveBotId(pbId);
					var monthAndYear = selects[i].options[selects[i].options.selectedIndex].value.split(" ");
					var month = monthAndYear[0];
					var year = monthAndYear[1] ? monthAndYear[1] : thisYear;
					var token = calendarLink.indexOf("?") == -1 ? "?" : "&";
					return popUpGen(calendarLink+token+"n="+index+"&view=calendar&setMonth="+month+"&setYear="+year,200,390,'popupcal','resizable=yes,menubar=no,status=no,scrollbars=no,toolbar=no,directories=no,location=no');
				}
			}
		}
	}

	this.submitHotelEditSearch = function(formId) {
		var frm = document.getElementById(formId);
		if (frm.locationType.value == 'adr')
			frm.keywordPIB.disabled = true;
	}

	// function to populate the location fields when savedLocation is selected
	this.changeSavedLocations = function(bId) {
		var savedLocRef = getRef(bId + 'SavedLocationID');
		var addrRef = getRef(bId + 'AddressOrIntersection');
		var cityRef = getRef(bId + 'City');
		var stateRef = getRef(bId + 'StateProvince');
		var postalRef = getRef(bId + 'PostalCode');
		if (savedLocRef && addrRef && cityRef && stateRef && postalRef) {
//			var savedLocValues = new Array();
//			savedLocValues = savedLocRef[savedLocRef.selectedIndex].value.split('|');
			var canGetAttrib = savedLocRef[savedLocRef.selectedIndex].getAttribute;
			if (canGetAttrib) {
				var addrValue = savedLocRef[savedLocRef.selectedIndex].getAttribute('street1');
				var cityValue = savedLocRef[savedLocRef.selectedIndex].getAttribute('city');
				var stateValue = savedLocRef[savedLocRef.selectedIndex].getAttribute('state');
				var postalValue = savedLocRef[savedLocRef.selectedIndex].getAttribute('postal');
//			} else {
//				var addrValue = savedLocValues[0];
//				var cityValue = savedLocValues[1];
//				var stateValue = savedLocValues[2];
//				var postalValue = savedLocValues[3];
			}
			var undefined;
			addrRef.value = (addrValue != null && addrValue != undefined) ? addrValue : "";
			cityRef.value = (cityValue != null && cityValue != undefined) ? cityValue : "";
			postalRef.value = (postalValue != null && postalValue != undefined) ? postalValue : "";
			// State works differently since it is a select
			var stateMatch = false;
			if (stateValue!=null) {
				for (var i=0; i<stateRef.length; i++) {
					if (stateRef[i].value == stateValue) {
						stateRef.selectedIndex = i;
						stateMatch = true;
						break;
					}
				}
			}
			// If no state matches or the value is null, set the select back to 0
			if (stateValue==null || !stateMatch) {
				stateRef.selectedIndex = 0;
			}
		}
	}

	// function to clear the location fields when Clear stop link is clicked
	this.clearSavedLocation = function(bId) {
		var savedLocRef = getRef(bId + 'SavedLocationID');
		if (savedLocRef) {
			savedLocRef.selectedIndex = 0;
			this.changeSavedLocations(bId);
		}
	}

	/*BEGIN: Orbot DHTML calendar events*/

	this.showAndPositionCalendar = function(event) {
		calendar.dateFieldFocused = true;
		var evt = (event) ? event : ((window.event) ? window.event : "");
		if (evt) {
			var element = (evt.target) ? evt.target : evt.srcElement;
			//re-pop calendar if it is not visible or the user has clicked in another date field (eventElement)
			if (!calendar.calendarVisible || element != calendar.eventElement ) {
				botMgr.swapClasses(calendar.containerDivRef, 'active', 'inactive');
				botMgr.removeClass(calendar.containerDivRef, botMgr.bId);
				calendar.eventElement = element;
			var index = element.id.substr(element.id.length - 1);
			index = (isNaN(index)) ? 0 : index;
			// pbId = passed botId
			var pbId = element.id.slice(0,(element.id.length-element.name.length));
			botMgr.setActiveBotId(pbId);

			// this is an ugly hack to position the calDiv relative to the eventElement because IE positions the calendar appropriately but doesn't move the elements on show/hide if they are set to relative in the css, and won't place the calendar correctly if they are set to static in the css. - mduhan - 2005-10-10
				calendar.eventElement.style.position = 'relative';

				var newXPos = botMgr.getXPosition(getRef(calendar.eventElement.id)) + calendar.xoffset; //calculate the difference in distance between the calendar and the current dates field
			newXPos = (newXPos > 0) ? newXPos : 0;
				calendar.containerDivRef.style.left = newXPos + 'px';

				var newYPos = botMgr.getYPosition(getRef(calendar.eventElement.id)) + calendar.yoffset; //calculate the difference in distance between the calendar and the current dates field
			newYPos = (newYPos > 0) ? newYPos : 0;
				calendar.containerDivRef.style.top = newYPos + 'px';

				calendar.eventElement.style.position = '';

				calendar.draw();
				calendar.documentRef.getElementById('calendarBody').className = '';
				calendar.calendarVisible = true;
				calendar.calendarFocused = false;
				calendar.dateFieldFocused = true;
				botMgr.appendClass(calendar.containerDivRef, pbId);
				calendar.containerDivRef.style.visibility = 'visible';
				botMgr.swapClasses(calendar.containerDivRef, 'inactive', 'active');
			}
			calendar.eventElement.select();
		}
	}

	this.hideCalendar = function() {
		if (calendar.calendarVisible) {
			botMgr.swapClasses(calendar.containerDivRef, 'active', 'inactive');
			botMgr.removeClass(calendar.containerDivRef, botMgr.bId);
			calendar.containerDivRef.style.visibility = 'hidden';   //setting a div-wrapped iframe to display:none crashes Safari, changing to visibility:hidden
			calendar.containerDivRef.style.top = calendar.yPos - calendar.yoffset;
			calendar.containerDivRef.style.left = calendar.xPos - calendar.xoffset;
			calendar.documentRef.getElementById('calendarBody').className = 'hidden';
			calendar.calendarFocused = false;
			calendar.calendarVisible = false;
		}
	} //this.hideCalendar();

	this.dateFieldBlur = function() {
		calendar.dateFieldFocused = false;
		window.setTimeout('botMgr.checkCalFocus()', 200);
	}

	this.setCalFocus = function() {
		calendar.calendarFocused = true;
	}

	this.clearCalFocus = function() {
		calendar.calendarFocused = false;
		window.setTimeout('botMgr.checkCalFocus()', 100);
	}

	this.checkCalFocus = function() {
		if (!calendar.calendarFocused && !calendar.dateFieldFocused)
			botMgr.hideCalendar();
	}

	this.getXPosition = function(obj) {
		var curleft = 0;
		if (obj.offsetLeft) {
			curleft += obj.offsetLeft;
		} else {
			if (obj.x) {
				curleft += obj.x;
			}
		}
		return curleft;
	}

	this.getYPosition = function(obj) {
		var curtop = 0;
		if (obj.offsetTop) {
			curtop += obj.offsetTop;
		} else {
			if (obj.y) {
				curtop += obj.y;
			}
		}
		return curtop;
	}

	/*END: Orbot DHTML calendar events*/

	/* end: EVENTS */

	/* BEHAVIORS */
	//Builds out the location menu
	this.behaviorLocationType = function(bId) {
		var jarr = new Array();
		jarr = getInnerArray(botMgr.locTypeIds,bId);
		for (var i=0; i<jarr.length; i++) {
			// pbId = passed botId
			var pbId = jarr[i];
			var elemRef = getRef(pbId + 'LocationTypeBox');
			if (elemRef) {
				var radios = elemRef.getElementsByTagName('input');
				if (radios != null && radios.length > 0) {
					// car
					for (var l = 0; l < radios.length; l++) {
						radios[l].onclick = this.swapLocations;
						if (radios[l].checked)
							botMgr.swapClasses(radios[l].parentNode, 'inactiveRadio', 'activeRadio');//style the active label
					}
					// init
					this.showHideLocations(pbId);
				}
			}
		}
	}

	this.behaviorBotForms =  function(botsRef, skipElements) {
		if (!botsRef) return;
		var formList = botsRef.getElementsByTagName('form');
		for (var j=0; j<formList.length; j++)
		{
			if (formList[j].name==this.FORM_NAME) {
				dlog.alert('behaviorBotForm(): form='+ formList[j].name);
				formList[j].searchMethodHidden.value = 'find';
				if (!skipElements) {
					for (var k = 0; k < formList[j].elements.length; k++) {
						// tab index
						var elemRef = formList[j].elements[k];
						elemRef.disabled = false;
						if (elemRef.type != 'hidden' && elemRef.tagName != 'FIELDSET')
							elemRef.tabIndex  = this.tabCount++;
						switch (elemRef.type)
						{
							case "radio":
							break;
							case "checkbox":
							break;
							case "select-one":
								elemRef.onchange = this.dropdownChanged;
								dlog.alert("behaviorBotForms(): select-one: "+elemRef.id);
							break;
							case "text":
								elemRef.onchange = this.textfieldChanged;
								elemRef.onfocus = this.textfieldFocus;
							break;
							case "submit":
								if (this.hasClass(elemRef, 'aph'))
									elemRef.onclick = new Function("botMgr.setSearchType('"+'airhotel'+"');"+elemRef.onclick);
							break;
						}
					}
				}
			}
			if (formList[j].id == 'htledtBotForm') {
				formList[j].onsubmit = new Function("botMgr.submitHotelEditSearch('"+ formList[j].id +"');");
			}
		}
	}

	this.behaviorFlightType = function(bId) {
		var flightType = getRef(bId + 'FlightType');
		if (flightType != null) {
			var radios = flightType.getElementsByTagName('input');
			if (radios != null && radios.length >0) {
				for (i = 0; i < radios.length; i++)
					radios[i].onclick = this.swapAir; //swapAir is air-specific
			}
		}
	}

	this.behaviorFlightOptions = function(bId) {
		var elemRef = getRef(bId + 'Preferenced');
		if (elemRef) {
			elemRef.onclick = new Function("botMgr.hideShowPreferredCarriers('"+bId+"');");
			//initialization
			this.hideShowPreferredCarriers(bId);
		}
	}

	this.behaviorLinkSubmit = function (bId) {
		// children or seniors redirects

		dlog.alert("behaviorLinkSubmit("+bId+")");
		var linkRef = getRef(bId + 'TravelersRedirect');
		if (linkRef) {
			linkRef.onclick = this.expandTravelers;
		}
		//
		linkRef = getRef(bId + 'OneWayLink');
		if (linkRef) {
			linkRef.onclick = this.gotoOneWaySearch;
		}
		linkRef = getRef(bId + 'FlexDatesLink');
		if (linkRef) {
			linkRef.onclick = this.gotoFlexSearch;
		}
		linkRef = getRef(bId + 'FlexWeekendsLink');
		if (linkRef) {
			linkRef.onclick = this.gotoFlexSearch;
		}
	}
	// productNav redirects -- will only work with one botBox
	this.behaviorProductNav = function () {
		var elemRef = getRef('productNav');
		if (elemRef) {
			var elemList = elemRef.getElementsByTagName('input');
			for (var j=0; j<elemList.length; j++)
			{
				dlog.alert('behaviorProductNav(): input('+ elemList[j].id +') href='+elemList[j].getAttribute('href') +' bId='+elemList[j].getAttribute('botid'));
				elemList[j].onclick = this.gotoBot;
				// Record the checked product radio. used below.
				if (elemList[j].checked) {
					this.navProductSelected =  elemList[j].getAttribute('botid');
				}
			}
			// Reselect the last/current selected product. In case of reloads and back buttons.
			var elemRef = getRef(this.navProductSelected + 'FlightType');
			if (elemRef) {
				// flight type special case
				var elemList = elemRef.getElementsByTagName('input');
				for (var j=0; j<elemList.length; j++)
				{
					if (elemList[j].checked) {
						this.gotoFlightType(elemList[j]);
						break;
					}
				}
			} else {
				if (this.bId != this.navProductSelected)
					this.setProduct(this.navProductSelected);
			}
		}
	}

	this.behaviorExpandOptions = function (bId) {
		dlog.alert("behaviorExpandOptions()");
		var linkRef = getRef(bId + 'OptionsLink');
		dlog.alert("behaviorExpandOptions(): linkRef="+linkRef);
		if (linkRef) {
			var redirectLinkRef = getRef(bId + 'OptionsRedirect');
			if (redirectLinkRef) {
				linkRef.onclick = new Function("var e=getRef('"+bId+"ExpandSearchOptionsInput'); if (e) e.value='true'; clickSubmit('expand'); return false;");
			} else {
				// set event to expand the search options
				linkRef.onclick = new Function("return botMgr.showSearchOptions('"+ bId +"');");
			}
			// hide the search option markup initially (may not exist)
			var searchOptions = getRef(bId + 'SearchOptions');
			if (searchOptions != null)
				this.hideElement(searchOptions);
		}
	}

	//Builds the event functions for the "add another
	//flight" links in a multicity flight.  Also hides slices
	//4 thru 6 so the user can opt to "add another flight".
	this.behaviorAddAnotherFlight = function() {
	isHomeAMC = document.getElementById('amc');
		//assign event fuctions to the links
		for (m = 3; m <= 5; m++) {
			var addLink = getRef("addAnotherFlight" + m);
			if (addLink != null) {
				addLink.onclick = this.showNextSlice;
			}
		}
		//hide slices 4, 5 and 6 for front page amc only
		for (n = 4; n <= 6; n++) {
			var slice = getRef("slice" + n);
				if (slice != null && isHomeAMC != null) {
				botMgr.appendClass(slice, 'inactive');
			}
		}
	}

	//Builds the event functions for all calendars
	this.behaviorCalendar = function(bId) {
		var jarr = new Array();
		jarr = getInnerArray(botMgr.componentDateIds,bId);
		for (var i=0; i<jarr.length; i++) {
			// pbId = passed botId
			var pbId = jarr[i];
			var calStartLink = getRef(pbId + 'StartCalendar');
			var calEndLink = getRef(pbId + 'EndCalendar');
			if ((calStartLink == null) && (calEndLink == null)) { //if 'StartCalendar' and 'EndCalendar' don't exist we are looking for 'StartCalendar[1-6]' for multicity flight
				for (var k = 1; k <= 6; k++) {
					var calStartLink = getRef(pbId + 'StartCalendar' + k); //get indexed calendar button links
					if (calStartLink != null)
						calStartLink.onclick = this.popCalendar; //apply calendar popup event to the calendar button link
				}
			} else {
				if (calStartLink != null) {
					calStartLink.onclick = this.popCalendar; //apply calendar popup event to the calendar button link
				}
				if (calEndLink != null) {
					calEndLink.onclick = this.popCalendar; //apply calendar popup event to the calendar button link
				}
			}
		}
	}


	this.behaviorDisplayTravelers = function(bId) {
		dlog.alert("behaviorDisplayTravelers('"+bId+"')");
		// event to expand travelers
		elemRef = getRef(bId + 'TravelersExpand');
		if (elemRef)
			elemRef.onclick = this.showTravelers;
	}

	//Builds the event functions for all "search by
	//address" and "search by city" links in the
	//location type component.
	this.behaviorSearchBy = function(bId) {
		dlog.alert("behaviorSearchBy('"+bId+"')");
		var jarr = new Array();
		jarr = getInnerArray(botMgr.locTypeIds,bId);
		for (var i=0; i<jarr.length; i++) {
			// pbId = passed botId
			var pbId = jarr[i];
			var sByARef = getRef(pbId + 'SearchByAddressLink');
			var sByCRef = getRef(pbId + 'SearchByCityLink');
			if (sByARef && sByCRef) {
				sByARef.onclick = new Function("return botMgr.showAddress('"+ pbId +"');");
				sByCRef.onclick = new Function("return botMgr.showTarget('"+ pbId +"');");
				// init
				if (this.hasClass(sByARef, 'isDefault')) {
					this.showAddress(pbId);
				} else {
					this.showTarget(pbId);
				}
			}
		}
	}

	this.behaviorSpecificHotel = function(bId) {
		dlog.alert("behaviorSpecificHotel('"+bId+"')");
		var elemRef = getRef(bId + 'SpecificHotelOnly');
		if (elemRef) {
			elemRef.onclick = this.selectSpecificHotelOrNot;
		}
		elemRef = getRef(bId + 'AllHotels');
		if (elemRef) {
			elemRef.onclick = this.selectSpecificHotelOrNot;
		}
		// init
		this.selectSpecificHotelOrNot();
	}

	//Builds the event functions for all "search by hourly"
	// and "search by point-to-point" links in the bookBy
	// type component.
	this.behaviorBookBy = function(bId) {
		dlog.alert("behaviorBookBy('"+bId+"')");
		var jarr = new Array();
		jarr = getInnerArray(botMgr.bookTypeIds,bId);
		for (var i=0; i<jarr.length; i++) {
			// pbId = passed botId
			var pbId = jarr[i];
			var sByARef = getRef(pbId + 'BookByAddressLink');
			var sByHRef = getRef(pbId + 'BookByHourlyLink');
			if (sByARef && sByHRef) {
				sByARef.onclick = new Function("return botMgr.showBookByHourly('"+ pbId +"');");
				sByHRef.onclick = new Function("return botMgr.showBookByAddress('"+ pbId +"');");
				// init
				if (this.hasClass(sByARef, 'isDefault')) {
					this.showBookByAddress(pbId);
				} else {
					this.showBookByHourly(pbId);
				}
			}
		}
	}

	//Adds the dynamic date changing feature to
	//month and day select boxes
	this.behaviorDates = function(bId) {
		var jarr = new Array();
		jarr = getInnerArray(botMgr.componentDateIds,bId);
		for (var i=0; i<jarr.length; i++) {
			// pbId = passed botId
			var pbId = jarr[i];
			var dates = getRef(pbId + "Dates"); //check for a set of date fields
			if (dates != null) {
				selects = dates.getElementsByTagName('select'); //find all select fields
				for (m = 0; m < selects.length; m++)
					if (botMgr.hasClass(selects[m], 'startMonth') || botMgr.hasClass(selects[m], 'startDay'))
						selects[m].onchange = changeDateWithEvent; //apply changeDate event to startMonth and startDay select boxes
			} else { //it's a multicity flight date set
				dates = getRef(pbId + "Dates1"); //check for a set of indexed date fields (multicity flights)
				if (dates != null) {
					for (var k = 1; k <= 6; k++) {
						var datesRef = getRef(pbId + 'Dates' + k);
						if (datesRef) {
							selects = datesRef.getElementsByTagName('select'); //find all select fields
							for (n = 0; n < selects.length; n++)
								if (botMgr.hasClass(selects[n], 'startMonth') || botMgr.hasClass(selects[n], 'startDay'))
									selects[n].onblur = changeDateWithEvent; //apply changeDate event to startMonth and startDay select boxes
						}
					}
				}
			}
		}
	}

	//Add DHTML calendar functionality to date input boxes
	this.behaviorDatesWithCalendar = function (bId) {
		var jarr = new Array();
		jarr = getInnerArray(botMgr.componentDateIds,bId);
		for (var i=0; i<jarr.length; i++) {
			// pbId = passed botId
			var pbId = jarr[i];
			var dates = getRef(pbId + "Dates"); //check for a set of date fields
			if (dates != null) {
				inputs = dates.getElementsByTagName('input');
				for (var m = 0; m < inputs.length; m++) {
					if (document.getElementById('floating') == null) { //disable onfocus for floating bot 
						inputs[m].onfocus = this.showAndPositionCalendar;
						}
					inputs[m].onclick = this.showAndPositionCalendar;
					inputs[m].onblur = this.dateFieldBlur;
				}
			} else { //it's a multicity flight date set
				dates = getRef(pbId + "Dates1");
				if (dates != null) {
					for (var i = 1; i <= 6; i++) {
						var datesRef = getRef(pbId + 'Dates' + i);
						if (datesRef != null) {
							inputs = datesRef.getElementsByTagName('input');
							for (var n = 0; n < inputs.length; n++) {
								if (botMgr.hasClass(inputs[n], 'startDate')) {
									inputs[n].onfocus = this.showAndPositionCalendar;
									inputs[n].onclick = this.showAndPositionCalendar;
									inputs[n].onblur = this.dateFieldBlur;
								}
							}
						} //if datesRef
					} //for
				} //if dates
			} //else
		} //for
	} //this.behaviorDatesWithCalendar()

	this.behaviorTravelers = function(bId) {
		for (var k=0; k < this.travelerTypes.length; k++) {
			var elemId = bId + this.travelerTypes[k];
			var travelerSelectRef = getRef(elemId);
			if (travelerSelectRef) {
				travelerSelectRef.onchange = new Function("", "botMgr.changeTraveler('"+bId+"','"+this.travelerTypes[k]+"','"+elemId+"');");
			}
		}
		this.hideShowFlightPlusHotelButton(this.countTravelers(bId));
	}

	this.behaviorChildrenAge = function(bId) {
		var elemRef = getRef(bId + "children");
		if (elemRef) {
			elemRef.onchange = new Function("botMgr.changeChildrenAge('"+bId+"');");
		}
		for (var i=1; i<=this.CHILDRENAGE_MAX_AMOUNT; i++) {
			elemRef = getRef(bId+"ChildAge"+i);
			if (elemRef) {
				elemRef.onchange = new Function("botMgr.changeChildrenAge('"+bId+"');");
			}
			elemRef = getRef(bId+"InfantWithSeat"+i)
			if (elemRef) {
				elemRef.onchange = new Function("botMgr.changeChildrenAge('"+bId+"');");
			}
			elemRef = getRef(bId+"InfantWithoutSeat"+i)
			if (elemRef) {
				elemRef.onchange = new Function("botMgr.changeChildrenAge('"+bId+"');");
			}
		}
		// initialization
		this.changeChildrenAge(bId);
	}

	// Initialize function to populate the location fields when savedLocation is selected
	this.behaviorSavedLocation = function(bId) {
		var jarr = new Array();
		jarr = getInnerArray(botMgr.savedLocationIds,bId);
		for (var i=0; i<jarr.length; i++) {
			// pbId = passed botId
			var pbId = jarr[i];
			var savedLocRef = getRef(pbId + 'SavedLocationID');
			if (savedLocRef) {
				savedLocRef.onchange = new Function("botMgr.changeSavedLocations('"+pbId+"');");
			}
		}
	}

	// Initialize function to populate the links to clear a stop
	this.behaviorClearStop = function(bId) {
		var jarr = new Array();
		jarr = getInnerArray(botMgr.savedLocationIds,bId);
		for (var i=0; i<jarr.length; i++) {
			// pbId = passed botId
			var pbId = jarr[i];
			var clearStopRef = getRef(pbId + 'ClearStop');
			if (clearStopRef) {
				clearStopRef.onclick = new Function("botMgr.clearSavedLocation('"+pbId+"');");
			}
		}
	}

	// behavior alert
	this.behaviorRepriceAlert = function(bId) {
		dlog.alert("behaviorSpecificHotel('"+bId+"')");
		this.originalRepriceValuesInputA = new Array();
		this.affectRepriceElementsInputA = [bId+"StartDate", bId+"EndDate"];
		for (var k = 0; k < this.affectRepriceElementsInputA.length; k++) {
			var elemRef = getRef(this.affectRepriceElementsInputA[k]);
			if (elemRef) {
				elemRef.onfocus = new Function("botMgr.showRepriceAlert();");
				this.originalRepriceValuesInputA[k] = elemRef.value;
			}
		}
		this.originalRepriceValuesSelectA = new Array();
		this.affectRepriceElementsSelectA = [bId+"Target", bId+"StartTime", bId+"EndTime"];
		for (var k = 0; k < this.affectRepriceElementsSelectA.length; k++) {
			var elemRef = getRef(this.affectRepriceElementsSelectA[k]);
			if (elemRef) {
				elemRef.onchange = new Function("botMgr.showRepriceAlert();");
				this.originalRepriceValuesSelectA[k] = elemRef.options.selectedIndex;
			}
		}
		// init
	}

	this.behaviorCheckIntrastitial = function() {
			var elem = getRef('htlchgbotForm');
			if (elem)
				elem.onsubmit = checkSearch; //this function is defined in matrix_hotel.js; it prevents another search from being submitted while current search is still being processed
	}

	this.addBehavior = function(botsRef, bots) {
		dlog.alert("addBehavior() ");
		if (!bots) {dlog.alert("no bots element!"); return;}
		this.behaviorBotForms(botsRef, false); // general field behavior
		for (var i = 0; i < bots.length; i++) {
			var bId = bots[i].id;
			dlog.alert("bots["+i+"]="+bId);
			this.behaviorLinkSubmit(bId);
			this.behaviorLocationType(bId);
			this.behaviorFlightType(bId);
			this.behaviorDates(bId);
			this.behaviorDatesWithCalendar(bId);
			this.behaviorCalendar(bId);
			this.behaviorTravelers(bId);
			this.behaviorDisplayTravelers(bId);
			this.behaviorExpandOptions(bId);
			this.behaviorFlightOptions(bId);
			this.behaviorSearchBy(bId);
			this.behaviorSpecificHotel(bId);
			this.behaviorBookBy(bId);
			this.behaviorSavedLocation(bId);
			this.behaviorClearStop(bId);
			this.behaviorCheckIntrastitial();
			if (getRef('errorClickReprice')) {
				this.behaviorRepriceAlert(bId);
			}
			if (this.hasClass(bots[i], 'active')) {
				this.bId = bots[i].id;
			}
		}
		// Reselect the last/current selected product. In case of reloads and back buttons.
		var elemRef = getRef(this.navProductSelected + 'FlightType');
		if (elemRef) {
			var elemList = elemRef.getElementsByTagName('input');
			for (var j=0; j<elemList.length; j++)
			{
				if (elemList[j].checked) {
					this.gotoFlightType(elemList[j]);
					break;
				}
			}
		} else {
			this.setProduct(this.navProductSelected);
		}
		this.behaviorAddAnotherFlight();
		this.behaviorChildrenAge(this.PRODUCTID_WITH_CHILDRENAGE);
		this.behaviorChildrenAge(this.PRODUCTID2_WITH_CHILDRENAGE);
		this.behaviorChildrenAge(this.PRODUCTID3_WITH_CHILDRENAGE);
		//this.setFormFocus();
	}
	/* end: BEHAVIORS */


	// construct one botBox with all its nav and bots
	this.construct = function(botId) {
		dlog.alert("construct(): botId=>"+botId+"<");
		this.bId = botId;
		//this.loadState();//from Cookie
		var botsRef = getRef(this.bId+'Bots');
		var bots = this.getBotArray(botsRef);
		this.addBehavior(botsRef, bots);//to all bots' forms and their fields
		// add all found bots to the list
		this.botRefs = this.botRefs.concat(bots);

		dlog.alert("airOriginValue: '" + this.airOriginValue +"'");
		dlog.alert("Bot: NEW instantiated: " + this.bId);
	}

	this.init = function() {
		if (!this.initialized) {
			this.initialized = true;
			dlog.alert("botMgr.init()...");
			for (var i=0; i < this.botBoxIds.length; i++) {
				//this.hideElement(getRef(this.botBoxIds[i]));
				this.construct(this.botBoxIds[i]);
				//this.showElement(getRef(this.botBoxIds[i]));
			}
			dlog.alert("botMgr.init() end. bId=" +this.bId+ "<br />=====================");
		}
		else
			this.setFormFocus();
		// IE needs this to run after page load. always executed.
		this.behaviorProductNav();
		// single botBox pages. refresh for IE.
		var botsRef = getRef('Bots');
		this.behaviorBotForms(botsRef, true); // need to reset some fields
	}
}


function getRef(elemId) {
	var element = document.getElementById(elemId);
	if (!element) return null;
	return element;
}

function arrayIndexOf(arr,bId) {
	// array.indexOf only works in javascript 1.5, so here's the long way to do indexOf
	var j = -1;
	for (var i=0; i<arr.length; i++) {
		if (arr[i][0]==bId) {
			return i;
		}
	}
	return j;
}

function getInnerArray(arr,bId) {
	var j = arrayIndexOf(arr,bId);
	if (j != -1) {
		// if bId has multiple locTypeIds (i.e. it's in the 2 dimensional array botMgr.locTypeIds) then we need to build a 1 dimensional array of those locTypeIds.
		// Length is going to be -1 because botMgr.locTypeIds[0] is the bId
		var jarr = new Array(arr[j].length-1);
		// Remember, botMgr.locTypeIds[0] is the bId so we need to start counting k at 1...
		for (var k=1; k<arr[j].length; k++) {
			// ...and subtract 1 to position it correctly in the new array
			jarr[k-1]= bId + arr[j][k];
		}
	} else {
		// if bId does not have multiple locTypeIds, just build a 1 dimensional array containing the bId only
		var jarr = new Array(1);
		jarr[0]=bId;
	}
	return jarr;
}


/* All general initialization for the page, for the bot */
function botInit(where) {
	botMgr.init();
}



//DATE FUNCTIONALITY
var today = new Date();
var thisDay = today.getDate();
var thisMonth = today.getMonth();
var thisYear = today.getFullYear();
var calendarRef = "";

function getLastFebDay (currentYear) {
	if (((thisYear % 4 == 0) && (thisYear % 100 != 0)) || (thisYear % 400 == 0))
		return 29;
	else
		return 28;
}

this.months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
this.days = [31, getLastFebDay(thisYear), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];


function changeDateWithEvent (event) {
	var evt = (event) ? event : ((window.event) ? window.event : "");
	if (evt) {
		var element = (evt.target) ? evt.target : evt.srcElement;
		//check to see if the calendar has an index (for 'multicity' calendars)
		var index = element.id.substr(element.id.length - 1);
		// pbId = passed botId
		var pbId = element.id.slice(0,(element.id.length-element.name.length));
		if (isNaN(index)) {
			botMgr.setActiveBotId(pbId);
			chgDate(element);

			//The below chunk takes the user-specified values from the changed date set and applies it to all other date sets on all orbots on the page
			//this block gets the user-specified values from the changed date set
			var fieldsets = getRef(botMgr.getActiveBotId()+"botForm").getElementsByTagName('fieldset'); //get the fieldsets of the active element's form
			var indicies = new Array(); //this should have four values when the loop below finishes
			for (var f =0; f < fieldsets.length; f++) {
				var selects = fieldsets[f].getElementsByTagName('select');
				for (var s = 0; s < selects.length; s++) {
//					//only include the start and end date and time select boxes
					if (selects[s].className.indexOf('startMonth') != -1) {
						indicies[indicies.length] = 'startMonth';
						indicies['startMonth'] = new Array();
						indicies['startMonth'][0] = selects[s].selectedIndex;
					} else if (selects[s].className.indexOf('startDay') != -1) {
						indicies[indicies.length] = 'startDay';
						indicies['startDay'] = new Array();
						indicies['startDay'][0] = selects[s].selectedIndex;
					} else if (selects[s].className.indexOf('endMonth') != -1) {
						indicies[indicies.length] = 'endMonth';
						indicies['endMonth'] = new Array();
						indicies['endMonth'][0] = selects[s].selectedIndex;
					} else if (selects[s].className.indexOf('endDay') != -1) {
						indicies[indicies.length] = 'endDay';
						indicies['endDay'] = new Array();
						indicies['endDay'][0] = selects[s].selectedIndex;
					}
				}
			}
			//this block sets the user-specified values for all date sets
			var selects = document.getElementsByTagName('select');
			for (var s = 0; s < selects.length; s++) {
				if (botMgr.hasClass(selects[s], 'startMonth')) {
					selects[s].selectedIndex = indicies['startMonth'][0];
					botMgr.appendClass(selects[s], 'changed');
				} else if (botMgr.hasClass(selects[s], 'startDay')) {
					selects[s].selectedIndex = indicies['startDay'][0];
					botMgr.appendClass(selects[s], 'changed');
				} else if (botMgr.hasClass(selects[s], 'endMonth')) {
					selects[s].selectedIndex = indicies['endMonth'][0];
					botMgr.appendClass(selects[s], 'changed');
				} else if (botMgr.hasClass(selects[s], 'endDay')) {
					selects[s].selectedIndex = indicies['endDay'][0];
					botMgr.appendClass(selects[s], 'changed');
				}
			}
		}
		else {
			changeMultiDate(element, index);
		}
	}
}

function chgDate(element) {
	var bId = botMgr.getActiveBotId();
	var startMonth = getRef(bId + 'StartMonth');
	var startDay = getRef(bId + 'StartDay');
	if (bId == "carservorigin") {
		// This is an ugly ugly hack and I hope to abstract it soon. mduhan 2005-09-16
		var endMonth = getRef("carservdestinationEndMonth");
		var endDay = getRef('carservdestinationEndDay');
		botMgr.setActiveBotId('carserv');
	} else {
		var endMonth = getRef(bId + 'EndMonth');
		var endDay = getRef(bId + 'EndDay');
	}
	dateRules(startMonth, startDay, endMonth, endDay, element);
}

//Manages all date changing rules for month and day select box changes
function dateRules(startMonth, startDay, endMonth, endDay, element) {
	if (startMonth != null && startDay != null && endMonth != null && endDay != null) {
		var formRef = getRef(botMgr.getActiveBotId()).getElementsByTagName('form');
		var tripLength = formRef[0].tripLength.value;

		var startMonthIndex = startMonth.options.selectedIndex;
		var startDayIndex = startDay.options.selectedIndex;
		var endMonthIndex = endMonth.options.selectedIndex;
		var endDayIndex = endDay.options.selectedIndex;

		var startDate = getDateObject (startMonth, startDay);
		var endDate = getDateObject (endMonth, endDay);

		var dateType = (botMgr.hasClass(element, 'startMonth') || botMgr.hasClass(element, 'startDay')) ? 'start' : 'end';

		if (startMonthIndex > endMonthIndex && startDayIndex <= endDayIndex) {
			if (dateType == 'start') {
				endMonth.options.selectedIndex = startMonthIndex;
			} else {
				startMonth.options.selectedIndex = endMonthIndex;
			}
		}
		else if (startMonthIndex > endMonthIndex && startDayIndex > endDayIndex) {
			if (dateType == 'start') {
				setNewDate (endMonth, endDay, addDays (startDate, tripLength));
			} else {
				setNewDate (startMonth, startDay, addDays (endDate, -1 * tripLength));
			}
		}
		else if (startMonthIndex == endMonthIndex && startDayIndex > endDayIndex) {
			if (dateType == 'start') {
				setNewDate (endMonth, endDay, addDays (startDate, tripLength));
			} else {
				setNewDate (startMonth, startDay, addDays (endDate, -1 * tripLength));
			}
		}
	}
}

function getDateObject (monthSelectBox,daySelectBox) {
	var monthAndYear = monthSelectBox.options[monthSelectBox.options.selectedIndex].value.split(" ");
	var month = monthAndYear[0].substr(0,3);
	var year = (monthAndYear.length > 1) ? monthAndYear[1] : thisYear;
	var day = daySelectBox.options[daySelectBox.options.selectedIndex].value;

	for (i = 0; i < months.length; i++) {
		if (months[i] == month) {
			index = i;
			break;
		}
	}
	return new Date (year, index, day);
}

function getMonthLength (month) {
	month = month.substr(0,3);
	for (i = 0; i < months.length; i++) {
		if (month == months[i]) {
			index = i;
			break;
		}
	}
	return days[i];
}

function setNewDate (monthSelectBox, daySelectBox, newDate) {
	var maxMonthYear = monthSelectBox.options[monthSelectBox.options.length - 1].value;
	maxMonthYear = maxMonthYear.split(" ");
	var maxDay = getMonthLength (maxMonthYear[0]);

	var year = newDate.getFullYear();
	var month = months[newDate.getMonth()];
	var day = newDate.getDate();
	var matchedMonth = -1;

	var matchVal = (year == thisYear) ? month : month + " " + year;
	for (i = 0; i < monthSelectBox.options.length; i++) {
		if (monthSelectBox.options[i].value == matchVal) {
			matchedMonth = i;
			break;
		}
	}
	if (matchedMonth == -1) {
		day = 1;
	}

	monthSelectBox.options.selectedIndex = Math.max (0, matchedMonth);
	daySelectBox.options.selectedIndex = day - 1;
}

function addDays (newDate, days) {
	if (!days)
		days = 0;
	var mseconds = newDate.getTime() + 86400000 * days;
	return new Date (mseconds);
}

function chooseDate(day, monthAndYear) {
	var monthAndYear = monthAndYear.split(" ");
	var month = monthAndYear[0].substr(0,3);
	var year = monthAndYear[1];
	var newDate = new Date (month + " " + day + ", " + year);
	var startMonth, startDay, endMonth, endDay, productId, calType;

	//check to see if the calendar has an index (for 'multicity' calendars)
	var index = calendarRef.substr(calendarRef.length - 1);
	if (isNaN(index))
		index = "";	 //if there is no index, clear the variable

	if (calendarRef.indexOf('Start') != -1)
		calType = "Start";
	else if (calendarRef.indexOf('End') != -1)
		calType = "End";

	productId = botMgr.getActiveBotId();
	startMonth = getRef(productId + "StartMonth" + index);
	startDay = getRef(productId + "StartDay" + index);

	if (index.length > 0) { //this is a multicity flight calendar
		setNewDate (startMonth, startDay, newDate);
		changeMultiDate(getRef(calendarRef), index);
	} else {
		if (calType == "Start") {
			if (startMonth != null && startDay != null) {
				setNewDate (startMonth, startDay, newDate);
				chgDate(startMonth);
			}
		} else {
			endMonth = getRef(productId + "EndMonth" + index);
			endDay = getRef(productId + "EndDay" + index);
			if (endMonth != null && endDay != null) {
				setNewDate (endMonth, endDay, newDate);
				chgDate(endMonth);
			}
		}
	}
}

function changeMultiDate(element, index) {
	var index = parseInt(index);
	var startMonthSB, startDaySB;

	var productId = botMgr.getActiveBotId();
	var endMonthSB = getRef(productId + 'StartMonth' + index);
	var endDaySB = getRef(productId + 'StartDay' + index);

	// We only want to iterate down, not up at present - mduhan - 2005-09-29
	//we are going to count down through the slices first
//	for (var m = index-1; m >= 1; m--) {
		//since dateRules() depends on class names, we need to make sure then current date set has 'end' classes
//		botMgr.swapClasses(endMonthSB, 'startMonth', 'endMonth');
//		botMgr.swapClasses(endDaySB, 'startDay', 'endDay');

		//the 'start' slice is always the one previous to the current one
//		startMonthSB = getRef(productId + 'StartMonth' + m);
//		startDaySB = getRef(productId + 'StartDay' + m);
		//change the classes
//		botMgr.swapClasses(startMonthSB, 'endMonth', 'startMonth');
//		botMgr.swapClasses(startDaySB, 'endDay', 'startDay');

		//change the dates
//		dateRules(startMonthSB, startDaySB, endMonthSB, endDaySB, endMonthSB);

		//since we are working backwards through the slices, set the previous month/day to the current
//		endMonthSB = startMonthSB;
//		endDaySB = startDaySB;
//	}
	botMgr.swapClasses(endMonthSB, 'endMonth', 'startMonth');
	botMgr.swapClasses(endMonthSB, 'endDay', 'startDay');

	startMonthSB = getRef(productId + 'StartMonth' + index);
	startDaySB = getRef(productId + 'StartDay' + index);
	for (var n = index+1; n <= 6; n++) {
		//since dateRules() depends on class names, we need to make sure then current date set has 'start' classes
		botMgr.swapClasses(startMonthSB, 'endMonth', 'startMonth');
		botMgr.swapClasses(startDaySB, 'endDay', 'startDay');

		//the 'end' slice is always the one after to the current one
		endMonthSB = getRef(productId + 'StartMonth' + n);
		endDaySB = getRef(productId + 'StartDay' + n);
		//change the classes
		botMgr.swapClasses(endMonthSB, 'startMonth', 'endMonth');
		botMgr.swapClasses(endDaySB, 'startDay', 'endDay');

		//change the dates
		dateRules(startMonthSB, startDaySB, endMonthSB, endDaySB, startMonthSB);

		//since we are working forward through the slices, set the start month/day to the current
		startMonthSB = endMonthSB;
		startDaySB = endDaySB;
	}
}

/* Tab JS event to submit bot form to capture field values */
function qsToTab(tab) {
	dlog.alert("qsToTab('"+tab+"')");
	botMgr.setSearchType(tab);
	clickSubmit("expand");
	return false;
}
function clickSubmit(hiddenValue) {
	dlog.alert("clickSubmit('"+hiddenValue+"')");
	var f = getRef(botMgr.getActiveBotId()+botMgr.FORM_NAME);
	if (f) {
		f.searchMethodHidden.value = hiddenValue;
		if (hiddenValue=='expand')
			botMgr.disableUnchanged();
		f.submit();
	}
}


/***********************************************************************************************/
/*BEGIN: Orbot DHTML calendar functionality*/
//PLEASE NOTE:		this code expects the calendar to run in an iframe on the page.  References to parent (the document
//											where the iframe resides) will break if this criteria is not met.

//calendar object (singleton)
//  This variable references the calendar object.  The singleton design pattern - used to ensure
//  a class has only one instance and a global point to access it - is implemented using an anonymous
//  constructor.  It handle communication between the calendar (currently implemented for use in an
//  iframe) and the parent page.
var calendar = new function() {
	this.MONTHS = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
this.DAYS_BY_MONTH = [31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
	this.MAX_MONTH = this.MONTHS.length - 1;
	this.MIN_MONTH = 0;
	this.ARROW_PREV = '<img class="arrowPrevious" src="http://www.orbitz.com/site/img/chrome/buttons/calendarPrevious.gif" onclick="parent.calendar.showPrevMonth();" />';
	this.ARROW_NEXT = '<img class="arrowNext" src="http://www.orbitz.com/site/img/chrome/buttons/calendarNext.gif" onclick="parent.calendar.showNextMonth();" />';
	this.WEEKS = '<tr class="daysHeader"><td>S</td><td>M</td><td>T</td><td>W</td><td>T</td><td>F</td><td>S</td></tr>';
	this.CLOSE_BAR = '<div class="closeBar"><a href="javascript:parent.botMgr.hideCalendar();">Close</a></div>';

	this.month; //the current month
	this.year; //the current month's year
	this.hasPrev; //has a month preceding it
	this.hasNext; //has a month following it
	
	this.calendarVisible; //boolean indicating if the calendar is currently shown
	this.calendarFocused; //boolean indicating if the calendar is currently focused
	this.dateFieldFocused; //boolean indicating if the date field is currently focused
	this.eventElement; //element that called the calendar
	this.storedDateObj; //the stored date for calendar persistency (initially set to today)
	this.userStartDateObj; //start date from user as a date object
	this.userEndDateObj; //end date from user as a date object
	this.eventDateObj; //active date field's date as a date object
	this.documentRef; //document inside the iframe
	this.calendarRef; //<div> in the iframe holding the calendar table markup
	this.windowRef; //the window containing the orbot
	this.containerDivRef; //<div> holding the iframe
	this.xoffset = 70;	 //magic offset that puts the calendar beside the date field
	this.yoffset = -20;	 //magic offset that aligns the calendar vertically with the date field
		
	this.today; //date object for today's date
	this.maxDate; //date object for the max booking date
	
	//initialize the calendar
	this.init = function (windowRef, docRef, calRef, dateToday, dateMax) { log.debug('calendar.init(' + windowRef + ', ' + docRef + ', ' + calRef + ', ' + dateToday + ', ' + dateMax +')');
		this.calendarVisible = false;
		this.calendarFocused = false;
		this.dateFieldFocused = false;
		this.eventElement;
		this.storedDateObj = new Date(dateToday);
		this.userStartDateObj = null;
		this.userEndDateObj = null;
		this.eventDateObj = null;
		this.documentRef = docRef;
		this.calendarRef = calRef;
		this.windowRef = windowRef;
		this.containerDivRef = document.getElementById('calDiv');

		this.xPos = botMgr.getXPosition(getRef('calDiv'));
		this.yPos = botMgr.getYPosition(getRef('calDiv'));
		
		this.today = new Date(dateToday);
		this.maxDate = new Date(dateMax);
		
		botMgr.hideCalendar();
		this.behaviorCalendarFocus(); //apply a behavior to the body of the calendar
	} //this.init()
	
	this.behaviorCalendarFocus = function () { log.debug('calendar.behaviorCalendarFocus()');
		this.documentRef.onmousedown = botMgr.setCalFocus;
		document.onmousedown = botMgr.clearCalFocus;
		}

	//writes the new markup for calendar to the div ' + ', ' + 
	this.update = function(month, year, hasPrev, hasNext) { log.debug('calendar.update('+month+', '+year+', '+hasPrev+', '+hasNext+')');
		this.month = month;
		this.year = year;
		this.hasPrev = hasPrev;
		this.hasNext = hasNext;
		
		//build header
		var arrow, headerClass, header; //variables to hold the arrow markup, header class name, and header markup
		if (this.hasPrev && this.hasNext) {arrow = this.ARROW_PREV + this.ARROW_NEXT; headerClass = "";}
		else if (this.hasPrev && !this.hasNext) {arrow = this.ARROW_PREV; headerClass = 'hasPrevious';}
		else if (!this.hasPrev && this.hasNext) {arrow = this.ARROW_NEXT; headerClass = 'hasNext';}
		header = '<thead><tr class="monthHeader" ><th colspan="7">' + arrow + '<div class="' + headerClass + '">' + this.MONTHS[this.month] + ' ' + this.year + '</div></th></tr>' + this.WEEKS + '</thead>';		
		
		//build id of highlighed day
		var dateObj, highlightId;
		if (this.eventElement.className.indexOf('end') != -1) {//user clicked in the end date
			if (this.userEndDateObj != null) dateObj = this.userEndDateObj; //end date is filled so highlight
			else if (this.userStartDateObj != null) dateObj = this.userStartDateObj; //end date is empty so highlight start date
		}
		else if (this.userStartDateObj != null)
			dateObj = this.userStartDateObj; //user clicked in start date so highlight it
		if (dateObj) highlightId = dateObj.getMonth() + '_' + dateObj.getDate() + '_' + dateObj.getFullYear();

		//build days
		var days = ""; //string to hold the days markup
		var firstDay = this.getFirstDay(); //integer [0-6] of the day of the week for the first day of the month
		var totalDays = this.getTotalDays(this.month, this.year);
		var dayCounter = 1; //counter to track the current month's days
		var dayFill = false; //boolean to indicated if the current's months days are being filled

		days += '<tbody>';
		for (var i = 0; i < 6; i++) { //six rows for months that span six weeks
			days += '<tr class="days">';
			for (var j = 0; j <= 6; j++) { //seven days
				if (j == firstDay) dayFill = true; //we found the first day of the month
				if (!dayFill || dayCounter > totalDays)
					days += '<td class="none">&nbsp;</td>';
				else{
					//determine if the date being filled is after today's date, before the max date, and before the start date
					var beforeStartDate, afterCurrentDate, beforeMaxDate;
					if (this.eventElement.className.indexOf('end') >= 0 && this.userStartDateObj != null)
						beforeStartDate = this.year < this.userStartDateObj.getFullYear() || (this.year == this.userStartDateObj.getFullYear() && this.month < this.userStartDateObj.getMonth()) || (this.year == this.userStartDateObj.getFullYear() && this.month == this.userStartDateObj.getMonth() && dayCounter < this.userStartDateObj.getDate());
					afterCurrentDate = this.year > this.today.getFullYear() || (this.year == this.today.getFullYear() && this.month > this.today.getMonth()) || (this.year == this.today.getFullYear() && this.month == this.today.getMonth() && dayCounter > this.today.getDate());
					beforeMaxDate = this.year < this.maxDate.getFullYear() || (this.year == this.maxDate.getFullYear() && this.month < this.maxDate.getMonth()) || (this.year == this.maxDate.getFullYear() && this.month == this.maxDate.getMonth() && dayCounter < this.maxDate.getDate());
					
					var clickableDate = true;
					
					if (!beforeStartDate && highlightId == (this.month + '_' + dayCounter + '_' + this.year))
						days += '<td class="selected">'; //highlighted date
					else if (!beforeStartDate && this.year == this.today.getFullYear() && this.month == this.today.getMonth() && dayCounter == this.today.getDate())
						days += '<td class="today">'; //today
					else if (afterCurrentDate && beforeMaxDate && !beforeStartDate)
						days += '<td>'; //selectable date
					else {
						days += '<td class="disabled">'; //disabled date
						clickableDate = false;
					}
					if (clickableDate) days += '<a id="' + this.month + '_' + dayCounter + '_' + this.year + '" href="#" onmousedown="javascript:parent.calendar.clickDate(' + this.month + ',' + dayCounter + ',' + this.year + ');">' + dayCounter + '</a></td>';
					else days += dayCounter;
					days += '</td>';
					
					dayCounter++;
				}//else
			}//for
			days += '</tr>';
		}//for
		days += '</tbody>';

		this.calendarRef.innerHTML = '<table cellpadding="0" cellspacing="0">' + header +  days + '</table>' + this.CLOSE_BAR;
	} //this.update()

		//returns the total number of days for the calendar month/year
	this.getTotalDays = function(month, year) { log.debug('calendar.getTotalDays(' + month + ',' + year + ')');
		var returnVal;
		if (month == 1) {
			if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) returnVal = 29;
			else returnVal = 28;
	}
		else returnVal = this.DAYS_BY_MONTH[month];
		log.info('calendar.getTotalDays returned: ' + returnVal);
		return returnVal;
	} //this.getTotalDays(month, year)

	//returns an integer [0-6] representing the day of the week for the first day of the month
	this.getFirstDay = function() { log.debug('calendar.getFirstDay()');
		var firstDay = new Date(this.year, this.month, 1); //create a new date for the first of the month
		log.info('calendar.getFirstDay returned: ' + firstDay.getDay());
		return firstDay.getDay(); //return the integer indicating the day of the week
	} //this.getFirstDay()

	//moves the calendar ahead one month
	this.showNextMonth = function() { log.debug('calendar.showNextMonth()');
		var month = (this.month < this.MAX_MONTH) ? this.month + 1 : this.MIN_MONTH;
		var year = (this.month < this.MAX_MONTH) ? this.year : this.year + 1;	
		var hasPrevCal = (this.today.getFullYear() < year || (this.today.getFullYear() == year && this.today.getMonth() < month));
		var hasNextCal = (this.maxDate.getFullYear() > year || (this.maxDate.getFullYear() == year && this.maxDate.getMonth() > month));
		
		this.storedDateObj.setMonth(month);
		this.storedDateObj.setYear(year);
		this.update(month, year, hasPrevCal, hasNextCal);
	} //this.showNextMonth()
	
	//moves the calendar back one month
	this.showPrevMonth = function() { log.debug('calendar.showPrevMonth()');
		var month = (this.month != this.MIN_MONTH) ? this.month - 1 : this.MAX_MONTH;
		var year = (this.month != this.MIN_MONTH) ? this.year : this.year - 1;	
		var hasPrevCal = (this.today.getFullYear() < year || (this.today.getFullYear() == year && this.today.getMonth() < month));
		var hasNextCal = (this.maxDate.getFullYear() > year || (this.maxDate.getFullYear() == year && this.maxDate.getMonth() > month));
		
		this.storedDateObj.setMonth(month);
		this.storedDateObj.setYear(year);
		this.update(month, year, hasPrevCal, hasNextCal);
	} //this.showPrevMonth()

 //populates the input field that was clicked to reveal calendar
	this.clickDate = function(month, day, year) { log.debug('calendar.clickDate(' + month + ',' + day + ',' + year + ')');
		if (this.eventElement != null) {
			var month = new String(month + 1); //convert the index of the month to the numerical value
			month = (month.length == 1) ? '0' + month.toString() : month; //convert month to 'mm' format
			var day = new String(day);
			day = (day.length == 1) ? '0' + day.toString() : day; //convert day to 'dd' format
			var year = new String(year);
			year = year.substr(2); //convert year to 'yy' format

			this.eventElement.value = month + '/' + day + '/' + year;
			// This is a hack for GT3 because the startDate and endDate are in different components. I'd like to abstract it further. - mduhan - 2005-11-17
			if (this.eventElement.id=='carservoriginStartDate') {
				getRef('carservdestinationStartDate').value = month + '/' + day + '/' + year;
			}
			botMgr.hideCalendar();
		}
	} //this.clickDate(month, day, year)

	this.validateDate = function(dateStr) { log.debug('calendar.validateDate(' + dateStr + ')');
		var userDateObj = null;
		var valid = false;
		if (dateStr != null && dateStr != '') {
			var splitDates = dateStr.split('/');
			if (splitDates.length == 3) { //checks to make sure the date contains two forward slashes
				var userYear, userMonth, userDay;
				//make sure all values are numbers
				if (!isNaN(splitDates[0]) && !isNaN(splitDates[1]) && !isNaN(splitDates[2]))
					valid = true;
				//validate year string length
				if (valid && splitDates[2].length == 2) {
					userYear = '20' + splitDates[2];
					valid = true;
				} else if (valid && splitDates[2].length == 4) {
					userYear = splitDates[2];
					valid = true;
				} else valid = false;
				//validate month
				if (valid && (splitDates[0].length == 1 || splitDates[0].length == 2) &&	splitDates[0] > 0 && splitDates[0] < 13) {
					userMonth = splitDates[0] - 1;
					valid = true;
				} else valid = false;
				//validate day
				if (valid && (splitDates[1].length == 1 || splitDates[1].length == 2) && splitDates[1] > 0 && splitDates[1] <= this.getTotalDays(userMonth, userYear)) {
					userDay = splitDates[1];
					valid = true;
				}	 else valid = false;

				if (valid) {
					//check if the date appears before today
					if (userYear < this.today.getFullYear())
						valid = false;
					else if (userYear == this.today.getFullYear() && userMonth < this.today.getMonth())
						valid = false;
					else if (userYear == this.today.getFullYear() && userMonth == this.today.getMonth() && userDay < this.today.getDate())
						valid = false;
					//check if the date appears after the max booking date
					if (userYear > this.maxDate.getFullYear())
						valid = false;
					else if (userYear == this.maxDate.getFullYear() && userMonth > this.maxDate.getMonth())
						valid = false;
					else if (userYear == this.maxDate.getFullYear() && userMonth == this.maxDate.getMonth() && userDay > this.maxDate.getDate())
						valid = false;
				}
				if (valid) //create user date object
					userDateObj = new Date(userYear, userMonth, userDay); //create a new date object from the user supplied values
			} //if splitDates.length
		} //if dateStr
		log.info('calendar.validateDate returned: ' + userDateObj);
		return userDateObj;
	} //this.validateDate(dateStr)

	//determines if the calendar should show a specific date or the current month
	this.draw = function() { log.debug('calendar.draw()');
		this.eventDateObj = this.validateDate(this.eventElement.value); //validate the string the the date field
		if (this.eventElement.className.indexOf('end') != -1) { //the focus is in the end date field
			this.userEndDateObj = this.eventDateObj;

			var startDateField = getRef(botMgr.bId + 'StartDate');
			if (startDateField != null) this.userStartDateObj = this.validateDate(startDateField.value); //find and validate the string in the start date field	

			var isAfter = false;
			if (this.userStartDateObj != null && this.userEndDateObj != null) {
				//check if the startDate is after endDate
				if (this.userStartDateObj.getFullYear() > this.userEndDateObj.getFullYear())
					isAfter = true;
				else if (this.userStartDateObj.getFullYear() == this.userEndDateObj.getFullYear() && this.userStartDateObj.getMonth() > this.userEndDateObj.getMonth())
					isAfter = true;
				else if (this.userStartDateObj.getFullYear() == this.userEndDateObj.getFullYear() && this.userStartDateObj.getMonth() == this.userEndDateObj.getMonth() && this.userStartDateObj.getDate() > this.userEndDateObj.getDate())
					isAfter = true;
			}
			
			if (!isAfter && this.userEndDateObj != null) this.setUserDate(this.userEndDateObj); //the end date is valid so show it
			else if (isAfter || (this.userEndDateObj == null && this.userStartDateObj != null)) this.setUserDate(this.userStartDateObj); //start is after end or the start date is valid so show it
			else this.setUserDate(this.userEndDateObj); //the end date is invalid so show the stored
			}
		else { //the focus is in the start date field
			this.userStartDateObj = this.eventDateObj;
			this.setUserDate(this.userStartDateObj);
	}
	} //this.draw()

	//changes the calendar and selects the user date in the calendar OR defaults to stored month/day for invalid dates
	this.setUserDate = function(userDateObj) { log.debug('calendar.setUserDate(' + userDateObj + ')');
		var dateObj;
		
		if (userDateObj == null) dateObj = this.storedDateObj; //the user has not entered a date, so load the stored date
		else dateObj = userDateObj; //othewise, use the user date
		
		var month = dateObj.getMonth();
		var year = dateObj.getFullYear();
		var hasPrevCal = (this.today.getFullYear() < year || (this.today.getFullYear() == year && this.today.getMonth() < month));
		var hasNextCal = (this.maxDate.getFullYear() > year || (this.maxDate.getFullYear() == year && this.maxDate.getMonth() > month));
		
		this.storedDateObj.setMonth(month);
		this.storedDateObj.setYear(year);

		this.update(month, year, hasPrevCal, hasNextCal);
	} //this.setUserDate()
} //var calendar
/*END: Orbot DHTML calendar functionality*/
/***********************************************************************************************/
