/*<script>*/
/*
 * This module purposely does not bog the client down with null continuous checks due to initial checks.
 * No client-side JavaScript should be modifying the HTML QQ DOM, unless you want errors.
 * Also, you will notice there aren't as many null checks in here as could be from the data we receive from Disney.
 * The production team know certain things that must be set correctly for this to work.
 * If something is broken in this JS it is because they forgot something vital, and should not be ran without.
 *
 * Business Units: It may be proper to ensure the selectedIndex value matches the index/key in the BU array, but this is time consuming
 *    and a waste of resources due to the HTML controlled by us.
 *
 * Components: If the SQQComponent exists in the object, the value is a valid array with length > 0; not making additional checks for this
 */
 
function DisneyQuickQuote() {
	// "cur*" variables should/can change, "qq*" variables should not
	this.arrAttributes = {
		'curOpenCalendar': -1,			// if a calendar is open this will be the # in our qqCalendars array, -1 means none open
		'curOpenCalendarBtn': '',		// the ID of the button that opened the calendar
		'fAfterInit': '',				// if function exists, fires after init is completed, before qq displays
		'qqCalendarPadding': 10,		// the padding around the calendar for where a click will not close the calendar
										// ** this should encompass the calendar button, or it will close when clicked **
										// if no padding is needed, change the event function to include a safe zone
										// for the calendar button image as well
		'qqCalendars': Array(),			// array of all available calendar objects
		'qqElement': 'DisneyQuickQuote',	// the qq container element ID, as a string
		'qqTravelMinLength': Array(),	// array of integers for minimum travel length; ID matches the calendar it
										// interfaces with, e.g. qqTravelMinLength[2] relative to qqCalendars[2]
		'qqWidth': 220		// width of the qq container/please wait layer
	};
	
	// array of supported SQQComponents for processing (not rendering)
	// we also need to process SQQBusinessUnit and SQQProductOption
	this.arrSupport = [
		'SQQTravelDates',
		'SQQPartyMix',
		'SQQDropDownMulti',
		'SQQDropDown',
		'SQQTextBox',
		'SQQGrouping',
		'SQQBusinessUnit',
		'SQQProductOption'
	];
	
	this.objData = null; // storage of json data
	this.autoCompleteObj = new Array(); 
}

// @param aStr contain all the autoComplete strings
// @param oText is the text box used
// @param oDiv is the div showing the suggested text
DisneyQuickQuote.AutoComplete = function(strParent, aStr, oText, oDiv){
	// initialize member variables
	this.parent = strParent;
	this.oText = oText;
	this.oDiv = oDiv;
	this.arr = aStr;
	this.arSaved=[];   
	this.curCount=0;
	this.selectedIndex = -1;

	// attach handlers to the text-box
	oText.AutoComplete = this;
	oText.onkeyup = DisneyQuickQuote.AutoComplete.prototype.onKeyUp;
	oText.onblur = DisneyQuickQuote.AutoComplete.prototype.onTextBlur;
};


DisneyQuickQuote.AutoComplete.prototype.onKeyUp = function(e){
	var code;
	var prev = -1;
	if(!e){
		var e = window.event
	}	
	code = e.keyCode;

	switch(code){
		case(37):
			//Left Arrow
			break;
		case(39):
			//Right Arrow
			break;
		case(38):
			//Up Arrow
			if(this.AutoComplete.oDiv.style.visibility == 'visible'){
				if(this.AutoComplete.oDiv.hasChildNodes()){
					var children = this.AutoComplete.oDiv.childNodes;
					if(this.AutoComplete.selectedIndex < 0 || this.AutoComplete.selectedIndex >= children.length){
						this.AutoComplete.selectedIndex = children.length-1;
					}
					else if(this.AutoComplete.selectedIndex == 0){
						prev = this.AutoComplete.selectedIndex;
						this.AutoComplete.selectedIndex = children.length-1;
					}
					else{
						prev = this.AutoComplete.selectedIndex;
						this.AutoComplete.selectedIndex -= 1;
					}
					children.item(this.AutoComplete.selectedIndex).className = "AutoCompleteHighlight";
					if(prev > -1){
						children.item(prev).className ='AutoCompleteBackground';
					}
					//children.item(this.AutoComplete.selectedIndex).innerHTML = this.AutoComplete.selectedIndex;
					this.AutoComplete.oText.value = children.item(this.AutoComplete.selectedIndex).innerHTML;
				}
			}
			break;
		case(40):
			//Down Arrow
			if(this.AutoComplete.oDiv.style.visibility == 'visible'){
				if(this.AutoComplete.oDiv.hasChildNodes()){

					var children = this.AutoComplete.oDiv.childNodes;
					if(this.AutoComplete.selectedIndex < 0 || this.AutoComplete.selectedIndex >= children.length){
						this.AutoComplete.selectedIndex = 0;
					}
					else if(this.AutoComplete.selectedIndex == children.length-1){
						prev = this.AutoComplete.selectedIndex;
						this.AutoComplete.selectedIndex = 0;
					}
					else{
						prev = this.AutoComplete.selectedIndex;
						this.AutoComplete.selectedIndex += 1;
					}
					children.item(this.AutoComplete.selectedIndex).className = "AutoCompleteHighlight";
					if(prev > -1){
						children.item(prev).className ='AutoCompleteBackground';
						//children.item(prev).innerHTML = prev+"D";
					}
					//children.item(this.AutoComplete.selectedIndex).innerHTML = this.AutoComplete.selectedIndex;
					this.AutoComplete.oText.value = children.item(this.AutoComplete.selectedIndex).innerHTML;
				}
			}
			break;
		default:
			this.AutoComplete.getMatches();
			this.AutoComplete.selectedIndex = -1;

			break;
	}
}

//loopback until a match is found.
// @param txt is the compared txt
DisneyQuickQuote.AutoComplete.prototype.verify = function(txt){
	var subArr;
	var len = txt.length;

	if(txt){
		subArr = this.arSaved[len-1];
		if(subArr){
			if(subArr.length > 0){
				bool = false;
				for(i = 0; i < subArr.length; i++){				
					var strTemp = this.arr[subArr[i]];
					if(strTemp.substring(0, len).toLowerCase() != txt.toLowerCase()){
						bool = true;
						break;
					}
				}
				if(bool){
					if(this.arSaved[txt.length-1].length > 0){
						this.arSaved[txt.length-1] = [];
						this.curCount = this.curCount - 1;
					}
					if(len > 0){
						this.verify(txt.substring(0, len-1));
					}
				}
			}
		}
	}
};

//add new matches to arSaved array
// @param str is the txt to be compare with
// @param subArray nodes of this array is used to compare with the true list
DisneyQuickQuote.AutoComplete.prototype.addArr = function(str, subArray){
	var arr=[];
	if(str){
		if(subArray){
			if(subArray.length != 0){
				for(i = 0; i < subArray.length; i++){
					if(str.toLowerCase() == this.arr[subArray[i]].substring(0, str.length).toLowerCase()){
						arr[arr.length] = subArray[i];
					}
				}
			}			
		}
		else{
			if(this.arSaved.length == 1){
				for(i = 0; i < this.arr.length; i++){
					if(str.toLowerCase() == this.arr[i].substring(0, str.length).toLowerCase()){
						arr[arr.length] = i;
					}
				}		
			}
		}		
		if(arr.length > 0){
			this.curCount = this.curCount + 1;
		}
		this.arSaved[str.length-1] = arr;
	}
};

//function first verify current array with new text.
//function then add new array to arSaved if necessary then display the result to screen
DisneyQuickQuote.AutoComplete.prototype.getMatches = function(){
	var txt = this.oText.value;
	var array = this.arr;
	
	//clear all
	if(txt.length == 0){
		this.arSaved = [];
		this.curCount = 0;
	}
	//init case
	else if(this.arSaved.length == 0){
		var subArray = [];
		for(i = 0; i < array.length; i++){
			if(txt.toLowerCase() == array[i].substring(0, txt.length).toLowerCase()){
				subArray[subArray.length] = i;
			}
		}
		if(subArray.length != 0){
			this.curCount+=1;
		}
		this.arSaved[this.arSaved.length] = subArray;
	}
	//continuous case
	else{
		if(this.arSaved.length > txt.length){

			//remove extra element from arSaved
			this.arSaved.splice(txt.length, this.arSaved.length - txt.length);

			if(this.curCount > txt.length){
				this.curCount = txt.length;
			}
		}
		
		this.verify(txt.substring(0, this.arSaved.length));
		
		if(this.curCount == 0 && this.arSaved[0].length == 0){
			this.arSaved.splice(1,this.arSaved.length-1);
		}

		var len = this.curCount;
		for(k = len;  k < txt.length; k++){
			this.addArr(txt.substring(0,k+1), this.arSaved[k-1]);
		}
	}

	//removing elements
	while(this.oDiv.hasChildNodes()){
		this.oDiv.removeChild(this.oDiv.firstChild);
	}

	//add Childs to Div
	if(this.arSaved.length > 0){
		var lastArray = this.arSaved[this.arSaved.length-1];
		
		if(lastArray && lastArray.length > 0){
			for(i = 0; i < lastArray.length; i++){
				var oDiv = document.createElement('div');
				this.oDiv.appendChild(oDiv);
				oDiv.innerHTML = this.arr[lastArray[i]];
				oDiv.onmousedown = DisneyQuickQuote.AutoComplete.prototype.onDivMouseDown;
				oDiv.onmouseover = DisneyQuickQuote.AutoComplete.prototype.onDivMouseOver;
				oDiv.onmouseout = DisneyQuickQuote.AutoComplete.prototype.onDivMouseOut;
				oDiv.AutoComplete = this;

			}
			this.oDiv.style.visibility = "visible";
			this.oText.className = '';
			this.oText.setAttribute("autoMatch",true);

		}
		else{
			this.oDiv.style.visibility = "hidden";
			this.oText.className = 'redFlag';
			this.oText.setAttribute("autoMatch", false);
		}
	}

};

//function hide the suggestive div and check the current text with the real list
DisneyQuickQuote.AutoComplete.prototype.onblur = function()
{
	this.oDiv.style.visibility = "hidden";

	//trim text
	this.oText.value = this.oText.value.replace(/^\s+|\s+$/g,"");
	this.selectedIndex = -1;
	
	var textID =  this.oText.id;
	textID = textID.substring(0, textID.lastIndexOf("_Text"));
	var selId = this.parent + '_'+ textID;
	
	var selEl  = document.getElementById(selId);
	if(selEl){
		selEl.selectedIndex = -1;

		for(var i = 0; i < this.arr.length; i++){
			var strTemp = selEl.options[i].text;
			if(strTemp.toLowerCase() == this.oText.value.toLowerCase()){
				selEl.selectedIndex = i;
			}
		}
	}
	
	if(this.oText.value.length > 0){
		var bool = false;
		for(var i = 0; i < this.arr.length; i++){
			if(this.oText.value.toLowerCase() == this.arr[i].toLowerCase()){
				bool = true;
			}
		}
		if(bool == false){
				this.oText.className = 'redFlag';
				this.oText.setAttribute("autoMatch", false);
		}
	}
	else{
			this.oText.className = '';
			this.oText.setAttribute("autoMatch", true);
	}
};

DisneyQuickQuote.AutoComplete.prototype.onDivMouseDown = function()
{
	this.AutoComplete.oText.value = this.innerHTML;
};

DisneyQuickQuote.AutoComplete.prototype.onDivMouseOver = function()
{
	if(this.AutoComplete.oDiv.hasChildNodes()){
		var children = this.AutoComplete.oDiv.childNodes;
		for(var i = 0; i < children.length; i++){		
			var child = children.item(i);
			if( child == this){
				this.AutoComplete.selectedIndex = i;
				child.className ='AutoCompleteHighlight';
			}
			else{
				child.className ='AutoCompleteBackground';
			}
		}
	}
};

//change className to provide css changes
DisneyQuickQuote.AutoComplete.prototype.onDivMouseOut = function()
{
	this.className = "AutoCompleteBackground";
};

DisneyQuickQuote.AutoComplete.prototype.onTextBlur = function()
{
	this.AutoComplete.onblur();
};
//*****END AUTOCOMPLETE **********/

//Function reads the elements relation off the object.Data.Groups object with the name "Custom Reset Elements"
//elementsID contain the selector element and the targeted element
DisneyQuickQuote.prototype.setResetTag = function (){

	//get element
	var objGroups = this.objData.Groups["Custom Reset Elements"];
	if (objGroups != null){
		if(objGroups.length != 0){
			//loop thru element
			for (i = 0; i < objGroups.length; i++){
				var that = this;
				var elSelector="";
				var elTarget="";

				//get values
				var elementsID = objGroups[i].l.split(':');
				var action = objGroups[i].d;
				
				//set the selected element and the target element
				elSelector = document.getElementById(elementsID[0]);
				elTarget = document.getElementById(elementsID[1]);
				
				//if both exist
				if(elSelector && elTarget){
				
					if(action=="change"){
						if(!elSelector.onChangeFlag){
							elSelector.onChangeFlag = elementsID[1];
						}
						else{
							elSelector.onChangeFlag = elSelector.onChangeFlag + "," + elementsID[1];
						}
						this._handleResetElementToDefault(elSelector, action);
					}
				}
			}
		}
	}
};

DisneyQuickQuote.prototype._handleResetElementToDefault = function(el, action){
	var that = this;
	this.addEvent(el, action, function(){that.resetElementToDefault(el, action)}, false);
};

//function reset the target Element to the default values based on the type of the elements
//more type can be added as needed
//customTag holds the ID of all the elements associated with the target element

DisneyQuickQuote.prototype.resetElementToDefault = function (el, action){
  if(el){
	switch (action){
	    case ("change"):
		if(el.onChangeFlag){
		    var arr = el.onChangeFlag.split(',');
		    for(i = 0; i < arr.length; i++){
		        var resetEl = document.getElementById(arr[i]);
			if(resetEl){
			    //reseting to default values here
			    switch(resetEl.type){
				case "text":
				    resetEl.value="";
				    resetEl.setAttribute('autoMatch','true');
				    resetEl.className='';
				    break;
				case "select-one":
				    resetEl.selectedIndex = 0;
				    break;
				default:
				    //Do nothing
				    break;
			    }
			}
		    }
		}
	    break;
	    case ("click"):
		break;
	    default:
		break;
	}
  }
};

// custom function to handle loops that executes a function on all returns objects
DisneyQuickQuote.prototype.loopElementsWithCallback = function( nodeElements, funcCallback ) {
	if ( !nodeElements || !funcCallback ) {
		return false;
	}
	
	//var nodeElements = nodeRoot.getElementsByTagName( strTagName );
	if ( typeof( nodeElements ) === 'object') {
		var intLength = ( nodeElements.length - 1 );
		
		if ( intLength < 0 ) {
			return false;
		}
		
		do {
			funcCallback( nodeElements[intLength] );
		} while ( intLength-- );
	} else {
		nodeElements = Array.prototype.slice.call( nodeElements );
		
		while ( nodeElements.length > 0 ) {
			funcCallback( nodeElements.pop() );
		}
	}
	
	return true;
};


// errors are displayed in our please wait layer
// @param strMessage string - the error text that will be placed in the please wait layer
DisneyQuickQuote.prototype.displayError = function( strMessage ) {
	document.getElementById( 'qqPleaseWaitLabel' ).innerHTML = strMessage;
	document.getElementById( this.arrAttributes.qqElement ).style.display = 'none';
	document.getElementById( 'qqPleaseWait' ).style.display = 'block';
	return false;
};

// controller of the submission-related errors, utilizes this.displayMessage if the browser supports it
// @param strElement string - element id, used for ie6 to display message underneath the submit button
// @param strMessage string - the error text that will be placed in the notification
DisneyQuickQuote.prototype.displaySubmitError = function( strElement, strMessage ) {
	this.displayMessage( strMessage, this.objData.Prop.errors.strHead, this.objData.Prop.errors.strCloseLabel );
	
	return false;
};

// displays a notification to the client, creates the div if it doesn't exist
// @param strMessage string - the error text that will be placed in the please wait layer
// @param strTitle string - the title text
// @param strClose string - the close button text
// @param bHideInnerBox boolean - this is mostly used for IE6, it hides the inner box, only displaying the background
DisneyQuickQuote.prototype.displayMessage = function( strMessage, strTitle, strClose, bHideInnerBox ) {
	var nodeQQ = document.getElementById( this.arrAttributes.qqElement );
	var nodeWarn = document.getElementById( 'qqWarning' );
	if ( typeof( document.body.style.maxHeight ) == 'undefined' ) {
		this.loopElementsWithCallback( nodeQQ.getElementsByTagName( 'select' ), function( node ) {
			node.style.visibility = 'hidden';
		} );
	}
	
	if ( !nodeWarn ) {
		var that = this;
		nodeWarn = document.createElement( 'div' );
		nodeWarn.id = 'qqWarning';
		nodeWarn.style.display = 'block';
		
		var nodeBg = nodeWarn.appendChild( document.createElement( 'div' ) );
		nodeBg.className = 'qqWarningBackground';
		nodeBg.id = 'qqWarningBackground';
		nodeBg = undefined;
		
		var nodeContainer = nodeWarn.appendChild( document.createElement( 'div' ) );
		nodeContainer.className = 'qqWarningContainer';
		nodeContainer.id = 'qqWarningContainer';
		
		if ( document.all ) {
			nodeContainer.style.position = 'relative';
		}
		
		var nodeBox = nodeContainer.appendChild( document.createElement( 'div' ) );
		nodeBox.className = 'qqWarningBox';
		nodeContainer = undefined;
		
		var nodeText = nodeBox.appendChild( document.createElement( 'div' ) );
		nodeText.id = 'qqWarningTitle';
		nodeText.innerHTML = '&nbsp;';
		nodeText = undefined;
		
		nodeText = nodeBox.appendChild( document.createElement( 'div' ) );
		nodeText.id = 'qqWarningMessage';
		nodeText.innerHTML = '&nbsp;';
		nodeText = undefined;
		
		nodeText = nodeBox.appendChild( document.createElement( 'div' ) );
		nodeText.id = 'qqWarningClose';
		nodeText.innerHTML = 'Close';
		this.addEvent( nodeText, 'click', function() { that.hidePopup( 'qqWarning', 'click' ); }, false );
		nodeText = undefined;
		
		nodeBox = undefined;
		nodeQQ.appendChild( nodeWarn );
	} else {
		nodeWarn.style.display = 'block';
	}
	
	if ( bHideInnerBox ) {
		document.getElementById( 'qqWarningContainer' ).style.visibility = 'hidden';
	} else {
		document.getElementById( 'qqWarningContainer' ).style.visibility = 'visible';
	}
		
	document.getElementById( 'qqWarningTitle' ).innerHTML = strTitle;
	document.getElementById( 'qqWarningMessage' ).innerHTML = strMessage;
	document.getElementById( 'qqWarningClose' ).innerHTML = strClose;
	
	if ( document.all ) {
		if ( typeof( document.body.style.maxHeight )== 'undefined' ) {
			nodeWarn.style.display = 'block';
			nodeWarn.style.height = document.getElementById( this.arrAttributes.qqElement ).offsetHeight + 'px';
			document.getElementById( 'qqWarningBackground' ).style.height = nodeWarn.offsetHeight + 'px';
			document.getElementById( 'qqWarningBackground' ).style.width = nodeWarn.offsetWidth + 'px';
		}
		
		nodeWarn.style.display = 'block';
		document.getElementById( 'qqWarningContainer' ).style.top = ( Math.floor( nodeWarn.offsetHeight / 2 ) - Math.floor( document.getElementById( 'qqWarningContainer' ).offsetHeight / 2 ) ) + 'px';
	} else {
		nodeWarn.style.display = 'block';
	}
};

// function executed once the page loads
DisneyQuickQuote.prototype.startOnload = function() {
	if ( !this.arrAttributes.qqElement ) {
		return this.displayError( 'Unable to find the Disney Quick Quote placeholder.' );
	}
	
	// display our please wait layer, and create our container
	this.displayPleaseWait( true );
	
	// we don't have a "var" in front, because setTimeout() will not scope, our execute function frees the memory allocation
	that = this;
	// start our requests, this is in here to ensure the display of our please wait layer
	setTimeout( 'that.execute();', 1 );
	
	return true;
};

// this function's purpose is to call our functions and free up memory
// not hold onto functions by calling the next one inside of each
DisneyQuickQuote.prototype.execute = function() {
	that = undefined;
	
	this.requestPage();
	this.requestBusinessRules();
	
	// make sure our objects were created
	if ( this.objData && this.objData.Prop ) {

		this.processBusinessRules();
		this.setResetTag();
	} else {
		return this.displayError( 'Unable to find the Disney Quick Quote object data.' );
	}
	
	if ( typeof( this.arrAttributes.fAfterInit ) == 'function' ) {
		this.arrAttributes.fAfterInit();
	}
	
	this.displayPleaseWait( false );
	
	return true;
};


// display or hide our please wait layer, create QQ container if it doesn't exist
// @param bDisplay boolean - display (true)/hide (false) the please wait layer, qq container gets opposite
DisneyQuickQuote.prototype.displayPleaseWait = function( bDisplay ) {
	var nodeQQ = document.getElementById( this.arrAttributes.qqElement );
	var nodePleaseWait = document.getElementById( 'qqPleaseWait' );
	
	// if our container doesn't exist, create it
	if ( !nodeQQ ) {
		nodeQQ = document.createElement( 'div' );
		nodeQQ.id = this.arrAttributes.qqElement;
		
		document.body.appendChild( nodeQQ );
	}
	
	if ( bDisplay ) {
		// this should never happen, but we don't want to accidentally recreate this layer
		if ( nodePleaseWait ) {
			nodeQQ.style.display = 'none';
			nodePleaseWait.style.display = 'block';
		} else {
			nodePleaseWait = document.createElement( 'div' );
			nodePleaseWait.id = 'qqPleaseWait';
			
			// if a width is specified, restrain our please wait layer
			if ( this.arrAttributes.qqWidth && this.arrAttributes.qqWidth > 0 ) {
				nodePleaseWait.style.width = this.arrAttributes.qqWidth + 'px';
				nodeQQ.style.width = this.arrAttributes.qqWidth + 'px';
			}
			
			nodePleaseWait.style.display = 'block';
			
			var nodeContainer = nodePleaseWait.appendChild( document.createElement( 'div' ) );
			nodeContainer.className = 'qqPleaseWaitContainer';
			
			var nodeText = nodeContainer.appendChild( document.createElement( 'p' ) );
			nodeText.className = 'qqPleaseWaitLabel';
			nodeText.id = 'qqPleaseWaitLabel';
			nodeText.innerHTML = 'Please wait...';
			
			nodeText = undefined;
			nodeContainer = undefined;
			
			nodeQQ.style.display = 'none';
			// insert the please wait layer before the QQ container
			nodeQQ.parentNode.insertBefore( nodePleaseWait, nodeQQ );
		}
	} else {
		nodePleaseWait.parentNode.removeChild( nodePleaseWait );
		nodeQQ.style.display = 'block';
	}
	
	nodePleaseWait = undefined;
	nodeQQ = undefined;
	
	return true;
};

// wait until page has loaded the DOM until moving on with the business rules
DisneyQuickQuote.prototype.requestPage = function() {
	document.getElementById( this.arrAttributes.qqElement ).innerHTML = '<div id="DCL2SQQProperties_BookingGenie_en_US" class="SQQProperties"><div id="DCL_Container" class="SQQBusinessUnit"><div class="SQQBUProductOptions"><form action="#" onsubmit="return false;"><div id="DCL_DCL2CruisesSQQProductOption_InputContainer" class="SQQProductOptionContainer"><div id="DCL_DCL2CruisesSQQProductOption_InputDisplay" class="SQQProductOptionOnContainer"><input type="radio" class="SQQProductOptionInput" name="BusinessType" id="DCL_DCL2CruisesSQQProductOption" value="DCL2Cruises" checked="checked" /><span class="SQQProductOptionInputLabel"><label for="DCL_DCL2CruisesSQQProductOption">Cruise Search</label></span></div></div><div id="DCL_DCL2ReservationSQQProductOption_InputContainer" class="SQQProductOptionContainer"><div id="DCL_DCL2ReservationSQQProductOption_InputDisplay" class="SQQProductOptionOffContainer"><input type="radio" class="SQQProductOptionInput" name="BusinessType" id="DCL_DCL2ReservationSQQProductOption" value="DCL2Reservation" /><span class="SQQProductOptionInputLabel"><label for="DCL_DCL2ReservationSQQProductOption">Get Reservation</label></span></div></div><div class="clearBoth"><!-- --></div></form><div class="clearBoth"><!-- --></div></div><div id="DCL_DCL2CruisesSQQProductOption_Container" class="SQQProductOption"><form action="http://disneycruise.disney.go.com/reservations/customize" method="POST" id="DCL_DCL2CruisesSQQProductOption_Form" name="DCL_DCL2CruisesSQQProductOption_Form"><input type="hidden" name="publishedKey" value="DCL2CruisesSQQProductOption_BookingGenie_en_US" /><input type="hidden" name="BusinessType" value="DCL2Cruises" /><input type="hidden" name="BusinessUnit" value="DCL" /><div class="SQQProductOptionTitle"><span class="SQQProductOptionLabel">Cruise Search</span></div><div id="DCL_DCL2CruisesSQQProductOption_DCL2CruiseHeaderSQQFloatingText" class="SQQFloatingText"><div class="SQQFloatingTextContainer"><span class="SQQFloatingTextLabel">Price Your Cruise Vacation</span></div></div><div id="DCL_DCL2CruisesSQQProductOption_DCL2DestinationSQQDropDown" class="SQQDropDown"><span class="SQQDropDownLabel">Destination</span><select class="SQQDropDownSelect" name="destination" id="DCL_DCL2CruisesSQQProductOption_DCL2_Destinations" size="1"><option value="">Choose a Destination</option><option value="BAHAMAS">Bahamas</option><option value="EUROPE">Europe</option><option value="TRANS_ATLANTIC">Transatlantic</option><option value="CARIBBEAN">Caribbean</option><option value="TRANS_PANAMA_CANAL">Panama Canal</option><option value="MEXICAN_RIVIERA">Mexican Riviera</option><option value="ALASKA">Alaska & Pacific Coast</option></select></div><div id="DCL_DCL2CruisesSQQProductOption_DCL2DateSQQDropDown" class="SQQDropDown"><span class="SQQDropDownLabel">Date</span><select class="SQQDropDownSelect" name="dates" id="DCL_DCL2CruisesSQQProductOption_DCLDates" size="1"><option value="">Choose a Date</option></select></div><div id="DCL_DCL2CruisesSQQProductOption_DCL2GuestsHeaderSQQFloatingText" class="SQQFloatingText"><div class="SQQFloatingTextContainer"><span class="SQQFloatingTextLabel">Guests</span></div></div><div id="DCL_DCL2CruisesSQQProductOption_DCL2MoreGuestsSQQFloatingText" class="SQQFloatingText"><div class="SQQFloatingTextContainer"><span class="SQQFloatingTextLabel"><a id="DCL_DCL2CruisesSQQProductOption_DCL2MoreGuestsSQQFloatingText_Link" href="#" class="SQQFloatingTextAnchor">More than 5 Guests?</a></span></div></div><div id="DCL_DCL2CruisesSQQProductOption_DCL2SQQPartyMix" class="SQQPartyMix"><div class="SQQPartyMixAdultsContainer"><span class="SQQPartyMixAdultLabel">Adults</span><select class="SQQPartyMixAdultsSelect" name="numberOfAdults" id="DCL_DCL2CruisesSQQProductOption_DCL2SQQPartyMix_numAdults" size="1"><option value="1">1</option><option value="2" selected="selected">2</option><option value="3">3</option><option value="4">4</option><option value="5">5</option></select></div><div class="SQQPartyMixChildrenContainer"><span class="SQQPartyMixChildrenLabel">Children (0-17)</span><select class="SQQPartyMixChildrenSelect" name="numberOfChildren" id="DCL_DCL2CruisesSQQProductOption_DCL2SQQPartyMix_numChildren" size="1"><option value="0" selected="selected">0</option><option value="1">1</option><option value="2">2</option><option value="3">3</option><option value="4">4</option></select></div><div class="SQQPartyMixChildAgeContainer" id="DCL_DCL2CruisesSQQProductOption_DCL2SQQPartyMix_childContainer"><div class="SQQPartyMixLabel" id="DCL_DCL2CruisesSQQProductOption_DCL2SQQPartyMix_Label"><span class="SQQPartyMixChildInstructionsLabel">Children\'s Ages at Time of Travel</span></div><div class="SQQPartyMixSelectContainer"><div class="SQQPartyMixChildAgeCount" id="DCL_DCL2CruisesSQQProductOption_DCL2SQQPartyMix_ageContainer1"><span class="SQQPartyMixChildAgeLabel">1</span><select class="SQQPartyMixChildAgeSelect" name="child1" id="DCL_DCL2CruisesSQQProductOption_DCL2SQQPartyMix_child1" size="1"><option value="17" selected="selected">17</option><option value="16">16</option><option value="15">15</option><option value="14">14</option><option value="13">13</option><option value="12">12</option><option value="11">11</option><option value="10">10</option><option value="9">9</option><option value="8">8</option><option value="7">7</option><option value="6">6</option><option value="5">5</option><option value="4">4</option><option value="3">3</option><option value="2">2</option><option value="1">Inf</option></select></div><div class="SQQPartyMixChildAgeCount" id="DCL_DCL2CruisesSQQProductOption_DCL2SQQPartyMix_ageContainer2"><span class="SQQPartyMixChildAgeLabel">2</span><select class="SQQPartyMixChildAgeSelect" name="child2" id="DCL_DCL2CruisesSQQProductOption_DCL2SQQPartyMix_child2" size="1"><option value="17" selected="selected">17</option><option value="16">16</option><option value="15">15</option><option value="14">14</option><option value="13">13</option><option value="12">12</option><option value="11">11</option><option value="10">10</option><option value="9">9</option><option value="8">8</option><option value="7">7</option><option value="6">6</option><option value="5">5</option><option value="4">4</option><option value="3">3</option><option value="2">2</option><option value="1">Inf</option></select></div><div class="SQQPartyMixChildAgeCount" id="DCL_DCL2CruisesSQQProductOption_DCL2SQQPartyMix_ageContainer3"><span class="SQQPartyMixChildAgeLabel">3</span><select class="SQQPartyMixChildAgeSelect" name="child3" id="DCL_DCL2CruisesSQQProductOption_DCL2SQQPartyMix_child3" size="1"><option value="17" selected="selected">17</option><option value="16">16</option><option value="15">15</option><option value="14">14</option><option value="13">13</option><option value="12">12</option><option value="11">11</option><option value="10">10</option><option value="9">9</option><option value="8">8</option><option value="7">7</option><option value="6">6</option><option value="5">5</option><option value="4">4</option><option value="3">3</option><option value="2">2</option><option value="1">Inf</option></select></div><div class="SQQPartyMixChildAgeCount" id="DCL_DCL2CruisesSQQProductOption_DCL2SQQPartyMix_ageContainer4"><span class="SQQPartyMixChildAgeLabel">4</span><select class="SQQPartyMixChildAgeSelect" name="child4" id="DCL_DCL2CruisesSQQProductOption_DCL2SQQPartyMix_child4" size="1"><option value="17" selected="selected">17</option><option value="16">16</option><option value="15">15</option><option value="14">14</option><option value="13">13</option><option value="12">12</option><option value="11">11</option><option value="10">10</option><option value="9">9</option><option value="8">8</option><option value="7">7</option><option value="6">6</option><option value="5">5</option><option value="4">4</option><option value="3">3</option><option value="2">2</option><option value="1">Inf</option></select></div><div class="clearBoth"><!-- --></div></div><div class="SQQPartyMixDisclaimer" id="DCL_DCL2CruisesSQQProductOption_DCL2SQQPartyMix_disclaimer"><a href="#" class="SQQPartyMixDisclaimerLink" id="DCL_DCL2CruisesSQQProductOption_DCL2SQQPartyMix_disclaimerLink">Why is this required?</a></div><div class="SQQPartyMixAlert" id="DCL_DCL2CruisesSQQProductOption_DCL2SQQPartyMix_disclaimerAlert"><span class="SQQPartyMixAlertHead" id="DCL_DCL2CruisesSQQProductOption_DCL2SQQPartyMix_disclaimerHead">Why is this required?</span><p class="SQQPartyMixAlertBody" id="DCL_DCL2CruisesSQQProductOption_DCL2SQQPartyMix_disclaimerBody">We require the ages of all children in your group because ticket package prices are calculated based on this information.</p></div></div><div class="clearBoth"><!-- --></div></div><div id="DCL_DCL2CruisesSQQProductOption_DCL2SearchOptionsSQQGrouping" class="SQQGrouping SQQGroupingHide"><div id="DCL_DCL2CruisesSQQProductOption_DCL2SearchOptionsSQQGrouping_Label" class="SQQGroupingLabelContainer transparent" style="display: block;"><span class="SQQGroupingLabel">More search options</span></div><div id="DCL_DCL2CruisesSQQProductOption_DCL2SearchOptionsSQQGrouping_OpenedLabel" class="SQQGroupingOpenedLabelContainer transparent" style="display: none;"><span class="SQQGroupingLabel">Hide Options</span></div><div id="DCL_DCL2CruisesSQQProductOption_DCL2SearchOptionsSQQGrouping_Group" class="SQQGroupingContainer"><div id="DCL_DCL2CruisesSQQProductOption_DCL2CruiseLengthSQQDropDown" class="SQQDropDown"><select class="SQQDropDownSelect" name="numberOfNights" id="DCL_DCL2CruisesSQQProductOption_DCLLength" size="1"><option value="">Cruise Length</option></select></div><div id="DCL_DCL2CruisesSQQProductOption_DCL2DeparturePortSQQDropDown" class="SQQDropDown"><select class="SQQDropDownSelect" name="departurePorts" id="DCL_DCL2CruisesSQQProductOption_DCLDeparturePort" size="1"><option value="">Departure Port</option></select></div><div id="DCL_DCL2CruisesSQQProductOption_DCL2ShipSQQDropDown" class="SQQDropDown"><select class="SQQDropDownSelect" name="ship" id="DCL_DCL2CruisesSQQProductOption_DCLShip" size="1"><option value="">Ship</option></select></div><div class="clearBoth"><!-- --></div></div></div><div class="SQQProductOptionSubmitContainer"><input type="button" name="inputSubmit" class="SQQProductOptionInputSubmit" id="DCL_DCL2CruisesSQQProductOption_Submit" value=" " /></div><div class="clearBoth"><!-- --></div></form><div class="SQQProductOptionsDisclaimerContainer" id="DCL_DCL2CruisesSQQProductOption_Disclaimer">Book online, call (800) 951-3532 or contact your travel agent.</div></div><div id="DCL_DCL2ReservationSQQProductOption_Container" class="SQQProductOption"><form action="https://disneycruise.disney.go.com/planning-center/dashboard/?webBindCommandName=landingForm&_eventId_SubmitLoginRetrieveReservation=SubmitLoginRetrieveReservation&stillShopping=false&clearPreviousReservation=true" method="POST" id="DCL_DCL2ReservationSQQProductOption_Form" name="DCL_DCL2ReservationSQQProductOption_Form"><input type="hidden" name="publishedKey" value="DCL2ReservationSQQProductOption_BookingGenie_en_US" /><input type="hidden" name="webBindCommandName" value="landingForm" /><input type="hidden" name="_eventId_SubmitLoginRetrieveReservation" value="SubmitLoginRetrieveReservation" /><input type="hidden" name="stillShopping" value="false" /><input type="hidden" name="clearPreviousReservation" value="true" /><input type="hidden" name="BusinessType" value="DCL2Reservation" /><input type="hidden" name="BusinessUnit" value="DCL" /><div class="SQQProductOptionTitle"><span class="SQQProductOptionLabel">Get Reservation</span></div><div id="DCL_DCL2ReservationSQQProductOption_DCL2RetrieveHeaderSQQFloatingText" class="SQQFloatingText"><div class="SQQFloatingTextContainer"><span class="SQQFloatingTextLabel">Retrieve Your Reservation</span></div></div><div id="DCL_DCL2ReservationSQQProductOption_DCL2ReservationNotLoggedInSQQGrouping" class="SQQGrouping SQQGroupingDisplay"><div id="DCL_DCL2ReservationSQQProductOption_DCL2ReservationNotLoggedInSQQGrouping_Group" class="SQQGroupingContainer"><div id="DCL_DCL2ReservationSQQProductOption_DCL2ReservationNotLoggedInHeaderSQQFloatingText" class="SQQFloatingText"><div class="SQQFloatingTextContainer"><span class="SQQFloatingTextLabel">Please provide the information requested. Your reservation number and birth date are required for security purposes.</span></div></div><div id="DCL_DCL2ReservationSQQProductOption_DCL2ReservationEmailSQQTextBox" class="SQQTextBox"><div class="SQQTextBoxInputContainer"><span id="DCL_DCL2ReservationSQQProductOption_DCL2ReservationEmailSQQTextBox_Overlay" class="SQQTextBoxOverlayLabel">Email Address or Member Name</span><input type="text" class="SQQTextBoxInput" name="userName" id="DCL_DCL2ReservationSQQProductOption_DCL2ReservationEmailSQQTextBox_Text" /></div></div><div id="DCL_DCL2ReservationSQQProductOption_DCL2ReservationPasswordSQQTextBox" class="SQQTextBox"><div class="SQQTextBoxInputContainer"><span id="DCL_DCL2ReservationSQQProductOption_DCL2ReservationPasswordSQQTextBox_Overlay" class="SQQTextBoxOverlayLabel">Password</span><input type="password" class="SQQTextBoxInput" name="gspw" id="DCL_DCL2ReservationSQQProductOption_DCL2ReservationPasswordSQQTextBox_Text" /></div></div><div id="DCL_DCL2ReservationSQQProductOption_DCL2ReservationForgotPasswordSQQFloatingText" class="SQQFloatingText"><div class="SQQFloatingTextContainer"><span class="SQQFloatingTextLabel"><a id="DCL_DCL2ReservationSQQProductOption_DCL2ReservationForgotPasswordSQQFloatingText_Link" href="http://www.disneycruise.disney.go.com/forgot-password/" class="SQQFloatingTextAnchor">Forgot your password? >></a></span></div></div><div id="DCL_DCL2ReservationSQQProductOption_DCL2ReservationNotLoggedInNumberSQQTextBox" class="SQQTextBox"><div class="SQQTextBoxInputContainer"><span id="DCL_DCL2ReservationSQQProductOption_DCL2ReservationNotLoggedInNumberSQQTextBox_Overlay" class="SQQTextBoxOverlayLabel">Reservation Number</span><input type="text" class="SQQTextBoxInput" name="reservationNumber" id="DCL_DCL2ReservationSQQProductOption_DCL2ReservationNotLoggedInNumberSQQTextBox_Text" /></div></div><div class="clearBoth"><!-- --></div></div></div><div id="DCL_DCL2ReservationSQQProductOption_DCL2ReservationBirthDateSQQFloatingText" class="SQQFloatingText"><div class="SQQFloatingTextContainer"><span class="SQQFloatingTextLabel">Date of Birth</span></div></div><div id="DCL_DCL2ReservationSQQProductOption_DCL2ReservationMonthSQQDropDown" class="SQQDropDown"><select class="SQQDropDownSelect" name="birthdayMonth" id="DCL_DCL2ReservationSQQProductOption_BirthDateMonth" size="1"><option value="">Month</option><option value="1">January</option><option value="2">February</option><option value="3">March</option><option value="4">April</option><option value="5">May</option><option value="6">June</option><option value="7">July</option><option value="8">August</option><option value="9">September</option><option value="10">October</option><option value="11">November</option><option value="12">December</option></select></div><div id="DCL_DCL2ReservationSQQProductOption_DCL2ReservationDaySQQDropDown" class="SQQDropDown"><select class="SQQDropDownSelect" name="birthdayDay" id="DCL_DCL2ReservationSQQProductOption_BirthDateDay" size="1"><option value="">Day</option><option value="1">1</option><option value="2">2</option><option value="3">3</option><option value="4">4</option><option value="5">5</option><option value="6">6</option><option value="7">7</option><option value="8">8</option><option value="9">9</option><option value="10">10</option><option value="11">11</option><option value="12">12</option><option value="13">13</option><option value="14">14</option><option value="15">15</option><option value="16">16</option><option value="17">17</option><option value="18">18</option><option value="19">19</option><option value="20">20</option><option value="21">21</option><option value="22">22</option><option value="23">23</option><option value="24">24</option><option value="25">25</option><option value="26">26</option><option value="27">27</option><option value="28">28</option><option value="29">29</option><option value="30">30</option><option value="31">31</option></select></div><div id="DCL_DCL2ReservationSQQProductOption_DCL2ReservationYearSQQDropDown" class="SQQDropDown"><select class="SQQDropDownSelect" name="birthdayYear" id="DCL_DCL2ReservationSQQProductOption_BirthDateYear" size="1"><option value="">Year</option><option value="1900">1900</option><option value="1901">1901</option><option value="1902">1902</option><option value="1903">1903</option><option value="1904">1904</option><option value="1905">1905</option><option value="1906">1906</option><option value="1907">1907</option><option value="1908">1908</option><option value="1909">1909</option><option value="1910">1910</option><option value="1911">1911</option><option value="1912">1912</option><option value="1913">1913</option><option value="1914">1914</option><option value="1915">1915</option><option value="1916">1916</option><option value="1917">1917</option><option value="1918">1918</option><option value="1919">1919</option><option value="1920">1920</option><option value="1921">1921</option><option value="1922">1922</option><option value="1923">1923</option><option value="1924">1924</option><option value="1925">1925</option><option value="1926">1926</option><option value="1927">1927</option><option value="1928">1928</option><option value="1929">1929</option><option value="1930">1930</option><option value="1931">1931</option><option value="1932">1932</option><option value="1933">1933</option><option value="1934">1934</option><option value="1935">1935</option><option value="1936">1936</option><option value="1937">1937</option><option value="1938">1938</option><option value="1939">1939</option><option value="1940">1940</option><option value="1941">1941</option><option value="1942">1942</option><option value="1943">1943</option><option value="1944">1944</option><option value="1945">1945</option><option value="1946">1946</option><option value="1947">1947</option><option value="1948">1948</option><option value="1949">1949</option><option value="1950">1950</option><option value="1951">1951</option><option value="1952">1952</option><option value="1953">1953</option><option value="1954">1954</option><option value="1955">1955</option><option value="1956">1956</option><option value="1957">1957</option><option value="1958">1958</option><option value="1959">1959</option><option value="1960">1960</option><option value="1961">1961</option><option value="1962">1962</option><option value="1963">1963</option><option value="1964">1964</option><option value="1965">1965</option><option value="1966">1966</option><option value="1967">1967</option><option value="1968">1968</option><option value="1969">1969</option><option value="1970">1970</option><option value="1971">1971</option><option value="1972">1972</option><option value="1973">1973</option><option value="1974">1974</option><option value="1975">1975</option><option value="1976">1976</option><option value="1977">1977</option><option value="1978">1978</option><option value="1979">1979</option><option value="1980">1980</option><option value="1981">1981</option><option value="1982">1982</option><option value="1983">1983</option><option value="1984">1984</option><option value="1985">1985</option><option value="1986">1986</option><option value="1987">1987</option><option value="1988">1988</option><option value="1989">1989</option><option value="1990">1990</option><option value="1991">1991</option><option value="1992">1992</option><option value="1993">1993</option><option value="1994">1994</option><option value="1995">1995</option><option value="1996">1996</option><option value="1997">1997</option><option value="1998">1998</option><option value="1999">1999</option><option value="2000">2000</option><option value="2001">2001</option><option value="2002">2002</option><option value="2003">2003</option><option value="2004">2004</option><option value="2005">2005</option><option value="2006">2006</option><option value="2007">2007</option><option value="2008">2008</option><option value="2009">2009</option></select></div><div class="SQQProductOptionSubmitContainer"><input type="button" name="inputSubmit" class="SQQProductOptionInputSubmit" id="DCL_DCL2ReservationSQQProductOption_Submit" value=" " /></div><div class="clearBoth"><!-- --></div></form><div class="SQQProductOptionsDisclaimerContainer" id="DCL_DCL2ReservationSQQProductOption_Disclaimer">Book online, call (800) 951-3532 or contact your travel agent.</div></div></div><div class="SQQBusinessUnitBottom"><!-- --></div></div>';
	
	return true;
};

// just like the rendered page request
DisneyQuickQuote.prototype.requestBusinessRules = function() {
	
	try {
		this.objData = eval( '({"Prop":{"name":"DCL2SQQProperties_BookingGenie_en_US","nextGenAnalytics":true,"listAllErrors":true,"monthLabels":["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],"errors":{"strTooManyGuests":"Sorry, you can only book a maximum of [N] guests. For parties greater than [N], you will be able to select a 2nd stateroom for more guests further into your booking.","strArriveAfterDepart":"Your check-in date occurs after your check-out date. Please change your check-in or check-out date.","strArriveIsAfterMaxDate":"Currently, <b>Walt Disney World</b>® Resort reservations are only available for check-in dates up to and including December 31, 2011. Please modify your travel dates accordingly.","strArriveIsBeforeAllowable":"Arrival date is before the first allowable booking day, please select a later arrival date.","strCloseLabel":"OK","strHead":"Warning","strStayTooLong":"Sorry, this package must be booked for a maximum stay of [N] nights. Please adjust your vacation dates.","strStayTooShort":"Sorry, this package must be booked for a minimum stay of at least [N] nights. Please adjust your vacation dates."},"BU":[{"value":"DCL","name":"DCL2SQQBusinessUnit","PO":[{"name":"DCL2CruisesSQQProductOption","trackingLinkId":"DCLQQModSubmit_link","value":"DCL2Cruises","SQQDropDown":[{"name":"DCL2DestinationSQQDropDown","dependency":"dates","autocomplete":"false","isRequired":true,"requiredError":"Please choose a destination.","htmlObjectName":"destination","xmlPointer":"DCL2_Destinations"},{"name":"DCL2DateSQQDropDown","dependency":"numberOfNights","autocomplete":"false","isRequired":true,"requiredError":"Please choose a date.","htmlObjectName":"dates","xmlPointer":"DCLDates"},{"name":"DCL2CruiseLengthSQQDropDown","dependency":"departurePorts","autocomplete":"false","isRequired":false,"htmlObjectName":"numberOfNights","xmlPointer":"DCLLength"},{"name":"DCL2DeparturePortSQQDropDown","dependency":"ship","autocomplete":"false","isRequired":false,"htmlObjectName":"departurePorts","xmlPointer":"DCLDeparturePort"},{"name":"DCL2ShipSQQDropDown","autocomplete":"false","isRequired":false,"htmlObjectName":"ship","xmlPointer":"DCLShip"}],"SQQPartyMix":{"name":"DCL2SQQPartyMix","maxGuests":5},"SQQGrouping":["DCL2SearchOptionsSQQGrouping"]},{"name":"DCL2ReservationSQQProductOption","trackingLinkId":"DCLQQModSubmit_link","value":"DCL2Reservation","SQQTextBox":[{"name":"DCL2ReservationEmailSQQTextBox","htmlObjectName":"userName","isRequired":true,"requiredError":"You must specify an email address or member name to continue.","overlayLabel":"Email Address or Member Name"},{"name":"DCL2ReservationPasswordSQQTextBox","htmlObjectName":"gspw","isRequired":true,"requiredError":"You must type in your password to continue.","overlayLabel":"Password"},{"name":"DCL2ReservationNotLoggedInNumberSQQTextBox","htmlObjectName":"reservationNumber","isRequired":true,"requiredError":"You must specify your reservation number to continue.","overlayLabel":"Reservation Number"}],"SQQDropDown":[{"name":"DCL2ReservationMonthSQQDropDown","autocomplete":"false","isRequired":true,"requiredError":"You must select the month of your birth date.","htmlObjectName":"birthdayMonth","xmlPointer":"BirthDateMonth"},{"name":"DCL2ReservationDaySQQDropDown","autocomplete":"false","isRequired":true,"requiredError":"You must select the day of your birth date.","htmlObjectName":"birthdayDay","xmlPointer":"BirthDateDay"},{"name":"DCL2ReservationYearSQQDropDown","autocomplete":"false","isRequired":true,"requiredError":"You must select the year of your birth date.","htmlObjectName":"birthdayYear","xmlPointer":"BirthDateYear"}],"SQQGrouping":["DCL2ReservationNotLoggedInSQQGrouping"]}]}]},"OptInfo":{},"Groups":{"DCL2_CARIBBEAN_2011-04-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_CARIBBEAN_2011-04-01_5-7_PCV_Ships"}],"DCL2_CARIBBEAN_2011-12-01_5-7_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_CARIBBEAN_2011-10-01_5-7_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCLDeparturePort":[{l:"Departure Port"}],"DCL2_BAHAMAS_2010-10-01_0-4_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Wonder",d:"DW"}],"DCL2_CARIBBEAN_2010-11-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_CARIBBEAN_2010-11-01_5-7_PCV_Ships"}],"DCL2_BAHAMAS_2011-12-01_0-4_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Dream",d:"DD"}],"DCL2_CARIBBEAN_2010-12-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_CARIBBEAN_2010-12-01_5-7_PCV_Ships"}],"DCL2_ALASKA_2011-06-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_ALASKA_2011-06-01_5-7_Ports"}],"DCL2_EUROPE_2011-07-01_8-13_Ports":[{l:"Departure Port",d:""},{l:"Barcelona, Spain",d:"BCN",t:"DCL2_EUROPE_2011-07-01_8-13_BCN_Ships"}],"DCL2_EUROPE_2011-07-01_8-13_BCN_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_TRANS_ATLANTIC_2011-09-01_Lengths":[{l:"Cruise Length",d:""},{l:"14+",d:"14+",t:"DCL2_TRANS_ATLANTIC_2011-09-01_14+_Ports"}],"DCL2_EUROPE_2010-09-01_Lengths":[{l:"Cruise Length",d:""},{l:"8-13",d:"8-13",t:"DCL2_EUROPE_2010-09-01_8-13_Ports"}],"DCL2_MEXICAN_RIVIERA_2011-11-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Los Angeles, California",d:"LAX",t:"DCL2_MEXICAN_RIVIERA_2011-11-01_5-7_LAX_Ships"}],"DCLDates":[{l:"Choose a Date"}],"DCL2_CARIBBEAN_Months":[{l:"Choose a Date",d:""},{l:"October 2010",d:"2010-10-01",t:"DCL2_CARIBBEAN_2010-10-01_Lengths"},{l:"November 2010",d:"2010-11-01",t:"DCL2_CARIBBEAN_2010-11-01_Lengths"},{l:"December 2010",d:"2010-12-01",t:"DCL2_CARIBBEAN_2010-12-01_Lengths"},{l:"January 2011",d:"2011-01-01",t:"DCL2_CARIBBEAN_2011-01-01_Lengths"},{l:"February 2011",d:"2011-02-01",t:"DCL2_CARIBBEAN_2011-02-01_Lengths"},{l:"March 2011",d:"2011-03-01",t:"DCL2_CARIBBEAN_2011-03-01_Lengths"},{l:"April 2011",d:"2011-04-01",t:"DCL2_CARIBBEAN_2011-04-01_Lengths"},{l:"May 2011",d:"2011-05-01",t:"DCL2_CARIBBEAN_2011-05-01_Lengths"},{l:"September 2011",d:"2011-09-01",t:"DCL2_CARIBBEAN_2011-09-01_Lengths"},{l:"October 2011",d:"2011-10-01",t:"DCL2_CARIBBEAN_2011-10-01_Lengths"},{l:"November 2011",d:"2011-11-01",t:"DCL2_CARIBBEAN_2011-11-01_Lengths"},{l:"December 2011",d:"2011-12-01",t:"DCL2_CARIBBEAN_2011-12-01_Lengths"}],"DCL2_BAHAMAS_2011-05-01_5-7_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Dream",d:"DD"}],"DCL2_BAHAMAS_2011-11-01_Lengths":[{l:"Cruise Length",d:""},{l:"0-4",d:"0-4",t:"DCL2_BAHAMAS_2011-11-01_0-4_Ports"}],"DCL2_BAHAMAS_2011-08-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_BAHAMAS_2011-08-01_5-7_Ports"},{l:"0-4",d:"0-4",t:"DCL2_BAHAMAS_2011-08-01_0-4_Ports"}],"DCL2_EUROPE_2011-07-01_5-7_BCN_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_BAHAMAS_2011-05-01_Lengths":[{l:"Cruise Length",d:""},{l:"0-4",d:"0-4",t:"DCL2_BAHAMAS_2011-05-01_0-4_Ports"},{l:"5-7",d:"5-7",t:"DCL2_BAHAMAS_2011-05-01_5-7_Ports"}],"DCL2_BAHAMAS_2010-11-01_0-4_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_BAHAMAS_2010-11-01_0-4_PCV_Ships"}],"DCL2_MEXICAN_RIVIERA_2011-03-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Los Angeles, California",d:"LAX",t:"DCL2_MEXICAN_RIVIERA_2011-03-01_5-7_LAX_Ships"}],"DCL2_MEXICAN_RIVIERA_2011-10-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_MEXICAN_RIVIERA_2011-10-01_5-7_Ports"}],"DCL2_CARIBBEAN_2010-12-01_8-13_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_CARIBBEAN_2011-04-01_5-7_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_MEXICAN_RIVIERA_2011-01-01_0-4_Ports":[{l:"Departure Port",d:""},{l:"Los Angeles, California",d:"LAX",t:"DCL2_MEXICAN_RIVIERA_2011-01-01_0-4_LAX_Ships"}],"DCL2_CARIBBEAN_2010-11-01_5-7_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_ALASKA_2011-07-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_ALASKA_2011-07-01_5-7_Ports"}],"DCL2_ALASKA_2011-07-01_5-7_VAN_Ships":[{l:"Ship",d:""},{l:"Disney Wonder",d:"DW"}],"DCL2_MEXICAN_RIVIERA_2011-09-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_MEXICAN_RIVIERA_2011-09-01_5-7_Ports"}],"DCL2_BAHAMAS_2010-12-01_0-4_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_BAHAMAS_2010-12-01_0-4_PCV_Ships"}],"DCL2_MEXICAN_RIVIERA_2011-04-01_8-13_Ports":[{l:"Departure Port",d:""},{l:"Los Angeles, California",d:"LAX",t:"DCL2_MEXICAN_RIVIERA_2011-04-01_8-13_LAX_Ships"}],"DCL2_CARIBBEAN_2011-11-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_CARIBBEAN_2011-11-01_5-7_Ports"}],"DCL2_EUROPE_2011-06-01_Lengths":[{l:"Cruise Length",d:""},{l:"8-13",d:"8-13",t:"DCL2_EUROPE_2011-06-01_8-13_Ports"}],"DCL2_BAHAMAS_2011-11-01_0-4_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_BAHAMAS_2011-11-01_0-4_PCV_Ships"}],"DCLLength":[{l:"Cruise Length"}],"DCL2_MEXICAN_RIVIERA_2011-01-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Los Angeles, California",d:"LAX",t:"DCL2_MEXICAN_RIVIERA_2011-01-01_5-7_LAX_Ships"}],"DCL2_CARIBBEAN_2011-03-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_CARIBBEAN_2011-03-01_5-7_PCV_Ships"}],"DCL2_BAHAMAS_2011-09-01_Lengths":[{l:"Cruise Length",d:""},{l:"0-4",d:"0-4",t:"DCL2_BAHAMAS_2011-09-01_0-4_Ports"}],"DCL2_EUROPE_2011-06-01_8-13_Ports":[{l:"Departure Port",d:""},{l:"Barcelona, Spain",d:"BCN",t:"DCL2_EUROPE_2011-06-01_8-13_BCN_Ships"}],"DCL2_ALASKA_2011-09-01_5-7_VAN_Ships":[{l:"Ship",d:""},{l:"Disney Wonder",d:"DW"}],"DCL2_MEXICAN_RIVIERA_2011-04-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_MEXICAN_RIVIERA_2011-04-01_5-7_Ports"},{l:"8-13",d:"8-13",t:"DCL2_MEXICAN_RIVIERA_2011-04-01_8-13_Ports"}],"DCL2_ALASKA_2011-08-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Vancouver, Canada",d:"VAN",t:"DCL2_ALASKA_2011-08-01_5-7_VAN_Ships"}],"DCL2_BAHAMAS_2010-12-01_Lengths":[{l:"Cruise Length",d:""},{l:"0-4",d:"0-4",t:"DCL2_BAHAMAS_2010-12-01_0-4_Ports"},{l:"5-7",d:"5-7",t:"DCL2_BAHAMAS_2010-12-01_5-7_Ports"}],"DCL2_BAHAMAS_2011-12-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_BAHAMAS_2011-12-01_5-7_PCV_Ships"}],"DCL2_BAHAMAS_2011-12-01_5-7_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Dream",d:"DD"}],"DCL2_BAHAMAS_2011-10-01_0-4_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Dream",d:"DD"}],"DCL2_ALASKA_2011-04-01_5-7_LAX_Ships":[{l:"Ship",d:""},{l:"Disney Wonder",d:"DW"}],"DCL2_TRANS_ATLANTIC_2011-05-01_14+_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_TRANS_ATLANTIC_2011-05-01_14+_PCV_Ships"}],"DCL2_CARIBBEAN_2011-10-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_CARIBBEAN_2011-10-01_5-7_Ports"}],"DCL2_MEXICAN_RIVIERA_2011-09-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Los Angeles, California",d:"LAX",t:"DCL2_MEXICAN_RIVIERA_2011-09-01_5-7_LAX_Ships"}],"DCL2_EUROPE_2011-05-01_8-13_Ports":[{l:"Departure Port",d:""},{l:"Barcelona, Spain",d:"BCN",t:"DCL2_EUROPE_2011-05-01_8-13_BCN_Ships"}],"DCL2_CARIBBEAN_2011-09-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_CARIBBEAN_2011-09-01_5-7_Ports"}],"DCL2_CARIBBEAN_2011-10-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_CARIBBEAN_2011-10-01_5-7_PCV_Ships"}],"DCL2_MEXICAN_RIVIERA_2011-12-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Los Angeles, California",d:"LAX",t:"DCL2_MEXICAN_RIVIERA_2011-12-01_5-7_LAX_Ships"}],"DCL2_BAHAMAS_2010-11-01_0-4_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Wonder",d:"DW"}],"DCL2_BAHAMAS_2011-02-01_0-4_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_BAHAMAS_2011-02-01_0-4_PCV_Ships"}],"BirthDateMonth":[{l:"Month"},{l:"January",d:"1"},{l:"February",d:"2"},{l:"March",d:"3"},{l:"April",d:"4"},{l:"May",d:"5"},{l:"June",d:"6"},{l:"July",d:"7"},{l:"August",d:"8"},{l:"September",d:"9"},{l:"October",d:"10"},{l:"November",d:"11"},{l:"December",d:"12"}],"DCL2_MEXICAN_RIVIERA_2011-02-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_MEXICAN_RIVIERA_2011-02-01_5-7_Ports"}],"DCL2_ALASKA_2011-08-01_5-7_VAN_Ships":[{l:"Ship",d:""},{l:"Disney Wonder",d:"DW"}],"DCL2_BAHAMAS_2011-03-01_0-4_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Dream",d:"DD"}],"DCL2_TRANS_ATLANTIC_2010-09-01_Lengths":[{l:"Cruise Length",d:""},{l:"14+",d:"14+",t:"DCL2_TRANS_ATLANTIC_2010-09-01_14+_Ports"}],"DCL2_CARIBBEAN_2010-11-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_CARIBBEAN_2010-11-01_5-7_Ports"}],"DCL2_BAHAMAS_2011-01-01_0-4_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Dream",d:"DD"}],"DCL2_CARIBBEAN_2011-02-01_5-7_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_BAHAMAS_2010-10-01_0-4_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_BAHAMAS_2010-10-01_0-4_PCV_Ships"}],"BirthDateDay":[{l:"Day"},{l:"1",d:"1"},{l:"2",d:"2"},{l:"3",d:"3"},{l:"4",d:"4"},{l:"5",d:"5"},{l:"6",d:"6"},{l:"7",d:"7"},{l:"8",d:"8"},{l:"9",d:"9"},{l:"10",d:"10"},{l:"11",d:"11"},{l:"12",d:"12"},{l:"13",d:"13"},{l:"14",d:"14"},{l:"15",d:"15"},{l:"16",d:"16"},{l:"17",d:"17"},{l:"18",d:"18"},{l:"19",d:"19"},{l:"20",d:"20"},{l:"21",d:"21"},{l:"22",d:"22"},{l:"23",d:"23"},{l:"24",d:"24"},{l:"25",d:"25"},{l:"26",d:"26"},{l:"27",d:"27"},{l:"28",d:"28"},{l:"29",d:"29"},{l:"30",d:"30"},{l:"31",d:"31"}],"DCL2_BAHAMAS_2011-09-01_0-4_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_BAHAMAS_2011-09-01_0-4_PCV_Ships"}],"DCL2_CARIBBEAN_2011-03-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_CARIBBEAN_2011-03-01_5-7_Ports"}],"DCL2_CARIBBEAN_2011-05-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_CARIBBEAN_2011-05-01_5-7_PCV_Ships"}],"DCL2_BAHAMAS_2011-06-01_0-4_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_BAHAMAS_2011-06-01_0-4_PCV_Ships"}],"DCL2_BAHAMAS_2011-07-01_0-4_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Dream",d:"DD"}],"DCL2Data":[{l:"Disney Magic",d:"DM"},{l:"Disney Wonder",d:"DW"},{l:"Disney Dream",d:"DD"},{l:"Caribbean",d:"CARIBBEAN"},{l:"Transatlantic",d:"TRANS_ATLANTIC"},{l:"Europe",d:"EUROPE"},{l:"Bahamas",d:"BAHAMAS"},{l:"Alaska &amp; Pacific Coast",d:"ALASKA"},{l:"Mexican Riviera",d:"MEXICAN_RIVIERA"},{l:"Panama Canal",d:"TRANS_PANAMA_CANAL"},{l:"Port Canaveral, Florida",d:"PCV"},{l:"Barcelona, Spain",d:"BCN"},{l:"Dover, England",d:"DVR"},{l:"Los Angeles, California",d:"LAX"},{l:"Vancouver, Canada",d:"VAN"}],"DCL2_BAHAMAS_2011-02-01_0-4_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Dream",d:"DD"}],"DCL2_EUROPE_Months":[{l:"Choose a Date",d:""},{l:"September 2010",d:"2010-09-01",t:"DCL2_EUROPE_2010-09-01_Lengths"},{l:"May 2011",d:"2011-05-01",t:"DCL2_EUROPE_2011-05-01_Lengths"},{l:"June 2011",d:"2011-06-01",t:"DCL2_EUROPE_2011-06-01_Lengths"},{l:"July 2011",d:"2011-07-01",t:"DCL2_EUROPE_2011-07-01_Lengths"},{l:"August 2011",d:"2011-08-01",t:"DCL2_EUROPE_2011-08-01_Lengths"},{l:"September 2011",d:"2011-09-01",t:"DCL2_EUROPE_2011-09-01_Lengths"}],"DCL2_ALASKA_Months":[{l:"Choose a Date",d:""},{l:"April 2011",d:"2011-04-01",t:"DCL2_ALASKA_2011-04-01_Lengths"},{l:"May 2011",d:"2011-05-01",t:"DCL2_ALASKA_2011-05-01_Lengths"},{l:"June 2011",d:"2011-06-01",t:"DCL2_ALASKA_2011-06-01_Lengths"},{l:"July 2011",d:"2011-07-01",t:"DCL2_ALASKA_2011-07-01_Lengths"},{l:"August 2011",d:"2011-08-01",t:"DCL2_ALASKA_2011-08-01_Lengths"},{l:"September 2011",d:"2011-09-01",t:"DCL2_ALASKA_2011-09-01_Lengths"}],"DCL2_CARIBBEAN_2011-09-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_CARIBBEAN_2011-09-01_5-7_PCV_Ships"}],"DCL2_MEXICAN_RIVIERA_2011-04-01_5-7_LAX_Ships":[{l:"Ship",d:""},{l:"Disney Wonder",d:"DW"}],"DCL2_BAHAMAS_2010-12-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_BAHAMAS_2010-12-01_5-7_PCV_Ships"}],"DCL2_MEXICAN_RIVIERA_Months":[{l:"Choose a Date",d:""},{l:"January 2011",d:"2011-01-01",t:"DCL2_MEXICAN_RIVIERA_2011-01-01_Lengths"},{l:"February 2011",d:"2011-02-01",t:"DCL2_MEXICAN_RIVIERA_2011-02-01_Lengths"},{l:"March 2011",d:"2011-03-01",t:"DCL2_MEXICAN_RIVIERA_2011-03-01_Lengths"},{l:"April 2011",d:"2011-04-01",t:"DCL2_MEXICAN_RIVIERA_2011-04-01_Lengths"},{l:"September 2011",d:"2011-09-01",t:"DCL2_MEXICAN_RIVIERA_2011-09-01_Lengths"},{l:"October 2011",d:"2011-10-01",t:"DCL2_MEXICAN_RIVIERA_2011-10-01_Lengths"},{l:"November 2011",d:"2011-11-01",t:"DCL2_MEXICAN_RIVIERA_2011-11-01_Lengths"},{l:"December 2011",d:"2011-12-01",t:"DCL2_MEXICAN_RIVIERA_2011-12-01_Lengths"}],"DCL2_EUROPE_2011-09-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Barcelona, Spain",d:"BCN",t:"DCL2_EUROPE_2011-09-01_5-7_BCN_Ships"}],"DCL2_EUROPE_2010-09-01_8-13_BCN_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_BAHAMAS_2010-10-01_Lengths":[{l:"Cruise Length",d:""},{l:"0-4",d:"0-4",t:"DCL2_BAHAMAS_2010-10-01_0-4_Ports"}],"DCL2_MEXICAN_RIVIERA_2011-09-01_5-7_LAX_Ships":[{l:"Ship",d:""},{l:"Disney Wonder",d:"DW"}],"DCL2_MEXICAN_RIVIERA_2011-04-01_8-13_LAX_Ships":[{l:"Ship",d:""},{l:"Disney Wonder",d:"DW"}],"DCL2_EUROPE_2011-05-01_8-13_BCN_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_BAHAMAS_2011-01-01_5-7_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_MEXICAN_RIVIERA_2011-11-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_MEXICAN_RIVIERA_2011-11-01_5-7_Ports"}],"DCL2_MEXICAN_RIVIERA_2011-12-01_5-7_LAX_Ships":[{l:"Ship",d:""},{l:"Disney Wonder",d:"DW"}],"DCL2_MEXICAN_RIVIERA_2011-01-01_5-7_LAX_Ships":[{l:"Ship",d:""},{l:"Disney Wonder",d:"DW"}],"DCL2_TRANS_PANAMA_CANAL_2011-01-01_14+_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Wonder",d:"DW"}],"DCL2_BAHAMAS_2011-11-01_0-4_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Dream",d:"DD"}],"DCL2_CARIBBEAN_2011-12-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_CARIBBEAN_2011-12-01_5-7_PCV_Ships"}],"DCL2_TRANS_PANAMA_CANAL_2011-01-01_14+_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_TRANS_PANAMA_CANAL_2011-01-01_14+_PCV_Ships"}],"DCL2_BAHAMAS_2011-07-01_Lengths":[{l:"Cruise Length",d:""},{l:"0-4",d:"0-4",t:"DCL2_BAHAMAS_2011-07-01_0-4_Ports"},{l:"5-7",d:"5-7",t:"DCL2_BAHAMAS_2011-07-01_5-7_Ports"}],"DCL2_CARIBBEAN_2011-01-01_5-7_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_CARIBBEAN_2010-12-01_5-7_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"},{l:"Disney Wonder",d:"DW"}],"DCL2_CARIBBEAN_2011-01-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_CARIBBEAN_2011-01-01_5-7_Ports"}],"DCL2_BAHAMAS_2011-08-01_0-4_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Dream",d:"DD"}],"DCL2_CARIBBEAN_2011-12-01_8-13_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_CARIBBEAN_2011-12-01_8-13_PCV_Ships"}],"DCL2_ALASKA_2011-05-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Vancouver, Canada",d:"VAN",t:"DCL2_ALASKA_2011-05-01_5-7_VAN_Ships"}],"DCL2_BAHAMAS_2011-10-01_Lengths":[{l:"Cruise Length",d:""},{l:"0-4",d:"0-4",t:"DCL2_BAHAMAS_2011-10-01_0-4_Ports"}],"DCL2_BAHAMAS_2011-06-01_0-4_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Dream",d:"DD"}],"DCL2_MEXICAN_RIVIERA_2011-03-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_MEXICAN_RIVIERA_2011-03-01_5-7_Ports"}],"DCL2_MEXICAN_RIVIERA_2011-04-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Los Angeles, California",d:"LAX",t:"DCL2_MEXICAN_RIVIERA_2011-04-01_5-7_LAX_Ships"}],"DCL2_BAHAMAS_2011-05-01_0-4_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_BAHAMAS_2011-05-01_0-4_PCV_Ships"}],"DCL2_TRANS_ATLANTIC_2011-05-01_14+_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_BAHAMAS_2011-08-01_0-4_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_BAHAMAS_2011-08-01_0-4_PCV_Ships"}],"DCL2_MEXICAN_RIVIERA_2011-02-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Los Angeles, California",d:"LAX",t:"DCL2_MEXICAN_RIVIERA_2011-02-01_5-7_LAX_Ships"}],"DCL2_CARIBBEAN_2011-12-01_8-13_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_BAHAMAS_2010-09-01_0-4_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_BAHAMAS_2010-09-01_0-4_PCV_Ships"}],"DCL2_CARIBBEAN_2010-12-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_CARIBBEAN_2010-12-01_5-7_Ports"},{l:"8-13",d:"8-13",t:"DCL2_CARIBBEAN_2010-12-01_8-13_Ports"}],"DCL2_EUROPE_2011-07-01_Lengths":[{l:"Cruise Length",d:""},{l:"8-13",d:"8-13",t:"DCL2_EUROPE_2011-07-01_8-13_Ports"},{l:"5-7",d:"5-7",t:"DCL2_EUROPE_2011-07-01_5-7_Ports"}],"DCL2_BAHAMAS_2011-05-01_0-4_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Dream",d:"DD"}],"DCL2_BAHAMAS_2011-08-01_5-7_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Dream",d:"DD"}],"DCL2_TRANS_ATLANTIC_2011-09-01_14+_Ports":[{l:"Departure Port",d:""},{l:"Barcelona, Spain",d:"BCN",t:"DCL2_TRANS_ATLANTIC_2011-09-01_14+_BCN_Ships"}],"DCL2_BAHAMAS_2011-09-01_0-4_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Dream",d:"DD"}],"DCL2_EUROPE_2011-05-01_Lengths":[{l:"Cruise Length",d:""},{l:"8-13",d:"8-13",t:"DCL2_EUROPE_2011-05-01_8-13_Ports"}],"DCL2_ALASKA_2011-04-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Los Angeles, California",d:"LAX",t:"DCL2_ALASKA_2011-04-01_5-7_LAX_Ships"}],"DCL2_CARIBBEAN_2011-03-01_5-7_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_MEXICAN_RIVIERA_2011-12-01_8-13_LAX_Ships":[{l:"Ship",d:""},{l:"Disney Wonder",d:"DW"}],"DCL2_MEXICAN_RIVIERA_2011-02-01_5-7_LAX_Ships":[{l:"Ship",d:""},{l:"Disney Wonder",d:"DW"}],"DCL2_TRANS_ATLANTIC_2010-09-01_14+_Ports":[{l:"Departure Port",d:""},{l:"Barcelona, Spain",d:"BCN",t:"DCL2_TRANS_ATLANTIC_2010-09-01_14+_BCN_Ships"}],"DCL2_CARIBBEAN_2011-02-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_CARIBBEAN_2011-02-01_5-7_PCV_Ships"}],"DCL2_ALASKA_2011-06-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Vancouver, Canada",d:"VAN",t:"DCL2_ALASKA_2011-06-01_5-7_VAN_Ships"}],"DCL2_ALASKA_2011-05-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_ALASKA_2011-05-01_5-7_Ports"}],"DCL2_ALASKA_2011-07-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Vancouver, Canada",d:"VAN",t:"DCL2_ALASKA_2011-07-01_5-7_VAN_Ships"}],"DCL2_BAHAMAS_2011-04-01_Lengths":[{l:"Cruise Length",d:""},{l:"0-4",d:"0-4",t:"DCL2_BAHAMAS_2011-04-01_0-4_Ports"}],"DCL2_MEXICAN_RIVIERA_2011-11-01_5-7_LAX_Ships":[{l:"Ship",d:""},{l:"Disney Wonder",d:"DW"}],"DCL2_CARIBBEAN_2010-10-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_CARIBBEAN_2010-10-01_5-7_PCV_Ships"}],"DCL2_CARIBBEAN_2011-01-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_CARIBBEAN_2011-01-01_5-7_PCV_Ships"}],"DCL2_EUROPE_2011-09-01_5-7_BCN_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_CARIBBEAN_2010-10-01_5-7_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_MEXICAN_RIVIERA_2011-12-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_MEXICAN_RIVIERA_2011-12-01_5-7_Ports"},{l:"8-13",d:"8-13",t:"DCL2_MEXICAN_RIVIERA_2011-12-01_8-13_Ports"}],"DCL2_BAHAMAS_2011-07-01_5-7_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Dream",d:"DD"}],"DCL2_BAHAMAS_2011-07-01_0-4_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_BAHAMAS_2011-07-01_0-4_PCV_Ships"}],"DCL2_BAHAMAS_2011-07-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_BAHAMAS_2011-07-01_5-7_PCV_Ships"}],"DCL2_BAHAMAS_2011-03-01_0-4_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_BAHAMAS_2011-03-01_0-4_PCV_Ships"}],"DCL2_BAHAMAS_2011-12-01_0-4_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_BAHAMAS_2011-12-01_0-4_PCV_Ships"}],"DCL2_TRANS_ATLANTIC_2011-05-01_Lengths":[{l:"Cruise Length",d:""},{l:"14+",d:"14+",t:"DCL2_TRANS_ATLANTIC_2011-05-01_14+_Ports"}],"DCL2_BAHAMAS_2011-08-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_BAHAMAS_2011-08-01_5-7_PCV_Ships"}],"DCL2_BAHAMAS_2010-12-01_0-4_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Wonder",d:"DW"}],"DCL2_ALASKA_2011-09-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Vancouver, Canada",d:"VAN",t:"DCL2_ALASKA_2011-09-01_5-7_VAN_Ships"}],"DCL2_TRANS_ATLANTIC_2011-09-01_14+_BCN_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_Destinations":[{l:"Choose a Destination",d:""},{l:"Bahamas",d:"BAHAMAS",t:"DCL2_BAHAMAS_Months"},{l:"Europe",d:"EUROPE",t:"DCL2_EUROPE_Months"},{l:"Transatlantic",d:"TRANS_ATLANTIC",t:"DCL2_TRANS_ATLANTIC_Months"},{l:"Caribbean",d:"CARIBBEAN",t:"DCL2_CARIBBEAN_Months"},{l:"Panama Canal",d:"TRANS_PANAMA_CANAL",t:"DCL2_TRANS_PANAMA_CANAL_Months"},{l:"Mexican Riviera",d:"MEXICAN_RIVIERA",t:"DCL2_MEXICAN_RIVIERA_Months"},{l:"Alaska &amp; Pacific Coast",d:"ALASKA",t:"DCL2_ALASKA_Months"}],"DCL2_ALASKA_2011-08-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_ALASKA_2011-08-01_5-7_Ports"}],"DCL2_EUROPE_2010-09-01_8-13_Ports":[{l:"Departure Port",d:""},{l:"Barcelona, Spain",d:"BCN",t:"DCL2_EUROPE_2010-09-01_8-13_BCN_Ships"}],"DCL2_BAHAMAS_2011-04-01_0-4_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_BAHAMAS_2011-04-01_0-4_PCV_Ships"}],"DCL2_MEXICAN_RIVIERA_2011-01-01_Lengths":[{l:"Cruise Length",d:""},{l:"0-4",d:"0-4",t:"DCL2_MEXICAN_RIVIERA_2011-01-01_0-4_Ports"},{l:"5-7",d:"5-7",t:"DCL2_MEXICAN_RIVIERA_2011-01-01_5-7_Ports"}],"DCL2_MEXICAN_RIVIERA_2011-01-01_0-4_LAX_Ships":[{l:"Ship",d:""},{l:"Disney Wonder",d:"DW"}],"DCL2_EUROPE_2011-06-01_8-13_BCN_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_ALASKA_2011-05-01_5-7_VAN_Ships":[{l:"Ship",d:""},{l:"Disney Wonder",d:"DW"}],"DCL2_EUROPE_2011-08-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Barcelona, Spain",d:"BCN",t:"DCL2_EUROPE_2011-08-01_5-7_BCN_Ships"}],"DCL2_EUROPE_2011-07-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Barcelona, Spain",d:"BCN",t:"DCL2_EUROPE_2011-07-01_5-7_BCN_Ships"}],"DCL2_ALASKA_2011-06-01_5-7_VAN_Ships":[{l:"Ship",d:""},{l:"Disney Wonder",d:"DW"}],"DCL2_BAHAMAS_2011-12-01_Lengths":[{l:"Cruise Length",d:""},{l:"0-4",d:"0-4",t:"DCL2_BAHAMAS_2011-12-01_0-4_Ports"},{l:"5-7",d:"5-7",t:"DCL2_BAHAMAS_2011-12-01_5-7_Ports"}],"DCL2_EUROPE_2011-08-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_EUROPE_2011-08-01_5-7_Ports"}],"DCL2_EUROPE_2011-08-01_5-7_BCN_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_BAHAMAS_2010-12-01_5-7_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_BAHAMAS_2010-09-01_0-4_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Wonder",d:"DW"}],"DCL2_CARIBBEAN_2011-09-01_5-7_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_ALASKA_2011-04-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_ALASKA_2011-04-01_5-7_Ports"}],"DCL2_BAHAMAS_2010-11-01_Lengths":[{l:"Cruise Length",d:""},{l:"0-4",d:"0-4",t:"DCL2_BAHAMAS_2010-11-01_0-4_Ports"}],"DCL2_CARIBBEAN_2011-05-01_5-7_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_MEXICAN_RIVIERA_2011-12-01_8-13_Ports":[{l:"Departure Port",d:""},{l:"Los Angeles, California",d:"LAX",t:"DCL2_MEXICAN_RIVIERA_2011-12-01_8-13_LAX_Ships"}],"DCL2_TRANS_PANAMA_CANAL_Months":[{l:"Choose a Date",d:""},{l:"January 2011",d:"2011-01-01",t:"DCL2_TRANS_PANAMA_CANAL_2011-01-01_Lengths"}],"DCLShip":[{l:"Ship"}],"DCL2_CARIBBEAN_2011-11-01_5-7_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_BAHAMAS_2011-05-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_BAHAMAS_2011-05-01_5-7_PCV_Ships"}],"DCL2_EUROPE_2011-09-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_EUROPE_2011-09-01_5-7_Ports"}],"DCL2_BAHAMAS_2011-10-01_0-4_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_BAHAMAS_2011-10-01_0-4_PCV_Ships"}],"DCL2_BAHAMAS_2011-01-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_BAHAMAS_2011-01-01_5-7_PCV_Ships"}],"DCL2_BAHAMAS_2010-09-01_Lengths":[{l:"Cruise Length",d:""},{l:"0-4",d:"0-4",t:"DCL2_BAHAMAS_2010-09-01_0-4_Ports"}],"DCL2_CARIBBEAN_2011-11-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_CARIBBEAN_2011-11-01_5-7_PCV_Ships"}],"DCL2_BAHAMAS_2011-06-01_5-7_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Dream",d:"DD"}],"BirthDateYear":[{l:"Year"},{l:"1900",d:"1900"},{l:"1901",d:"1901"},{l:"1902",d:"1902"},{l:"1903",d:"1903"},{l:"1904",d:"1904"},{l:"1905",d:"1905"},{l:"1906",d:"1906"},{l:"1907",d:"1907"},{l:"1908",d:"1908"},{l:"1909",d:"1909"},{l:"1910",d:"1910"},{l:"1911",d:"1911"},{l:"1912",d:"1912"},{l:"1913",d:"1913"},{l:"1914",d:"1914"},{l:"1915",d:"1915"},{l:"1916",d:"1916"},{l:"1917",d:"1917"},{l:"1918",d:"1918"},{l:"1919",d:"1919"},{l:"1920",d:"1920"},{l:"1921",d:"1921"},{l:"1922",d:"1922"},{l:"1923",d:"1923"},{l:"1924",d:"1924"},{l:"1925",d:"1925"},{l:"1926",d:"1926"},{l:"1927",d:"1927"},{l:"1928",d:"1928"},{l:"1929",d:"1929"},{l:"1930",d:"1930"},{l:"1931",d:"1931"},{l:"1932",d:"1932"},{l:"1933",d:"1933"},{l:"1934",d:"1934"},{l:"1935",d:"1935"},{l:"1936",d:"1936"},{l:"1937",d:"1937"},{l:"1938",d:"1938"},{l:"1939",d:"1939"},{l:"1940",d:"1940"},{l:"1941",d:"1941"},{l:"1942",d:"1942"},{l:"1943",d:"1943"},{l:"1944",d:"1944"},{l:"1945",d:"1945"},{l:"1946",d:"1946"},{l:"1947",d:"1947"},{l:"1948",d:"1948"},{l:"1949",d:"1949"},{l:"1950",d:"1950"},{l:"1951",d:"1951"},{l:"1952",d:"1952"},{l:"1953",d:"1953"},{l:"1954",d:"1954"},{l:"1955",d:"1955"},{l:"1956",d:"1956"},{l:"1957",d:"1957"},{l:"1958",d:"1958"},{l:"1959",d:"1959"},{l:"1960",d:"1960"},{l:"1961",d:"1961"},{l:"1962",d:"1962"},{l:"1963",d:"1963"},{l:"1964",d:"1964"},{l:"1965",d:"1965"},{l:"1966",d:"1966"},{l:"1967",d:"1967"},{l:"1968",d:"1968"},{l:"1969",d:"1969"},{l:"1970",d:"1970"},{l:"1971",d:"1971"},{l:"1972",d:"1972"},{l:"1973",d:"1973"},{l:"1974",d:"1974"},{l:"1975",d:"1975"},{l:"1976",d:"1976"},{l:"1977",d:"1977"},{l:"1978",d:"1978"},{l:"1979",d:"1979"},{l:"1980",d:"1980"},{l:"1981",d:"1981"},{l:"1982",d:"1982"},{l:"1983",d:"1983"},{l:"1984",d:"1984"},{l:"1985",d:"1985"},{l:"1986",d:"1986"},{l:"1987",d:"1987"},{l:"1988",d:"1988"},{l:"1989",d:"1989"},{l:"1990",d:"1990"},{l:"1991",d:"1991"},{l:"1992",d:"1992"},{l:"1993",d:"1993"},{l:"1994",d:"1994"},{l:"1995",d:"1995"},{l:"1996",d:"1996"},{l:"1997",d:"1997"},{l:"1998",d:"1998"},{l:"1999",d:"1999"},{l:"2000",d:"2000"},{l:"2001",d:"2001"},{l:"2002",d:"2002"},{l:"2003",d:"2003"},{l:"2004",d:"2004"},{l:"2005",d:"2005"},{l:"2006",d:"2006"},{l:"2007",d:"2007"},{l:"2008",d:"2008"},{l:"2009",d:"2009"}],"DCL2_ALASKA_2011-09-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_ALASKA_2011-09-01_5-7_Ports"}],"DCL2_BAHAMAS_2011-01-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_BAHAMAS_2011-01-01_5-7_Ports"},{l:"0-4",d:"0-4",t:"DCL2_BAHAMAS_2011-01-01_0-4_Ports"}],"DCL2_TRANS_ATLANTIC_2010-09-01_14+_BCN_Ships":[{l:"Ship",d:""},{l:"Disney Magic",d:"DM"}],"DCL2_BAHAMAS_2011-06-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_BAHAMAS_2011-06-01_5-7_PCV_Ships"}],"DCL2_BAHAMAS_Months":[{l:"Choose a Date",d:""},{l:"September 2010",d:"2010-09-01",t:"DCL2_BAHAMAS_2010-09-01_Lengths"},{l:"October 2010",d:"2010-10-01",t:"DCL2_BAHAMAS_2010-10-01_Lengths"},{l:"November 2010",d:"2010-11-01",t:"DCL2_BAHAMAS_2010-11-01_Lengths"},{l:"December 2010",d:"2010-12-01",t:"DCL2_BAHAMAS_2010-12-01_Lengths"},{l:"January 2011",d:"2011-01-01",t:"DCL2_BAHAMAS_2011-01-01_Lengths"},{l:"February 2011",d:"2011-02-01",t:"DCL2_BAHAMAS_2011-02-01_Lengths"},{l:"March 2011",d:"2011-03-01",t:"DCL2_BAHAMAS_2011-03-01_Lengths"},{l:"April 2011",d:"2011-04-01",t:"DCL2_BAHAMAS_2011-04-01_Lengths"},{l:"May 2011",d:"2011-05-01",t:"DCL2_BAHAMAS_2011-05-01_Lengths"},{l:"June 2011",d:"2011-06-01",t:"DCL2_BAHAMAS_2011-06-01_Lengths"},{l:"July 2011",d:"2011-07-01",t:"DCL2_BAHAMAS_2011-07-01_Lengths"},{l:"August 2011",d:"2011-08-01",t:"DCL2_BAHAMAS_2011-08-01_Lengths"},{l:"September 2011",d:"2011-09-01",t:"DCL2_BAHAMAS_2011-09-01_Lengths"},{l:"October 2011",d:"2011-10-01",t:"DCL2_BAHAMAS_2011-10-01_Lengths"},{l:"November 2011",d:"2011-11-01",t:"DCL2_BAHAMAS_2011-11-01_Lengths"},{l:"December 2011",d:"2011-12-01",t:"DCL2_BAHAMAS_2011-12-01_Lengths"}],"DCL2_BAHAMAS_2011-04-01_0-4_PCV_Ships":[{l:"Ship",d:""},{l:"Disney Dream",d:"DD"}],"DCL2_MEXICAN_RIVIERA_2011-10-01_5-7_Ports":[{l:"Departure Port",d:""},{l:"Los Angeles, California",d:"LAX",t:"DCL2_MEXICAN_RIVIERA_2011-10-01_5-7_LAX_Ships"}],"DCL2_TRANS_ATLANTIC_Months":[{l:"Choose a Date",d:""},{l:"September 2010",d:"2010-09-01",t:"DCL2_TRANS_ATLANTIC_2010-09-01_Lengths"},{l:"May 2011",d:"2011-05-01",t:"DCL2_TRANS_ATLANTIC_2011-05-01_Lengths"},{l:"September 2011",d:"2011-09-01",t:"DCL2_TRANS_ATLANTIC_2011-09-01_Lengths"}],"DCL2_MEXICAN_RIVIERA_2011-10-01_5-7_LAX_Ships":[{l:"Ship",d:""},{l:"Disney Wonder",d:"DW"}],"DCL2_TRANS_PANAMA_CANAL_2011-01-01_Lengths":[{l:"Cruise Length",d:""},{l:"14+",d:"14+",t:"DCL2_TRANS_PANAMA_CANAL_2011-01-01_14+_Ports"}],"DCL2_MEXICAN_RIVIERA_2011-03-01_5-7_LAX_Ships":[{l:"Ship",d:""},{l:"Disney Wonder",d:"DW"}],"DCL2_BAHAMAS_2011-06-01_Lengths":[{l:"Cruise Length",d:""},{l:"0-4",d:"0-4",t:"DCL2_BAHAMAS_2011-06-01_0-4_Ports"},{l:"5-7",d:"5-7",t:"DCL2_BAHAMAS_2011-06-01_5-7_Ports"}],"DCL2_CARIBBEAN_2010-10-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_CARIBBEAN_2010-10-01_5-7_Ports"}],"DCL2_CARIBBEAN_2011-02-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_CARIBBEAN_2011-02-01_5-7_Ports"}],"DCLDestinations":[{l:"Choose a Destination"}],"DCL2_CARIBBEAN_2011-12-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_CARIBBEAN_2011-12-01_5-7_Ports"},{l:"8-13",d:"8-13",t:"DCL2_CARIBBEAN_2011-12-01_8-13_Ports"}],"DCL2_CARIBBEAN_2011-04-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_CARIBBEAN_2011-04-01_5-7_Ports"}],"DCL2_BAHAMAS_2011-03-01_Lengths":[{l:"Cruise Length",d:""},{l:"0-4",d:"0-4",t:"DCL2_BAHAMAS_2011-03-01_0-4_Ports"}],"DCL2_BAHAMAS_2011-02-01_Lengths":[{l:"Cruise Length",d:""},{l:"0-4",d:"0-4",t:"DCL2_BAHAMAS_2011-02-01_0-4_Ports"}],"DCL2_CARIBBEAN_2011-05-01_Lengths":[{l:"Cruise Length",d:""},{l:"5-7",d:"5-7",t:"DCL2_CARIBBEAN_2011-05-01_5-7_Ports"}],"DCL2_BAHAMAS_2011-01-01_0-4_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_BAHAMAS_2011-01-01_0-4_PCV_Ships"}],"DCL2_CARIBBEAN_2010-12-01_8-13_Ports":[{l:"Departure Port",d:""},{l:"Port Canaveral, Florida",d:"PCV",t:"DCL2_CARIBBEAN_2010-12-01_8-13_PCV_Ships"}]}})' );
	} catch ( e ) {
		return this.displayError( 'An error has occurred while loading the Disney Quick Quote business rules.' );
	}
	
	return true;
};

// parse aspects of our feed to store in memory the exact portions we need
// @param objRequest object - ajax returned object reference
DisneyQuickQuote.prototype.processBusinessRules = function() {
	var intChild = 0;
	
	// this loops through each option types in our config and processes them individually
	intChild = ( this.arrSupport.length - 1 );
	do {
		this.processGroup( this.arrSupport[ intChild ] );
	} while ( intChild-- );
	
	return true;
};

DisneyQuickQuote.prototype.createCalendarConfig = function( strId, dtRangeStart, dtRangeEnd ) {
	var objConfig = {
		target: document.body,
		dateRangeStart: new Date( dtRangeStart ),
		dateRangeEnd: new Date( dtRangeEnd ),
		showInput: true,
		monthLabels: this.objData.Prop.monthLabels.join( ',' )
	};
	
	return objConfig;
};

// process all of a specific SQQComponent
// @param strTagName string - string of what SQQComponent will be processed
DisneyQuickQuote.prototype.processGroup = function( strTagName ) {
	var intCount = 0;
	var intBU = 0;
	var intPO = 0;
	var strName = null;
	var strParentName = null;
	var nodeElement = null;
	var that = this;
	
	// we can use the assumption that if the SQQComponent exists in the product option, its length is not 0
	// our JSON data feed ensures this
	switch ( strTagName ) {
		case 'SQQTravelDates':
			var bSingleTextField = false;
			var bUseDropDown = false;
			var dtEnd;
			var dtStart;
			var dtToday;
			var dtTravel;
			var intChild = 0;
			var intCal1 = null;
			var intCal2 = null;
			var intMinBookTime = 1;
			var intTravelStartDate = 0;
			var intTravelStartMonth = 0;
			var intTravelStartYear = 0;
			var intDisplayStartDate = 0;
			var intDisplayStartMonth = 0;
			var intDisplayStartYear = 0;
			var intDisplayEndYear = 0;
			var intStartDaysFromToday = 0;
			var intRiskFactorDays = 0;
			var intRiskFactorMinutes = 0;
			var intDisplayDateRange = 0;
			var intUpdateAfter = -1;
			var strOperationalStartTime = null;
			var strOperationalEndTime = null;
			var strDateTimeType = null;
			var nodeArrivalMonth = null;
			var nodeArrivalDay = null;
			var nodeArrivalYear = null;
			var nodeArrivalDate = null;
			var nodeCalendarBtn1 = null;
			var nodeCalendarBtn2 = null;
			var nodeDepartureMonth = null;
			var nodeDepartureDay = null;
			var nodeDepartureYear = null;
			var nodeDepartureDate = null;
			var nodeTravelTime = null;
			var nodeOption = null;
			var objGroup;
			var objTravelTimeDropDown;
			var objData;
			
			// prep our calendar mouse click event
			this.addOpenCalendarMouseCheckEvent();
			
			// if our json data does not month labels, set the var to ''
			if ( !this.objData.Prop.monthLabels && typeof this.objData.Prop.monthLabels.length != 'undefined' ) {
				this.objData.Prop.monthLabels = Array( '' );
			}
			
			
			// loop through all sqqbusinessunits
			intBU = ( this.objData.Prop.BU.length - 1 );
			do {
				// loop through all sqqproductoptions
				intPO = ( this.objData.Prop.BU[ intBU ].PO.length - 1 );
				do {
					if ( typeof( this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTravelDates ) != 'undefined' ) {
						dtToday = new Date();
						dtToday.setToCalendarDate();
						bUseDropDown = false;
						intUpdateAfter = -1;
						
						strName = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTravelDates.name;
						bSingleTextField = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTravelDates.singleTextField;
						intMinBookTime = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTravelDates.minBookTime;
						intTravelStartDate = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTravelDates.travelStartDate;
						intTravelStartMonth = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTravelDates.travelStartMonth;
						intTravelStartYear = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTravelDates.travelStartYear;
						intDisplayStartDate = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTravelDates.displayStartDate;
						intDisplayStartMonth = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTravelDates.displayStartMonth;
						intDisplayStartYear = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTravelDates.displayStartYear;
						intDisplayEndYear = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTravelDates.displayEndYear;
						intStartDaysFromToday = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTravelDates.startDaysFromToday;
						intRiskFactorDays = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTravelDates.riskFactorDays;
						intRiskFactorMinutes = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTravelDates.riskFactorMinutes;
						intDisplayDateRange = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTravelDates.displayDateRange;
						strOperationalStartTime = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTravelDates.operationalStartTime;
						strOperationalEndTime = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTravelDates.operationalEndTime ;
						strTravelDateType = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTravelDates.travelDateType;
						objTravelTimeDropDown = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTravelDates.timeDropDown;
																	
						strParentName = this.objData.Prop.BU[ intBU ].value + '_' + this.objData.Prop.BU[ intBU ].PO[ intPO ].name;
						nodeCalendarBtn1 = document.getElementById( strParentName + '_' + strName + '_arrivalCalendarBtn' );
						nodeCalendarBtn2 = document.getElementById( strParentName + '_' + strName + '_departureCalendarBtn' );
						nodeTravelTime = document.getElementById( strParentName + '_' + objTravelTimeDropDown );
						
						// we only need specific elements if single text field is true
						if ( bSingleTextField ) {
							nodeArrivalDate = document.getElementById( strParentName + '_' + strName + '_arrivalDate' );
							nodeDepartureDate = document.getElementById( strParentName + '_' + strName + '_departureDate' );
						} else {
							nodeArrivalMonth = document.getElementById( strParentName + '_' + strName + '_arrivalMonth' );
							nodeArrivalDay = document.getElementById( strParentName + '_' + strName + '_arrivalDay' );
							nodeArrivalYear = document.getElementById( strParentName + '_' + strName + '_arrivalYear' );
							nodeDepartureMonth = document.getElementById( strParentName + '_' + strName + '_departureMonth' );
							nodeDepartureDay = document.getElementById( strParentName + '_' + strName + '_departureDay' );
							nodeDepartureYear = document.getElementById( strParentName + '_' + strName + '_departureYear' );
						}
						
						if ( !intRiskFactorDays ) {
							intRiskFactorDays = 0;
						}
						
						// all combo boxes and calendar buttons must exist for at least calendar 1 - 
						//there will always be at least one calendar displayed when the SQQTravelDate object is included in the 
						//module option
						if ( nodeCalendarBtn1 && ( ( !bSingleTextField && nodeArrivalMonth && nodeArrivalDay && nodeArrivalYear ) || ( bSingleTextField && nodeArrivalDate ) ) ) {
							// check our opt info data to preset our dates (important!)
							if ( typeof( this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDown ) != 'undefined' && typeof( this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDown.length ) != 'undefined' ) {
								intCount = ( this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDown.length - 1 );

								if ( intCount > -1 ) {

									do {
										// long if statement, checks dependency to make sure it's defined and set, then checks our group data from the xmlPointer
										if ( typeof( this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDown[ intCount ].dependency ) != 'undefined' && this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDown[ intCount ].dependency && typeof( this.objData.Groups[ this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDown[ intCount ].xmlPointer ] ) != 'undefined' ) {
											// make sure our group exists and has data
											objGroup = this.objData.Groups[ this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDown[ intCount ].xmlPointer ][ document.getElementById( strParentName + '_' + this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDown[ intCount ].xmlPointer ).selectedIndex ];
											if ( !objGroup || objGroup.length < 1 ) {
												continue;
											}

											// if our opt info code doesn't exist, end it
											if ( typeof( objGroup.t ) == 'undefined' || !this.objData.OptInfo[ objGroup.t ] ) {
												continue;
											}

											// for some reason we have a few items without a day/date, so lets put it to 1, then change it
											dtStart = new Date( dtToday );
											dtStart.setFullYear( this.objData.OptInfo[ objGroup.t ].travelStartYear, ( ( this.objData.OptInfo[ objGroup.t ].travelStartMonth * 1 ) - 1 ), 1 );
											if ( typeof( this.objData.OptInfo[ objGroup.t ].travelStartDate ) != 'undefined' && this.objData.OptInfo[ objGroup.t ].travelStartDate !== null ) {
												dtStart.setDate( this.objData.OptInfo[ objGroup.t ].travelStartDate );
											}

											// overwrite the travel info
											intTravelStartDate = dtStart.getDate();
											intTravelStartMonth = ( dtStart.getMonth() + 1 );
											intTravelStartYear = dtStart.getFullYear();
											bUseDropDown = true;

											// update our travel dates
											this.updateTravelDates( strParentName + '_' + strName + '_arrival', bSingleTextField, ( dtStart.getMonth() + 1 ), dtStart.getDate(), dtStart.getFullYear() );

											if (this.objData.OptInfo[ objGroup.t ].minBookTime && intDisplayDateRange > this.objData.OptInfo[ objGroup.t ].minBookTime) {
												dtStart.setDate( dtStart.getDate() + intDisplayDateRange );
											} else {
												dtStart.setDate( dtStart.getDate() + this.objData.OptInfo[ objGroup.t ].minBookTime );
											}

											this.updateTravelDates( strParentName + '_' + strName + '_departure', bSingleTextField, ( dtStart.getMonth() + 1 ), dtStart.getDate(), dtStart.getFullYear() );
											// set drop down # to update drop down selection after events
											intUpdateAfter = intCount;
											break;
										}
										
										// If the 'date-travel' option is selected let's go ahead and add the dates
										if ( strTravelDateType == 'date-time' && nodeTravelTime ) {
											if(this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDown[intCount].name == objTravelTimeDropDown) {

												nodeTravelTimeDropdown = document.getElementById( strParentName + '_' + this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDown[intCount].xmlPointer );
												intRiskFactorDays += this.setDefaultTime(nodeTravelTimeDropdown, new Date(), intRiskFactorMinutes, strOperationalStartTime, strOperationalEndTime);
												nodeTravelTime.className = 'SQQDropDownSelect';
											}
										}

									} while ( intCount-- );
								}
							}
							// javascript users can click the calendar button
							nodeCalendarBtn1.style.display = 'block';

							// ie fix for putting the calendar in the wrong position if the qq is too small
							if ( document.all ) {
								if ( this.arrAttributes.qqWidth < 260 ) {
									nodeCalendarBtn1.parentNode.style.width = '100%';
								}
							}
							
							// we can go ahead and create our start dates now
							dtStart = new Date( dtToday );

										
						
							if ( strTravelDateType == 'date-time'){
										
							// if a travel date is specified from our data, see if it's in the future
							// we need a date range start
							if ( intTravelStartYear > 0 && intTravelStartMonth > 0 && intTravelStartDate > 0 ) {
								dtTravel = new Date( dtStart );
								dtTravel.setFullYear( intTravelStartYear, ( intTravelStartMonth - 1 ), intTravelStartDate );

								// if the travel date is after than today's date, use that instead
								if ( dtStart.compare( dtTravel ) == -1 ) {
									dtStart = new Date( dtTravel );
								} else if ( !bUseDropDown ) { // travel date is in the past, today + intRiskFactorDays (defaults to 1)
									dtStart.setDate( ( dtStart.getDate() * 1 ) + intRiskFactorDays );
								}

								dtTravel = undefined;
							} else if ( !bUseDropDown ) { // no travel date specified, today + intRiskFactorDays (defaults to 1)
								dtStart.setDate( ( dtStart.getDate() * 1 ) + intRiskFactorDays );
							}

							// if not using a drop down, lets update our dates instead of relying on TEA
							if ( !bUseDropDown ) {
								dtTravel = new Date( dtStart );

								if ( intStartDaysFromToday > 0 && intRiskFactorDays < intStartDaysFromToday ) {
									dtTravel.setDate( ( dtTravel.getDate() * 1 ) + (intStartDaysFromToday - intRiskFactorDays) );
								}

								this.updateTravelDates( strParentName + '_' + strName + '_arrival', bSingleTextField, ( dtTravel.getMonth() + 1 ), dtTravel.getDate(), dtTravel.getFullYear() );

								if ( intDisplayDateRange > 0 ) {
									dtTravel.setDate( ( dtTravel.getDate() * 1 ) + intDisplayDateRange );
								}
							}

							// Calendar id's
							intCal1 = ( this.arrAttributes.qqCalendars.length );

							// set our ints
							this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTravelDates.arrival = intCal1;


							this.arrAttributes.qqCalendars[ intCal1 ] = {};

							// we instaniate a new object and pass it to our event setter so we can hold these values instead of by ref
							// store our data we need for the calendars to work properly
							objData = {
								minBookTime: intMinBookTime,
								displayDateRange: intDisplayDateRange,
								isArrival: true,
								departure: intCal1,
								parentName: strParentName,
								name: strParentName + '_' + strName + '_arrival',
								config: this.createCalendarConfig( strParentName + '_' + strName + '_arrivalCalendar', dtStart, dtEnd ),
								singleTextField: bSingleTextField,
								timeDropDown: nodeTravelTimeDropdown,
								riskFactorMinutes: intRiskFactorMinutes,
								operationalStartTime: strOperationalStartTime,
								operationalEndTime: strOperationalEndTime
							};

							this.addDisplayCalendarEvent( nodeCalendarBtn1, objData, intCal1, true );

							if ( bSingleTextField ) {
								this.addDisplayCalendarEvent( nodeArrivalDate, null, intCal1, false );
							}

							// our ending date range differs, add the min book time to start and end
							dtStart.setDate( ( ( dtStart.getDate() * 1 ) + intMinBookTime ) );

							objData = {
								minBookTime: intMinBookTime,
								isArrival: false,
								arrival: intCal1,
								parentName: strParentName,
								singleTextField: bSingleTextField
							};

							// our travel events covers date changes and selection handling for calendar
							this.addTravelEvents( this.arrAttributes.qqCalendars[ intCal1 ], this.arrAttributes.qqCalendars[ intCal1 ] );

							if ( intUpdateAfter > -1 ) {
								this.updateDropDownSelection( this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDown[ intUpdateAfter ].xmlPointer, strParentName, intUpdateAfter, 'initTravel', intBU, intPO );
							}

							} else {
							
						
							// all combo boxes and calendar buttons must exist
							if ( nodeCalendarBtn2 && ( ( nodeDepartureMonth && nodeDepartureDay && nodeDepartureYear ) || nodeDepartureDate  ) ) {
								// javascript users can click the calendar button
								nodeCalendarBtn2.style.display = 'block';

								// ie fix for putting the calendar in the wrong position if the qq is too small
								if ( document.all ) {
									if ( this.arrAttributes.qqWidth < 260 ) {
										nodeCalendarBtn2.parentNode.style.width = '100%';
									}
								}

								// we can go ahead and create our end dates now
								dtEnd = new Date( dtToday );

								// if a travel date is specified from our data, see if it's in the future
								// we need a date range start
								if ( intTravelStartYear > 0 && intTravelStartMonth > 0 && intTravelStartDate > 0 ) {
									dtTravel = new Date( dtStart );
									dtTravel.setFullYear( intTravelStartYear, ( intTravelStartMonth - 1 ), intTravelStartDate );

									// if the travel date is after than today's date, use that instead
									if ( dtStart.compare( dtTravel ) == -1 ) {
										dtStart = new Date( dtTravel );
									} else if ( !bUseDropDown ) { // travel date is in the past, today + intRiskFactorDays (defaults to 1)
										dtStart.setDate( ( dtStart.getDate() * 1 ) + intRiskFactorDays );
									}

									dtTravel = undefined;
								} else if ( !bUseDropDown ) { // no travel date specified, today + intRiskFactorDays (defaults to 1)
									dtStart.setDate( ( dtStart.getDate() * 1 ) + intRiskFactorDays );
								}

								// if not using a drop down, lets update our dates instead of relying on TEA
								if ( !bUseDropDown ) {
									dtTravel = new Date( dtStart );

									if ( intStartDaysFromToday > 0 && intRiskFactorDays < intStartDaysFromToday ) {
										dtTravel.setDate( ( dtTravel.getDate() * 1 ) + (intStartDaysFromToday - intRiskFactorDays) );
									}

									this.updateTravelDates( strParentName + '_' + strName + '_arrival', bSingleTextField, ( dtTravel.getMonth() + 1 ), dtTravel.getDate(), dtTravel.getFullYear() );

									if ( intDisplayDateRange > 0 ) {
										dtTravel.setDate( ( dtTravel.getDate() * 1 ) + intDisplayDateRange );
									}

									this.updateTravelDates( strParentName + '_' + strName + '_departure', bSingleTextField, ( dtTravel.getMonth() + 1 ), dtTravel.getDate(), dtTravel.getFullYear() );
								}

								// by default date range is going to end of (current + 2)/display years, minus the minimum book days
								if ( intDisplayEndYear ) {
									dtEnd.setFullYear( intDisplayEndYear, 11, ( 31 - intMinBookTime ) );
								} else {
									dtEnd.setFullYear( ( dtStart.getFullYear() + 2 ), 11, ( 31 - intMinBookTime ) );
								}

								// 2 calendar id's
								intCal1 = ( this.arrAttributes.qqCalendars.length );
								intCal2 = ( intCal1 + 1 );

								// set our ints
								this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTravelDates.arrival = intCal1;
								this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTravelDates.departure = intCal2;

								this.arrAttributes.qqCalendars[ intCal1 ] = {};
								this.arrAttributes.qqCalendars[ intCal2 ] = {};

								// we instaniate a new object and pass it to our event setter so we can hold these values instead of by ref
								// store our data we need for the calendars to work properly
								objData = {
									minBookTime: intMinBookTime,
									displayDateRange: intDisplayDateRange,
									isArrival: true,
									departure: intCal2,
									parentName: strParentName,
									name: strParentName + '_' + strName + '_arrival',
									config: this.createCalendarConfig( strParentName + '_' + strName + '_arrivalCalendar', dtStart, dtEnd ),
									singleTextField: bSingleTextField
								};

								this.addDisplayCalendarEvent( nodeCalendarBtn1, objData, intCal1, true );

								if ( bSingleTextField ) {
									this.addDisplayCalendarEvent( nodeArrivalDate, null, intCal1, false );
								}

								// our ending date range differs, add the min book time to start and end
								dtStart.setDate( ( ( dtStart.getDate() * 1 ) + intMinBookTime ) );
								dtEnd.setDate( ( ( dtEnd.getDate() * 1 ) + intMinBookTime ) );

								objData = {
									minBookTime: intMinBookTime,
									isArrival: false,
									arrival: intCal1,
									parentName: strParentName,
									name: strParentName + '_' + strName + '_departure',
									config: this.createCalendarConfig( strParentName + '_' + strName + '_departureCalendar', dtStart, dtEnd ),
									singleTextField: bSingleTextField
								};

								this.addDisplayCalendarEvent( nodeCalendarBtn2, objData, intCal2, true );

								if ( bSingleTextField ) {
									this.addDisplayCalendarEvent( nodeDepartureDate, null, intCal2, false );
								}

								// our travel events covers date changes and selection handling for calendar
								this.addTravelEvents( this.arrAttributes.qqCalendars[ intCal1 ], this.arrAttributes.qqCalendars[ intCal2 ] );

								if ( intUpdateAfter > -1 ) {
									this.updateDropDownSelection( this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDown[ intUpdateAfter ].xmlPointer, strParentName, intUpdateAfter, 'initTravel', intBU, intPO );
								}
							}
						}
					}
					}
				} while ( intPO-- );
			} while ( intBU-- );
			
			break;
		case 'SQQPartyMix':
			var nodeChildren = null;
			var nodeContainer = null;
			var nodeDisclaimer = null;
			var nodeLink = null;
			var nodeAlert = null;
			
			// loop through all sqqbusinessunits
			intBU = ( this.objData.Prop.BU.length - 1 );
			do {
				// loop through all sqqproductoptions
				intPO = ( this.objData.Prop.BU[ intBU ].PO.length - 1 );
				do {
					if ( typeof( this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQPartyMix ) != 'undefined' ) {
						strName = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQPartyMix.name;
						strParentName = this.objData.Prop.BU[ intBU ].value + '_' + this.objData.Prop.BU[ intBU ].PO[ intPO ].name;
						nodeChildren = document.getElementById( strParentName + '_' + strName + '_numChildren' );
						nodeContainer = document.getElementById( strParentName + '_' + strName + '_childContainer' );
						nodeDisclaimer = document.getElementById( strParentName + '_' + strName + '_disclaimer' );
						nodeLink = document.getElementById( strParentName + '_' + strName + '_disclaimerLink' );
						nodeAlert = document.getElementById( strParentName + '_' + strName + '_disclaimerAlert' );
						this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQPartyMix.currentChildren = -1;
						
						// if the children and container exist, add our events and go ahead and default our children box
						if ( nodeChildren && nodeContainer ) {
							this.addPartyMixEvent( strParentName, strName );
							
							// we execute this on init due to non-vendor html inclusion
							// meaning browsers could default a # if you refreshed after a selection
							this.updateNumChildren( strParentName, strName, 'init', intBU, intPO );
						}
						
						// this is separated due to disclaimers being optional
						if ( nodeDisclaimer && nodeLink && nodeAlert ) {
							// replace our href for the link, hide the default alert for non-JS users, and compact it with a link
							nodeLink.href = 'javascript:void(0);';
							nodeDisclaimer.style.display = 'block';
							nodeAlert.style.display = 'none';
							
							// child age disclaimer event for the link to change into our other layer (which used to cover the entire qq in a pretty way)
							this.addChildAgeDisclaimerEvent( strParentName + '_' + strName + '_disclaimer' );
						}
					}
				} while ( intPO-- );
			} while ( intBU-- );
			
			break;
		case 'SQQDropDownMulti':
			var strHTMLVarName1 = null;
			var strHTMLVarName2 = null;
			var bTargetSecond = null;
			nodeElement = null;
			var nodeSelect1 = null;
			var nodeSelect2 = null;
			
			// loop through all sqqbusinessunits
			intBU = ( this.objData.Prop.BU.length - 1 );
			do {
				// loop through all sqqproductoptions
				intPO = ( this.objData.Prop.BU[ intBU ].PO.length - 1 );
				do {
					if ( typeof( this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDownMulti ) != 'undefined' ) {
						intCount = ( this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDownMulti.length - 1 );
						do {
							bTargetSecond = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDownMulti[ intCount ].targetSecond;
							
							// we only need multi drop downs that have business rules (where #1 effects #2)
							if ( bTargetSecond ) {
								strName = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDownMulti[ intCount ].name;
								strParentName = this.objData.Prop.BU[ intBU ].value + '_' + this.objData.Prop.BU[ intBU ].PO[ intPO ].name;
								strHTMLVarName1 = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDownMulti[ intCount ].htmlVarName1;
								strHTMLVarName2 = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDownMulti[ intCount ].htmlVarName2;
								nodeElement = document.getElementById( strParentName + '_' + strName );
								nodeSelect1 = document.getElementById( strParentName + '_' + strName + '_' + strHTMLVarName1 );
								nodeSelect2 = document.getElementById( strParentName + '_' + strName + '_' + strHTMLVarName2 );
								
								if ( typeof( this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDownMulti[ intCount ].xmlPointer2 ) == 'undefined' ) {
									this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDownMulti[ intCount ].xmlPointer2 = '';
								}
								
								if ( nodeElement && nodeSelect1 && nodeSelect2 ) {
									// add our event to select1 to change select2
									this.addDropDownMultiEvent( nodeSelect1, intCount, strParentName + '_' + strName + '_' + strHTMLVarName1, strParentName + '_' + strName + '_' + strHTMLVarName2 );
									
									// initialize drop down change, this will set our internal var to our current select1/select2
									this.updateDropDownMultiSelection( intCount, strParentName + '_' + strName + '_' + strHTMLVarName1, strParentName + '_' + strName + '_' + strHTMLVarName2, 'init', intBU, intPO );
								}
							}
						} while ( intCount-- );
					}
				} while ( intPO-- );
			} while ( intBU-- );
			
			break;
		case 'SQQDropDown':
			var intChildCount = 0;
			
			// loop through all sqqbusinessunits
			intBU = ( this.objData.Prop.BU.length - 1 );
			do {
				// loop through all sqqproductoptions
				intPO = ( this.objData.Prop.BU[ intBU ].PO.length - 1 );
				do {
					// if we have any SQQDropDown's loop through them
					if ( typeof( this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDown ) != 'undefined' ) {
						intCount = ( this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDown.length - 1 );
						do {
							strName = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDown[ intCount ].xmlPointer;
							strParentName = this.objData.Prop.BU[ intBU ].value + '_' + this.objData.Prop.BU[ intBU ].PO[ intPO ].name;
							nodeElement = document.getElementById( strParentName + '_' + strName );
							
							if ( nodeElement ) {
								if ( typeof( this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDown[ intCount ].dependency ) != 'undefined' ) {
									// loop through sqqdropdown's for one's XMLPointer to match the dependency
									intChildCount = ( this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDown.length - 1 );
									
									do {
										if ( typeof( this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDown[ intChildCount ].htmlObjectName ) != 'undefined' && this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDown[ intCount ].dependency == this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDown[ intChildCount ].htmlObjectName ) {
        										// add our event to update our dependency, etc. if we found it
											this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDown[ intCount ].child = intChildCount;
											this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDown[ intChildCount ].targetData = null;
											this.addDropDownEvent( nodeElement, strName, strParentName, intCount );
											
											if ( strName == 'DCLCruises' ) {
												this.updateDropDownSelection( strName, strParentName, intCount, 'init', intBU, intPO );
											}
											
											break;
										}
									} while ( intChildCount-- );
								}
							}
						} while ( intCount-- );
					}
				} while ( intPO-- );
			} while ( intBU-- );
			
			break;
		case 'SQQTextBox':
			var nodeOverlay = null;
			
			// loop through all sqqbusinessunits
			intBU = ( this.objData.Prop.BU.length - 1 );
			do {
				// loop through all sqqproductoptions
				intPO = ( this.objData.Prop.BU[ intBU ].PO.length - 1 );
				do {
					// if we have any SQQTextBox's loop through them
					if ( typeof( this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTextBox ) != 'undefined' ) {
						intCount = ( this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTextBox.length - 1 );
						do {
							strName = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTextBox[ intCount ].name;
							strParentName = this.objData.Prop.BU[ intBU ].value + '_' + this.objData.Prop.BU[ intBU ].PO[ intPO ].name;
							nodeElement = document.getElementById( strParentName + '_' + strName + '_Text' );
							nodeOverlay = document.getElementById( strParentName + '_' + strName + '_Overlay' );
							
							if ( nodeElement && nodeOverlay ) {
								if ( typeof( this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQTextBox[ intCount ].overlayLabel ) != 'undefined' ) {
									// this textbox has an overlay, add event to hide/display
									this.addTextBoxOverlayEvent( nodeElement, nodeOverlay, strName, strParentName );
								}
							}

							//create AUTO_COMPLETE on the fly
							
							var objList = this.objData.Groups[strParentName + '_' + strName];
							if(objList){
								if(objList.length != 0){
									nodeAutoComp = document.getElementById(strParentName + '_' + strName +'_AutoCmp');
									var aNames = [];
									for (i = 0; i < objList.length; i++){
										aNames[i] = objList[i].l;
									}
									if(nodeElement && nodeAutoComp && aNames.length !=0){
										this.autoCompleteObj.push(new DisneyQuickQuote.AutoComplete(strParentName, aNames,nodeElement, nodeAutoComp));
									}
								}
							}
						} while ( intCount-- );
					}
				} while ( intPO-- );
			} while ( intBU-- );
			
			break;
		case 'SQQGrouping':
			var nodeLabel = null;
			var nodeGroup = null;
			
			// loop through all sqqbusinessunits
			intBU = ( this.objData.Prop.BU.length - 1 );
			do {
				// loop through all sqqproductoptions
				intPO = ( this.objData.Prop.BU[ intBU ].PO.length - 1 );
				do {
					// if we have any SQQGroupings's loop through them
					if ( typeof( this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQGrouping ) != 'undefined' ) {
						intCount = ( this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQGrouping.length - 1 );
						do {
							strName = this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQGrouping[ intCount];
							strParentName = this.objData.Prop.BU[ intBU ].value + '_' + this.objData.Prop.BU[ intBU ].PO[ intPO ].name;
							nodeLabel = document.getElementById( strParentName + '_' + strName + '_Label' );
							nodeGroup = document.getElementById( strParentName + '_' + strName + '_Group' );
							
							// if the item has no label, then no points of adding event, cause you can't click anything
							// for a blank clickable item (like an image background), you should use a &nbsp;, then use CSS to stretch the object and this will pick it up like normal
							if ( nodeLabel && nodeGroup ) {
								// add our event to hide/display the group
								this.addGroupEvent( strParentName + '_' + strName );
							}
						} while ( intCount-- );
					}
				} while ( intPO-- );
			} while ( intBU-- );
			
			break;
		case 'SQQProductOption':
			var bChecked = false;
			nodeContainer = null;
			
			// loop through all sqqbusinessunits
			intBU = ( this.objData.Prop.BU.length - 1 );
			do {
				bChecked = false;
				strName = this.objData.Prop.BU[ intBU ].value;
				// loop through all sqqproductoptions
				intPO = ( this.objData.Prop.BU[ intBU ].PO.length - 1 );
				
				do {
					nodeElement = document.getElementById( strName + '_' + this.objData.Prop.BU[ intBU ].PO[ intPO ].name );
					nodeContainer = document.getElementById( strName + '_' + this.objData.Prop.BU[ intBU ].PO[ intPO ].name + '_Container' );
					
					if ( nodeElement || nodeContainer ) {
						// add event for when the radio button is checked
						this.addProductOptionsEvent( strName + '_' + this.objData.Prop.BU[ intBU ].PO[ intPO ].name, intPO );
						
						if ( nodeElement && nodeContainer ) {
							// if it came checked, display our form and save it
							// if the PO is > 0 then always hide if not checked, if the PO is 0 and an item is checked, hide it
							// otherwise leave it alone, because we're defaulting to it anyways
							if ( nodeElement.checked ) {
								bChecked = true;
								this.objData.Prop.BU[ intBU ].currentPO = intPO;
							} else if ( intPO > 0 || ( intPO === 0 && bChecked ) ) {
								nodeContainer.className = 'SQQProductOption hidden';
							}
						} else {
							bChecked = true;
							this.objData.Prop.BU[ intBU ].currentPO = intPO;
						}
					}
				} while ( intPO-- );
				
				// if no items came checked and we found our first product option, check it, display it, save it
				if ( !bChecked ) {
					// I was storing the name in a var, but the additional var checks, etc.
					// can't offer a good performance diff for sacrificing memory
					// only check if there's more than 1 -- meaning, if there actually is a radio button
					if ( this.objData.Prop.BU[ intBU ].PO.length > 1 ) {
						document.getElementById( strName + '_' + this.objData.Prop.BU[ intBU ].PO[ 0 ].name ).checked = true;
					}
					
					this.objData.Prop.BU[ intBU ].currentPO = 0;
				}
			} while ( intBU-- );
			
			break;
		case 'SQQBusinessUnit':
			var bSelected = false;
			
			// if we have multiple business units, below will return an object
			var nodeMulti = document.getElementById( 'SQQMultiBU' );
			
			// if our node is set, then add event to the combo box
			if ( typeof( nodeMulti ) != 'undefined' && nodeMulti !== null ) {
				this.addMultiBusinessUnitEvent();
				
				// loop through all sqqbusinessunits
				intBU = ( this.objData.Prop.BU.length - 1 );
				do {
					strName = this.objData.Prop.BU[ intBU ].value;
					nodeContainer = document.getElementById( strName + '_Container' );
					
					if ( nodeContainer ) {
						if ( nodeMulti.value == strName ) {
							bSelected = true;
							this.objData.Prop.currentBU = intBU;
						} else {
							nodeContainer.className = 'SQQBusinessUnit hidden';
						}
					}
				} while ( intBU-- );
				
				// if no item was selected, default to the first data
				if ( !bSelected ) {
					document.getElementById( this.objData.Prop.BU[ 0 ].value + '_Container' ).className = 'SQQBusinessUnit';
				}
			}
			
			// if no item was selected, default to the first data
			// this is also for non-multi BUs so we know what BU we're using wihout having to do multi checks
			if ( !bSelected ) {
				this.objData.Prop.currentBU = 0;
			}
			
			break;
		default:
			break;
	}
	
	return true;
};

// event adds
// handle events for multi business unit combo box
DisneyQuickQuote.prototype.addMultiBusinessUnitEvent = function() {
	var that = this;
	var nodeMulti = document.getElementById( 'SQQMultiBU' );
	
	this.addEvent( nodeMulti, 'change', function() { that.updateMultiBUSelection( 'change' ); }, false );
	this.addEvent( nodeMulti, 'keyup', function() { that.updateMultiBUSelection( 'keyup' ); }, false );
};

// handle events for product option radio buttons and submit button for form
// @param strElement string - element id for product option
// @param intPO integer - the index key of the BU where this PO is
DisneyQuickQuote.prototype.addProductOptionsEvent = function( strElement, intPO ) {
	var that = this;
	var nodeElement = document.getElementById( strElement );
	var nodeSubmit = document.getElementById( strElement + '_Submit' );
	
	// if there are multiple sqqproductoptions, we need to add event to radio button
	if ( nodeElement ) {
		// ie needs extra events since it won't fire "change" for key up and click events
		if ( document.all ) {
			// this is EXTREMELY ugly... but it was the ONLY way to get IE to cooperate.. so deal with it
			// the timeout call first corrects the behavior of the divs rendering BELOW the QQ (it actually looks exactly right if you're not hiding any other QQ)
			// the parent node is to correct the button location.. for some strange reason it couldn't show until you adjusted the height AFTER the 100ms
			// none of this works outside of the setTimeout, you have to give IE time to fix itself
			this.addEvent( nodeElement, 'click', function() {
				that.switchProductOptions( strElement, intPO, 'click' );
				setTimeout( function() {
					that.switchProductOptions( strElement, intPO, 'click' );
					document.getElementById( strElement + '_Submit' ).parentNode.style.height = '100%';
					document.getElementById( strElement + '_Submit' ).parentNode.style.height = 'auto';
				}, 1 );
			}, false );
			this.addEvent( nodeElement, 'keyup', function() { that.switchProductOptions( strElement, intPO, 'keyup' ); }, false );
		} else {
			// add event for radio switching
			this.addEvent( nodeElement, 'change', function() { that.switchProductOptions( strElement, intPO, 'change' ); }, false );
		}
	}
	
	// add event for submit button if it was found (it's optional)
	if ( nodeSubmit ) {
		this.addEvent( nodeSubmit, 'click', function() { that.submitProductOption( strElement, 'click' ); }, false );
	}
	
	return true;
};

// handle events for hiding/displaying grouping
// @param strName string - element id for sqqcomponent
DisneyQuickQuote.prototype.addGroupEvent = function( strName ) {
	var that = this;
	
	// add event to click, only 1, so I didn't want to make a var for the element
	this.addEvent( document.getElementById( strName + '_Label' ), 'click', function() { that.displayGroup( strName, 'click' ); }, false );
	
	if ( document.getElementById( strName + '_OpenedLabel') ) {
		this.addEvent( document.getElementById( strName + '_OpenedLabel' ), 'click', function() { that.displayGroup( strName, 'click' ); }, false );
	}
	
	return true;
};

// handle events for children count to display age container
// @param strParentName string - element id for parent element
// @param strName string - element id for sqqcomponent
DisneyQuickQuote.prototype.addPartyMixEvent = function( strParentName, strName ) {
	var that = this;
	var nodeChildren = document.getElementById( strParentName + '_' + strName + '_numChildren' );
	
	// combo boxes need change (all) and keyup (ie) events to update children age
	if ( document.all ) {
		// see the function: DisneyQuickQuote.prototype.addProductOptionsEvent for details on why we're doing this setTimeout
		this.addEvent( nodeChildren, 'change', function() {
			that.updateNumChildren( strParentName, strName, 'change' );
			setTimeout(function() {
				document.getElementById( strParentName + '_Submit' ).parentNode.style.height = '100%';
				document.getElementById( strParentName + '_Submit' ).parentNode.style.height = 'auto';
			}, 1 );
		}, false );
		this.addEvent( nodeChildren, 'keyup', function() {
			that.updateNumChildren( strParentName, strName, 'keyup' );
			setTimeout(function() {
				document.getElementById( strParentName + '_Submit' ).parentNode.style.height = '100%';
				document.getElementById( strParentName + '_Submit' ).parentNode.style.height = 'auto';
			}, 1 );
		}, false );
	} else {
		this.addEvent( nodeChildren, 'change', function() { that.updateNumChildren( strParentName, strName, 'change' ); }, false );
		this.addEvent( nodeChildren, 'keyup', function() { that.updateNumChildren( strParentName, strName, 'keyup' ); }, false );
	}
	
	return true;
};

// handle event for link to display disclaimer, only added if it exists
// @param strName string - element id for sqqcomponent
DisneyQuickQuote.prototype.addChildAgeDisclaimerEvent = function( strName ) {
	var that = this;
	
	// add event to display disclaimer, only 1, so I didn't want to make a var for the element
	this.addEvent( document.getElementById( strName ), 'click', function() { that.displayChildAgeDisclaimer( strName, 'click' ); }, false );
	return true;
};

// handle events for multi drop down selection changes
// @param nodeSelect object - first drop down element to attach events to
// @param strElement string - element id for 1st drop down
// @param strElement2 string - element id for 2nd drop down
DisneyQuickQuote.prototype.addDropDownMultiEvent = function( nodeSelect, intNode, strElement, strElement2 ) {
	var that = this;
	
	// combo boxes need change (all) and keyup (ie) events to update drop down multi selection
	this.addEvent( nodeSelect, 'change', function() { that.updateDropDownMultiSelection( intNode, strElement, strElement2, 'change' ); }, false );
	this.addEvent( nodeSelect, 'keyup', function() { that.updateDropDownMultiSelection( intNode, strElement, strElement2, 'keyup' ); }, false );
	return true;
};

// handle events for drop down dependency selection changes
// @param nodeSelect object - first drop down element to attach events to
// @param strParentName string - element id for parent element
// @param strName string - element id for sqqcomponent
DisneyQuickQuote.prototype.addDropDownEvent = function( nodeSelect, strName, strParentName, intNode ) {
	var that = this;
	
	// combo boxes need change (all) and keyup (ie) events to update drop down selection
	this.addEvent( nodeSelect, 'change', function() { that.updateDropDownSelection( strName, strParentName, intNode, 'change' ); }, false );
	this.addEvent( nodeSelect, 'keyup', function() { that.updateDropDownSelection( strName, strParentName, intNode, 'keyup' ); }, false );
	return true;
};

// handle events for textbox overlay label hide/display
// @param nodeInput object - textbox input
// @param nodeOverlay object - overlay span object
// @param strParentName string - element id for parent element
// @param strName string - element id for sqqcomponent
DisneyQuickQuote.prototype.addTextBoxOverlayEvent = function( nodeInput, nodeOverlay, strName, strParentName ) {
	var that = this;
	
	// focus is for hiding, blur is for showing
	this.addEvent( nodeInput, 'focus', function() { that.updateTextBoxOverlay( strName, strParentName, true, false, 'focus' ); }, false );
	this.addEvent( nodeOverlay, 'click', function() { that.updateTextBoxOverlay( strName, strParentName, true, true, 'overlay' ); }, false );
	this.addEvent( nodeInput, 'blur', function() { that.updateTextBoxOverlay( strName, strParentName, false, false, 'blur' ); }, false );
	return true;
};

// handle event for image link to display calendar
// @param nodeButton object - calendar button that displays the calendar
// @param objData object - reference of data object to duplicate
// @param intCal integer - index of what calendar we're dealing with
// @param bSetData boolean - if true, set our calendar data
DisneyQuickQuote.prototype.addDisplayCalendarEvent = function( nodeButton, objData, intCal, bSetData ) {
	var that = this;
	if ( bSetData ) {
		this.arrAttributes.qqCalendars[ intCal ] = objData;
	}
	
	this.addEvent( nodeButton, 'click', function() { that.displayCalendar( that.arrAttributes.qqCalendars[ intCal ], intCal, 'click' ); }, false );
	return true;
};

// handle events for all the combo boxes that modify travel dates
// @param strName string - element id of sqqcomponent
// @param strParentName string - element id of parent
// @param intCal integer - index of what calendar we're dealing with
DisneyQuickQuote.prototype.addTravelEvents = function( objArrival, objDeparture ) {
	var that = this;
	
	// we assume that they are the same
	if ( objArrival.singleTextField ) {
		// update arrival and departure inputs, refer to updateSingleTravelDate function for details
		// since each is only used once, we're not setting extra vars for it
		this.addEvent( document.getElementById( objArrival.name + 'Date' ), 'change', function() { that.updateSingleTravelDate( objArrival, false, 'change' ); }, false );
		this.addEvent( document.getElementById( objDeparture.name + 'Date' ), 'change', function() { that.updateSingleTravelDate( objDeparture, false, 'change' ); }, false );
		
		// add our function for when users click a date on the calendar to update our combo boxes (and force update is true)
		objArrival._fChange = function() {
			that.updateSingleTravelDate( objArrival, true, 'click' );
		};
		objDeparture._fChange = function() {
			that.updateSingleTravelDate( objDeparture, true, 'click' );
		};
	} else {
		var nodeArrivalMonth = document.getElementById( objArrival.name + 'Month' );
		var nodeArrivalDay = document.getElementById( objArrival.name + 'Day' );
		var nodeArrivalYear = document.getElementById( objArrival.name + 'Year' );
		var nodeDepartureMonth = document.getElementById( objDeparture.name + 'Month' );
		var nodeDepartureDay = document.getElementById( objDeparture.name + 'Day' );
		var nodeDepartureYear = document.getElementById( objDeparture.name + 'Year' );
		
		// update all arrival and departure selects, refer to updateTravelDate function for details
		this.addEvent( nodeArrivalMonth, 'change', function() { that.updateTravelDate( objArrival, false, 'change' ); }, false );
		this.addEvent( nodeArrivalMonth, 'keyup', function() { that.updateTravelDate( objArrival, false, 'keyup' ); }, false );
		this.addEvent( nodeArrivalDay, 'change', function() { that.updateTravelDate( objArrival, false, 'change' ); }, false );
		this.addEvent( nodeArrivalDay, 'keyup', function() { that.updateTravelDate( objArrival, false, 'keyup' ); }, false );
		this.addEvent( nodeArrivalYear, 'change', function() { that.updateTravelDate( objArrival, false, 'change' ); }, false );
		this.addEvent( nodeArrivalYear, 'keyup', function() { that.updateTravelDate( objArrival, false, 'keyup' ); }, false );
		this.addEvent( nodeDepartureMonth, 'change', function() { that.updateTravelDate( objDeparture, false, 'change' ); }, false );
		this.addEvent( nodeDepartureMonth, 'keyup', function() { that.updateTravelDate( objDeparture, false, 'keyup' ); }, false );
		this.addEvent( nodeDepartureDay, 'change', function() { that.updateTravelDate( objDeparture, false, 'change' ); }, false );
		this.addEvent( nodeDepartureDay, 'keyup', function() { that.updateTravelDate( objDeparture, false, 'keyup' ); }, false );
		this.addEvent( nodeDepartureYear, 'change', function() { that.updateTravelDate( objDeparture, false, 'change' ); }, false );
		this.addEvent( nodeDepartureYear, 'keyup', function() { that.updateTravelDate( objDeparture, false, 'keyup' ); }, false );
		
		// add our function for when users click a date on the calendar to update our combo boxes (and force update is true)
		objArrival._fChange = function() {
			that.updateTravelDate( objArrival, true, 'click' );
		};
		objDeparture._fChange = function() {
			that.updateTravelDate( objDeparture, true, 'click' );
		};
	}
	
	return true;
};

// add's event to document/window to check for our open calendar
DisneyQuickQuote.prototype.addOpenCalendarMouseCheckEvent = function() {
	var that = this;
	// add our event to check for mouse click, arguments[0] is equivilent to event
	if ( document.all ) {
		// ie uses document instead of window, it doesn't span across everything, but it's the only event that'll work correctly
		this.addEvent( document, 'click', function() { that.checkOpenCalendar( arguments[0], that ); }, false );
	} else {
		this.addEvent( window, 'click', function() { that.checkOpenCalendar( arguments[0], that ); }, false );
	}
	return true;
};

// event process
// updates multi business unit data (displays/hides divs)
// @param x string - name of event
DisneyQuickQuote.prototype.updateMultiBUSelection = function( x ) {
	var nodeMulti = document.getElementById( 'SQQMultiBU' );
	
	// if our container doesn't exist, stop, don't change
	if ( typeof( document.getElementById( nodeMulti.value + '_Container' ) ) == 'undefined' ) {
		return false;
	}
	
	// hide our current business unit and show the new one
	document.getElementById( this.objData.Prop.BU[ this.objData.Prop.currentBU ].value + '_Container' ).className = 'SQQBusinessUnit hidden';
	document.getElementById( nodeMulti.value + '_Container' ).className = 'SQQBusinessUnit';
	
	// see global rules, we're assuming selectedIndex is 1:1 with array index
	this.objData.Prop.currentBU = nodeMulti.selectedIndex;
};

// displays/hides div when product options are selected
// @param strElement string - element id of product option
// @param x string - name of event
DisneyQuickQuote.prototype.switchProductOptions = function( strElement, intPO, x ) {
	// we set this to a variable since it's used twice and the value being set is a little complex
	var strName = this.objData.Prop.BU[ this.objData.Prop.currentBU ].value + '_' + this.objData.Prop.BU[ this.objData.Prop.currentBU ].PO[ this.objData.Prop.BU[ this.objData.Prop.currentBU ].currentPO ].name;
	// hide our current product option from our current business unit
	document.getElementById( strName  + '_Container' ).className = 'SQQProductOption hidden';
	document.getElementById( strName + '_InputDisplay' ).className = 'SQQProductOptionOffContainer';
	document.getElementById( strElement + '_Container' ).className = 'SQQProductOption';
	document.getElementById( strElement + '_InputDisplay' ).className = 'SQQProductOptionOnContainer';
	
	this.objData.Prop.BU[ this.objData.Prop.currentBU ].currentPO = intPO;
	
	return true;
};

// hides/displays the grouping of elements
// @param strElement string - element id of product option
// @param x string - name of event
DisneyQuickQuote.prototype.displayGroup = function( strElement, x ) {
	var nodeElement = document.getElementById( strElement );
	var nodeOpened = document.getElementById( strElement + '_OpenedLabel' );
	var nodeClosed = document.getElementById( strElement + '_Label' );
	
	if ( nodeElement.className == 'SQQGrouping SQQGroupingHide' ) {
		nodeElement.className = 'SQQGrouping SQQGroupingDisplay';
		
		if ( nodeOpened && nodeClosed ) {
			nodeOpened.style.display = 'block';
			nodeClosed.style.display = 'none';
		}
	} else {
		nodeElement.className = 'SQQGrouping SQQGroupingHide';
		
		if ( nodeOpened && nodeClosed ) {
			nodeOpened.style.display = 'none';
			nodeClosed.style.display = 'block';
		}
	}
};

// submits the selected product option of the selected business unit
// @param strElement string - element id of product option
// @param x string - name of event
DisneyQuickQuote.prototype.submitProductOption = function( strElement, x ) {
	if ( !document.getElementById( strElement + '_Form' ) ) {
		return false;
	}
	
	// I wouldn't normally do this, but this function interacts with this set of data a LOT, it out-performances the usage of more memory
	var objBU = this.objData.Prop.BU[ this.objData.Prop.currentBU ];
	var objPO = objBU.PO[ objBU.currentPO ];
	var dtArrival;
	var dtDeparture;
	var intCount;
	var intMax;
	var nodeElement;
	var arrErrors = [];
	
	// make sure we're checking the one we're on
	// if we're somehow not on the same form than our JS thinks we are, we have no choice but to submit them
	if ( objBU.value + '_' + objPO.name != strElement ) {
		document.getElementById( strElement + '_Form' ).submit();
		return true;
	}
	
	// a sqqtraveldates must exist for either check
	if ( typeof( objPO.SQQTravelDates ) != 'undefined' ) {
		var bDropDown = false;
		var objTravel = objPO.SQQTravelDates;
		dtArrival = new Date();
		dtArrival.setToCalendarDate();
		dtDeparture = new Date( dtArrival );
		var strTime = "";
		
		if ( typeof( objPO.SQQDropDown ) != 'undefined'  ) {
			var nodeDropDown;
			var nodeTarget;
			var strTarget = '';
			var intDropDown = ( objPO.SQQDropDown.length - 1 );
			
			do {
				// Handle all dining related warning messages
				if(objPO.SQQTravelDates.timeDropDown == objPO.SQQDropDown[ intDropDown ].name){
					nodeDropDown = document.getElementById( strElement + '_' + objPO.SQQDropDown[ intDropDown ].xmlPointer );
					
					// Make sure user has entered a dining time
					if (typeof(this.objData.Groups[ objPO.SQQDropDown[ intDropDown ].xmlPointer ][ nodeDropDown.selectedIndex ].d) == 'undefined') {
						if ( typeof( this.objData.Prop.listAllErrors ) != 'undefined' && this.objData.Prop.listAllErrors ) {
							arrErrors.push( this.objData.Prop.errors.strDiningTimeBlank );
						} else {
							return this.displaySubmitError( strElement, this.objData.Prop.errors.strDiningTimeBlank );
						}
					}
					
					// Make sure the user isn't trying to set a time that has already past
					if ( nodeDropDown.options[nodeDropDown.selectedIndex].disabled ) {
						if ( typeof( this.objData.Prop.listAllErrors ) != 'undefined' && this.objData.Prop.listAllErrors ) {
							arrErrors.push( this.objData.Prop.errors.strPastDiningTime );
						} else {
							return this.displaySubmitError( strElement, this.objData.Prop.errors.strPastDiningTime );
						}
					}
				}
				
				// if the child does not have a dependency, there are no rules for it to affect sqqtraveldates, skip it
				// also ensure it has the child attached from our business rules processing
				if ( typeof( objPO.SQQDropDown[ intDropDown ].dependency ) == 'undefined' || typeof( objPO.SQQDropDown[ intDropDown ].child ) == 'undefined' ) {
					continue;
				}
				
				nodeDropDown = document.getElementById( strElement + '_' + objPO.SQQDropDown[ intDropDown ].xmlPointer );
				nodeTarget = document.getElementById( strElement + '_' + objPO.SQQDropDown[ intDropDown ].dependency );
				
				// does the drop down or target not exist
				if ( !nodeDropDown || !nodeTarget ) {
					continue;
				}
				
				// we assume this is the correct data, but for whatever strange reason, it MAY not, and this needs to compensate
				if ( this.objData.Groups[ objPO.SQQDropDown[ intDropDown ].xmlPointer ][ nodeDropDown.selectedIndex ].d == nodeDropDown.value ) {
					strTarget = this.objData.Groups[ objPO.SQQDropDown[ intDropDown ].xmlPointer ][ nodeDropDown.selectedIndex ].t;
				} else {
					intCount = ( this.objData.Groups[ objPO.SQQDropDown[ intDropDown ].xmlPointer ].length - 1 );
					do {
						if ( this.objData.Groups[ objPO.SQQDropDown[ intDropDown ].xmlPointer ][ intCount ].d == nodeDropDown.value ) {
							strTarget = this.objData.Groups[ objPO.SQQDropDown[ intDropDown ].xmlPointer ][ nodeDropDown.selectedIndex ].t;
							break;
						}
					} while ( intCount-- );
				}
				
				// if our target does not exist
				if ( !strTarget ) {
					continue;
				}
				
				// if this target has NO data relevent to dates, simply skip over it
				if ( typeof( this.objData.OptInfo[ strTarget ].travelStartDate ) == 'undefined' && typeof( this.objData.OptInfo[ strTarget ].travelStartMonth ) == 'undefined' && typeof( this.objData.OptInfo[ strTarget ].travelStartYear ) == 'undefined' && typeof( this.objData.OptInfo[ strTarget ].travelEndDate ) == 'undefined' && typeof( this.objData.OptInfo[ strTarget ].travelEndMonth ) == 'undefined' && typeof( this.objData.OptInfo[ strTarget ].travelEndYear ) == 'undefined' ) {
					continue;
				}
				
				// set our drop down boolean to true to stop the sqqtraveldates check, since we're doing the sqqdropdown check now
				bDropDown = true;
				
				// for some reason we have a few items without a day/date, so lets put it to 1
				if ( typeof( this.objData.OptInfo[ strTarget ].travelStartDate ) == 'undefined' || this.objData.OptInfo[ strTarget ].travelStartDate === null ) {
					this.objData.OptInfo[ strTarget ].travelStartDate = 1;
				}
				
				var nodeArrivalDate = document.getElementById( strElement + '_' + objTravel.name + '_arrivalDate' );
				var nodeDepartureDate = document.getElementById( strElement + '_' + objTravel.name + '_departureDate' );
								
				// pull our arrival/departure dates
				if ( objPO.SQQTravelDates.singleTextField ) {
					if ( dtArrival.validate( nodeArrivalDate.value ) ) {
						dtArrival.setTime( Date.parse( nodeArrivalDate.value ) );
					}
					
					if ( dtDeparture.validate( nodeDepartureDate.value ) ) {
						dtDeparture.setTime( Date.parse( nodeDepartureDate.value ) );
					}
				} else {
					dtArrival.setFullYear( document.getElementById( strElement + '_' + objTravel.name + '_arrivalYear' ).value, ( ( document.getElementById( strElement + '_' + objTravel.name + '_arrivalMonth' ).value * 1 ) - 1 ), document.getElementById( strElement + '_' + objTravel.name + '_arrivalDay' ).value );
					dtDeparture.setFullYear( document.getElementById( strElement + '_' + objTravel.name + '_departureYear' ).value, ( ( document.getElementById( strElement + '_' + objTravel.name + '_departureMonth' ).value * 1 ) - 1 ), document.getElementById( strElement + '_' + objTravel.name + '_departureDay' ).value );
				}
				
				objTravel = this.objData.OptInfo[ strTarget ];
				break;
			} while ( intDropDown-- );
		}
		
		// if no drop downs are affecting our data, lets pull the data from the SQQTravelDates instead
		if ( !bDropDown ) {
			nodeArrivalDate = document.getElementById( strElement + '_' + objTravel.name + '_arrivalDate' );
			nodeDepartureDate = document.getElementById( strElement + '_' + objTravel.name + '_departureDate' );
			
			if ( nodeArrivalDate && nodeDepartureDate ) {
				if ( dtArrival.validate( nodeArrivalDate.value ) ) {
					dtArrival.setTime( Date.parse( nodeArrivalDate.value ) );
				}
				
				if ( dtDeparture.validate( nodeDepartureDate.value ) ) {
					dtDeparture.setTime( Date.parse( nodeDepartureDate.value ) );
				}
			} else if (nodeArrivalDate) {
				if ( dtArrival.validate( nodeArrivalDate.value ) ) {
					dtArrival.setTime( Date.parse( nodeArrivalDate.value ) );
				}
			} else {
				dtArrival.setFullYear( document.getElementById( strElement + '_' + objTravel.name + '_arrivalYear' ).value, ( ( document.getElementById( strElement + '_' + objTravel.name + '_arrivalMonth' ).value * 1 ) - 1 ), document.getElementById( strElement + '_' + objTravel.name + '_arrivalDay' ).value );
				dtDeparture.setFullYear( document.getElementById( strElement + '_' + objTravel.name + '_departureYear' ).value, ( ( document.getElementById( strElement + '_' + objTravel.name + '_departureMonth' ).value * 1 ) - 1 ), document.getElementById( strElement + '_' + objTravel.name + '_departureDay' ).value );
			}
		}
		
	
		// make sure departure time even exists - if it doesn't then change it to the arrival date
	
		if (!nodeDepartureDate) {
			dtDeparture = dtArrival;
		}
	
		// if the arrival date is after the departure date
		if ( dtArrival > dtDeparture ) {
			if ( typeof( this.objData.Prop.listAllErrors ) != 'undefined' && this.objData.Prop.listAllErrors ) {
				arrErrors.push( this.objData.Prop.errors.strArriveAfterDepart );
			} else {
				return this.displaySubmitError( strElement, this.objData.Prop.errors.strArriveAfterDepart );
			}
		}
		
		var intDayDiff = Math.round( ( dtDeparture.getTime() - dtArrival.getTime() ) / ( 1000 * 60 * 60 * 24 ) );
		
		// if the date diff is less than minimum booking time
		// or if the date diff is greater than max booking time
		if ( intDayDiff < objTravel.minBookTime  && objTravel.travelDateType == 'date-range') {
			if ( typeof( this.objData.Prop.listAllErrors ) != 'undefined' && this.objData.Prop.listAllErrors ) {
				arrErrors.push( this.objData.Prop.errors.strStayTooShort.replace( /\[N\]/gi, objTravel.minBookTime ) );
			} else {
				return this.displaySubmitError( strElement, this.objData.Prop.errors.strStayTooShort.replace( /\[N\]/gi, objTravel.minBookTime ) );
			}
		} else if ( intDayDiff > objTravel.maxBookTime ) {
			if ( typeof( this.objData.Prop.listAllErrors ) != 'undefined' && this.objData.Prop.listAllErrors ) {
				arrErrors.push( this.objData.Prop.errors.strStayTooLong.replace( /\[N\]/gi, objTravel.maxBookTime ) );
			} else {
				return this.displaySubmitError( strElement, this.objData.Prop.errors.strStayTooLong.replace( /\[N\]/gi, objTravel.maxBookTime ) );
			}
		}
		
		var dtMinMax = new Date();
		dtMinMax.setToCalendarDate();
		
		// if a travel date is specified from our data, see if it's in the future
		// we need a date range start
		if ( objTravel.travelStartYear > 0 && objTravel.travelStartMonth > 0 && objTravel.travelStartDate > 0 ) {
			var dtTravel = new Date( dtMinMax );
			dtTravel.setFullYear( objTravel.travelStartYear, ( objTravel.travelStartMonth - 1 ), objTravel.travelStartDate );
			
			// if the travel date is after than today's date, use that instead
			if ( dtMinMax.compare( dtTravel ) == -1 ) {
				dtMinMax = new Date( dtTravel );
			} else { // travel date is in the past, today + 1
				dtMinMax.setDate( ( dtMinMax.getDate() * 1 ) + 1 );
			}
			
			dtTravel = undefined;
		} else { // no travel date specified, today + 1
			dtMinMax.setDate( ( dtMinMax.getDate() * 1 ) + 1 );
		}
		
		// dtMinMax is currently today, they can't book before today
		if ( dtArrival < dtMinMax && objTravel.travelDateType == 'date-range') {
			if ( typeof( this.objData.Prop.listAllErrors ) != 'undefined' && this.objData.Prop.listAllErrors ) {
				arrErrors.push( this.objData.Prop.errors.strArriveIsBeforeAllowable );
			} else {
				return this.displaySubmitError( strElement, this.objData.Prop.errors.strArriveIsBeforeAllowable );
			}
		}
		
		strOutOfDateRangeError = this.objData.Prop.errors.strArriveIsAfterMaxDate;
		
		//calculate MaxDate in form of current day + number of day
		if(((objTravel.travelEndYear * 1) == 0) && ((objTravel.travelEndMonth * 1) == 0) && ((objTravel.travelEndDate * 1) > 0))
		{
			//dtMinMax is current Date + x number of day
			dtMinMax.setDate(dtMinMax.getDate()+(objTravel.travelEndDate * 1));
			strOutOfDateRangeError = this.objData.Prop.errors.strArrivalAfterXDays;
		}
		
		//calculate MaxDate with a harcoded end date.
		else{
			// dtMinMax is currently end of display year
			dtMinMax.setFullYear( objTravel.travelEndYear, ( objTravel.travelEndMonth - 1 ), objTravel.travelEndDate );
		}
		
		
		if ( dtDeparture > dtMinMax ) {
			if ( typeof( this.objData.Prop.listAllErrors ) != 'undefined' && this.objData.Prop.listAllErrors ) {
				arrErrors.push( this.objData.Prop.errors.strArriveIsAfterMaxDate );
			} else {
				return this.displaySubmitError( strElement, strOutOfDateRangeError );
			}
		}
	}
	
	// if we have sqqtextbox, check if any of them are required
	if ( typeof( objPO.SQQTextBox ) != 'undefined' ) {
		intMax = objPO.SQQTextBox.length;
		intCount = 0;
		
		do {
			
			nodeElement = document.getElementById(strElement + '_' + objPO.SQQTextBox[ intCount ].name + '_Text');
			
			//check to see if AutoFill text is matched.
			if(nodeElement){
				autoMatch = nodeElement.getAttribute('autoMatch');
				if(autoMatch && autoMatch == 'false'){
					if ( typeof( objPO.SQQTextBox[ intCount ].requiredError ) != 'undefined' ) {
						if ( typeof( this.objData.Prop.listAllErrors ) != 'undefined' && this.objData.Prop.listAllErrors ) {
							arrErrors.push( objPO.SQQTextBox[ intCount ].requiredError );
						} else {
							return this.displaySubmitError( strElement, objPO.SQQTextBox[ intCount ].requiredError );
						}
					} else {
						if ( typeof( this.objData.Prop.listAllErrors ) != 'undefined' && this.objData.Prop.listAllErrors ) {
							arrErrors.push( 'Please select a valid restaurant from the dropdown.' );
						} else {
							return this.displaySubmitError( strElement, this.objData.Prop.errors.strInvalidRestaurantName );
						}
					}
				}
			}
			
			if ( typeof( objPO.SQQTextBox[ intCount ].isRequired ) != 'undefined' && objPO.SQQTextBox[ intCount ].isRequired === true ) {	
				if ( nodeElement && ( typeof( nodeElement.value ) == 'undefined' || ( typeof( nodeElement.value ) != 'undefined' && nodeElement.value.length < 1 ) ) ) {
					if ( typeof( objPO.SQQTextBox[ intCount ].requiredError ) != 'undefined' ) {
						if ( typeof( this.objData.Prop.listAllErrors ) != 'undefined' && this.objData.Prop.listAllErrors ) {
							arrErrors.push( objPO.SQQTextBox[ intCount ].requiredError );
						} else {
							return this.displaySubmitError( strElement, objPO.SQQTextBox[ intCount ].requiredError );
						}
					} else {
						if ( typeof( this.objData.Prop.listAllErrors ) != 'undefined' && this.objData.Prop.listAllErrors ) {
							arrErrors.push( 'A required field was left blank.' );
						} else {
							return this.displaySubmitError( strElement, 'A required field was left blank.' );
						}
					}
				}
			}
			
			++intCount;
		} while ( intCount < intMax );
	}
	
	// if we have sqqdropdown, check if any of them are required
	if ( typeof( objPO.SQQDropDown ) != 'undefined' ) {
		intMax = objPO.SQQDropDown.length;
		intCount = 0;
		
		do {
			if ( typeof( objPO.SQQDropDown[ intCount ].isRequired ) != 'undefined' && objPO.SQQDropDown[ intCount ].isRequired === true ) {
				nodeElement = document.getElementById( strElement + '_' + objPO.SQQDropDown[ intCount ].xmlPointer );
	
				if ( nodeElement && ( typeof( nodeElement.value ) == 'undefined' || ( typeof( nodeElement.value ) != 'undefined' && nodeElement.value.length < 1 ) ) ) {
					if ( typeof( objPO.SQQDropDown[ intCount ].requiredError ) != 'undefined' ) {
						if ( typeof( this.objData.Prop.listAllErrors ) != 'undefined' && this.objData.Prop.listAllErrors ) {
							arrErrors.push( objPO.SQQDropDown[ intCount ].requiredError );
						} else {
							return this.displaySubmitError( strElement, objPO.SQQDropDown[ intCount ].requiredError );
						}
					} else {
						if ( typeof( this.objData.Prop.listAllErrors ) != 'undefined' && this.objData.Prop.listAllErrors ) {
							arrErrors.push( 'A required field was left blank.' );
						} else {
							return this.displaySubmitError( strElement, 'A required field was left blank.' );
						}
					}
				}
			}
			
			++intCount;
		} while ( intCount < intMax );
	}
	
	// if we have sqqpartymix, check if any of them are required
	if ( typeof( objPO.SQQPartyMix ) != 'undefined' ) {
		if ( typeof( objPO.SQQPartyMix.maxGuests ) != 'undefined' && objPO.SQQPartyMix.maxGuests > 0 ) {
			var intGuests = 0;
			
			nodeElement = document.getElementById( strElement + '_' + objPO.SQQPartyMix.name + '_numAdults' );
			if ( nodeElement && nodeElement.value ) {
				intGuests += ( nodeElement.value * 1 );
			}
			
			nodeElement = document.getElementById( strElement + '_' + objPO.SQQPartyMix.name + '_numChildren' );
			if ( nodeElement && nodeElement.value ) {
				intGuests += ( nodeElement.value * 1 );
			}
			
			if ( intGuests > objPO.SQQPartyMix.maxGuests ) {
				if ( typeof( this.objData.Prop.listAllErrors ) != 'undefined' && this.objData.Prop.listAllErrors ) {
					arrErrors.push( this.objData.Prop.errors.strTooManyGuests.replace( /\[N\]/gi, objPO.SQQPartyMix.maxGuests ) );
				} else {
					return this.displaySubmitError( strElement, this.objData.Prop.errors.strTooManyGuests.replace( /\[N\]/gi, objPO.SQQPartyMix.maxGuests ) );
				}
			}
		}
	}
	
	if ( typeof( this.objData.Prop.listAllErrors ) != 'undefined' && this.objData.Prop.listAllErrors ) {
		if ( arrErrors && arrErrors.length > 0 ) {
			return this.displaySubmitError( strElement, arrErrors.join( '<br />' ) );
		}
	}
	
	// at this point all data is valid, process ready-to-submit
	// if the product option supports tracking and the functions exist (internal only), fire it off
	if ( typeof( objPO.trackingLinkId ) != 'undefined' && objPO.trackingLinkId !== null ) {
		if ( typeof( s_wdpro ) != 'undefined' && typeof( s_wdpro.trackLink) != 'undefined' ) {
			s_wdpro.trackLink( document.getElementById( strElement + '_Submit' ), objPO.trackingLinkId );
		}
	}
	
	
	
	document.getElementById( strElement + '_Form' ).submit();
	return true;
};
// update the amount of child age combo boxes displayed from the number of children
DisneyQuickQuote.prototype.updateNumChildren = function( strParentName, strName, strEvent, intOverrideBU, intOverridePO ) {
	var intBU = ( ( typeof( intOverrideBU ) == 'undefined' ) ? this.objData.Prop.currentBU : intOverrideBU );
	var intPO = ( ( typeof( intOverridePO ) == 'undefined' ) ? this.objData.Prop.BU[ this.objData.Prop.currentBU ].currentPO : intOverridePO );
	var nodeChildren = document.getElementById( strParentName + '_' + strName + '_numChildren' );
	var intChildren = nodeChildren.options[ nodeChildren.selectedIndex ].value;
	
	// if the number of children matches what we currently show, do not update
	if ( this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQPartyMix.currentChildren == intChildren ) {
		return false;
	}
	
	// save our count
	this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQPartyMix.currentChildren = intChildren;
	var nodeContainer = document.getElementById( strParentName + '_' + strName + '_childContainer' );
	
	// if at least 1 child is coming, display the container, otherwise hide it
	if ( intChildren > 0 ) {
		// take the last value we have, this is supposed to be the highest value (e.g. 6)
		var intCount = nodeChildren.options[ ( nodeChildren.options.length - 1 ) ].value;
		
		// loop through our containers based on our count we just got, then hide/display based on what they selected
		do {
			if ( typeof( document.getElementById( strParentName + '_' + strName + '_ageContainer' + intCount ) ) != 'undefined' ) {
				document.getElementById( strParentName + '_' + strName + '_ageContainer' + intCount ).className = ( ( intCount > intChildren ) ? 'SQQPartyMixChildAgeCount SQQPartyMixChildAgeCountHide' : 'SQQPartyMixChildAgeCount SQQPartyMixChildAgeCountDisplay' );
			}
		} while ( --intCount );
		
		nodeContainer.className = 'SQQPartyMixChildAgeContainer';
	} else {
		nodeContainer.className = 'SQQPartyMixChildAgeContainer hidden';
	}
	
	return true;
};
// generates the popup/message for "why is this required?" usually
// @param strName string - element id of child disclaimer
// @param strEvent string - the event that fired this function
DisneyQuickQuote.prototype.displayChildAgeDisclaimer = function ( strName, strEvent ) {
	// pull the body and head from the HTML that is generated for non-JS users
	this.displayMessage( document.getElementById( strName + 'Body' ).innerHTML, document.getElementById( strName + 'Head' ).innerHTML, this.objData.Prop.errors.strCloseLabel );
	
	return true;
};
// hides any element, essentially
// currently used for the child age disclaimer and submit/validation errors
// @param strName string - element id of popup
// @param strEvent string - the event that fired this function
DisneyQuickQuote.prototype.hidePopup = function ( strName, strEvent ) {
	
	if ( typeof( document.body.style.maxHeight ) == 'undefined' ) {
		this.loopElementsWithCallback( document.getElementById( this.arrAttributes.qqElement ).getElementsByTagName( 'select' ), function( node ) {
			node.style.visibility = '';
		} );
	}
	
	if (document.getElementById( strName )) {
		document.getElementById( strName ).style.display = 'none';
	}
		
	return true;
};

// action function to calculate the default time - current hour + 90 minutes per biz rule BR.A.17.13
// @param nodeElement object - object referencing the select element
// @param currTime object - object referencing current date and time
// @param riskFactorMinutes int - integer referencing the number of minutes to add to the current hour 
// @param startTime string - string referencing the starting operational hour for the restaurants
// @param endTime string - string referencing the ending operational hour for the restaurants - current time should never pass it
DisneyQuickQuote.prototype.setDefaultTime = function( nodeElement, currTime, riskFactorMinutes, startTime, endTime ) {

	// Calculate how many hours and minutes need to be added to the current time for a new default hour
	var addHours = Math.floor(riskFactorMinutes / 60);
	var addMin = riskFactorMinutes % 60;
	var riskFactorMin = 0;	// This value will be changed if hour is after ending time - book tomorrow
	
	var dtEndTime = new Date (currTime.toDateString() + ' ' + endTime);
	
	// Check to see if it's daylight savings and add the timezone as set in the CMS to the current UTC time
	
	
	// Take current time and turn to UTC time so to easily change to the time set by the timezone
	var curr_hour = currTime.getUTCHours() + (-4);
	var curr_date = currTime.getUTCDate();
	var curr_min = currTime.getUTCMinutes();

	// if time is in the AM
	if(curr_hour < 0){
		curr_hour += 24;
	}
		
	// Check to see if current time is after the last possible booking time
	currTime.setHours(curr_hour);
	currTime.setMinutes(curr_min);
		
	if(dtEndTime.compare(currTime) == -1 || currTime.getDate() > dtEndTime.getDate()) {
		currTimeStr = startTime;
		riskFactorMin = 1;
	}
	
	curr_hour += addHours;
	curr_min += addMin;
	
	// Set new current default time
	currTime.setHours(curr_hour);
	currTime.setMinutes(curr_min);
	
	// Make sure minutes added are calculated currectly
	currTime = this.setNewTimeMinutes(currTime);
		
	if(dtEndTime.compare(currTime) == -1) {
		currTimeStr = startTime;
		riskFactorMin = 1;
	}
	
	curr_hour = currTime.getHours();
	curr_min = currTime.getMinutes();
	
	// Add any missign leading zeros
	if(curr_min == '0') {
	 	curr_min = '00';
	}
	
	// Change time to 12 hour format
	a_p = this.setAMPM(curr_hour);
	
	// Set hour in the AM/PM format
	curr_hour = this.setAMPMCurrentHour(curr_hour);
	
	// Add any missign leading zeros
		if(curr_hour.toString().length == 1) {
		 	curr_hour = '0' + curr_hour;
	}
	
	// Create comparison string
	if(riskFactorMin == 0) {
		currTimeStr = curr_hour + ":" + curr_min +" "+ a_p;
	}
	
	// Disable all past hours from the current available hour	
	this.disableTimeDropdown(nodeElement, currTimeStr);
	
	return riskFactorMin;
};


// action function to load drop down data, always returns true
// @param nodeElement object - object referencing the select element
// @param arrData array - array of objects that associate "l" and "d" for the values of the drop down
DisneyQuickQuote.prototype.loadDropDown = function( nodeElement, arrData ) {
	// remove all items before populating
	if ( nodeElement.length > 0 ) {
		do {
			nodeElement.remove( 0 );
		} while ( nodeElement.length );
	}
	
	// make sure our data exists and has a length
	if ( arrData && arrData.length > 0 ) {
		// loop through our array and grab options
		var nodeOption;
		var intCount = 0;
		var intTotal = arrData.length;
		
		// we need to add in order so we cannot use our efficient decrement loops
		do {
			// add the node data to our record
			nodeOption = document.createElement( 'option' );
			nodeOption.text = arrData[ intCount ].l.replace( /&amp;/gi, '&' );
			nodeOption.value = ( ( typeof( arrData[ intCount ].d ) != 'undefined' ) ? arrData[ intCount ].d : '' );
			
			// ie catch, firefox, safari, etc. first
			try {
				nodeElement.add( nodeOption, null );
			} catch ( e ) {
				nodeElement.add( nodeOption );
			}
			
			++intCount;
		} while ( intCount < intTotal );
	}
	
	return true;
};

// this event is only attached to multidropdown's who have set "targetSecond" to true
// this updates the second combo/drop down based on the value of the first
// @param intNode integer - the item corresponding to the current BU/PO
// @param strElement1 string - element id of first select
// @param strElement1 string - element id of second select
// @param strEvent string - the event that fired this function
DisneyQuickQuote.prototype.updateDropDownMultiSelection = function ( intNode, strElement1, strElement2, strEvent, intOverrideBU, intOverridePO ) {
	var nodeElement1 = document.getElementById( strElement1 );
	var intBU = ( ( typeof( intOverrideBU ) == 'undefined' ) ? this.objData.Prop.currentBU : intOverrideBU );
	var intPO = ( ( typeof( intOverridePO ) == 'undefined' ) ? this.objData.Prop.BU[ this.objData.Prop.currentBU ].currentPO : intOverridePO );
	
	// see if our first combo actually has a 2nd value, separated by the '|' char
	var intLoc = nodeElement1.options[ nodeElement1.selectedIndex ].value.indexOf( '|' );
	
	// if the 2nd value exists, get all the text after the '|' char
	if ( intLoc == -1 ) {
		return false;
	}
	
	var strNewValues = nodeElement1.options[ nodeElement1.selectedIndex ].value.substr( ( intLoc + 1 ) );
	var nodeElement2 = document.getElementById( strElement2 );
	
	// if there was any text after the '|', continue with the second combo box, and does the data exist
	if ( strNewValues || typeof( this.objData.Groups[ strNewValues ] ) != 'undefined' ) {
		// if the second select data is what we're already using, don't reprocess
		if ( strNewValues == this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDownMulti[ intNode ].xmlPointer2 ) {
			nodeElement2.parentNode.style.display = 'block';
			return true;
		}
		
		// set our record 
		this.objData.Prop.BU[ intBU ].PO[ intPO ].SQQDropDownMulti[ intNode ].xmlPointer2 = strNewValues;
		
		// load all drop down data
		this.loadDropDown( nodeElement2, this.objData.Groups[ strNewValues ] );
		
		// wait until all the DOM edition is added before displaying the combo box again
		nodeElement2.parentNode.style.display = 'block';
	} else {
		// if there is nothing 
		nodeElement2.parentNode.style.display = 'none';
	}
};

// this function was developed to consolidate setting travel dates
// @param strName string - ID name we prepend
// @param bSingle boolean - true/false if the travel dates uses single text or not
// @param intMonth int - month we're setting
// @param intDay int - day we're setting
// @param intYear int - year we're setting
DisneyQuickQuote.prototype.updateTravelDates = function ( strName, bSingle, intMonth, intDay, intYear ) {
	if ( bSingle ) {
		document.getElementById( strName + 'Date' ).value = intMonth + '/' + intDay + '/' + intYear;
	} else {
		var nodeMonth = document.getElementById( strName + 'Month' );
		var nodeDay = document.getElementById( strName + 'Day' );
		var nodeYear = document.getElementById( strName + 'Year' );
		
		nodeMonth.value = intMonth;
		nodeYear.value = intYear;
		this.updateDaysInMonth( nodeMonth, nodeDay, nodeYear );
		nodeDay.value = intDay;
	}
	
	return true;
};

// this event is only attached to textbox's that have overlay labels
// will automatically hide/display if the content is null
// @param strName string - name of our textbox
// @param strParentName string - name of our parent
// @param bIsFocus boolean - true if this event is focus, false if blur
// @param bSetFocus boolean - true if this event should set focus, false if not
// @param strEvent string - the event that fired this function
DisneyQuickQuote.prototype.updateTextBoxOverlay = function ( strName, strParentName, bIsFocus, bSetFocus, strEvent ) {
	var nodeElement = document.getElementById( strParentName + '_' + strName + '_Text' );
	var nodeOverlay = document.getElementById( strParentName + '_' + strName + '_Overlay' );
	
	if ( bSetFocus ) {
		nodeElement.focus();
	}
	
	// always hide if being focused
	if ( bIsFocus ) {
		nodeOverlay.className = 'SQQTextBoxOverlayLabelHide';
	} else {
		if ( typeof( nodeElement.value ) != 'undefined'  ) {
			if ( nodeElement.value && nodeElement.value.length > 0 ) {
				nodeOverlay.className = 'SQQTextBoxOverlayLabelHide';
			} else {
				nodeOverlay.className = 'SQQTextBoxOverlayLabel';
			}
		} else {
			nodeOverlay.className = 'SQQTextBoxOverlayLabel';
		}
	}
	
	return true;
};

// this event is only attached to drop downs who have a dependency
// this updates the second drop down and travel dates
// @param strName string - name of our drop down
// @param strParentName string - name of our drop down
// @param strEvent string - the event that fired this function
DisneyQuickQuote.prototype.updateDropDownSelection = function ( strName, strParentName, intNode, strEvent, intOverwriteBU, intOverwritePO ) {
	var nodeElement = document.getElementById( strParentName + '_' + strName );
	var intBU = ( ( typeof( intOverwriteBU ) == 'undefined' ) ? this.objData.Prop.currentBU : intOverwriteBU );
	var intPO = ( ( typeof( intOverwritePO ) == 'undefined' ) ? this.objData.Prop.BU[ this.objData.Prop.currentBU ].currentPO : intOverwritePO );
	
	var objPO = this.objData.Prop.BU[ intBU ].PO[ intPO ];
	var nodeSelect = document.getElementById( strParentName + '_' + objPO.SQQDropDown[ objPO.SQQDropDown[ intNode ].child ].xmlPointer );
	var strDataName = strName;
	var objData;
	
	if ( typeof( objPO.SQQDropDown[ intNode ].targetData ) != 'undefined' && objPO.SQQDropDown[ intNode ].targetData ) {
		strDataName = objPO.SQQDropDown[ intNode ].targetData ;
	}
	
	// make sure our drop down has a value
	if ( !nodeElement.value ) {
		// if it's blank and it's child has a default value, lets send that data
		if ( !this.objData.Groups[ objPO.SQQDropDown[ objPO.SQQDropDown[ intNode ].child ].xmlPointer ] ) {
			return false;
		} else {
			objData = this.objData.Groups[ objPO.SQQDropDown[ objPO.SQQDropDown[ intNode ].child ].xmlPointer ];
			objPO.SQQDropDown[ objPO.SQQDropDown[ intNode ].child ].targetData = null;
		}
	} else {
		// does our data not exist or have no entries?
		var objGroup = this.objData.Groups[ strDataName ][ nodeElement.selectedIndex ];
		
		if ( !objGroup || objGroup.length < 1 || ( typeof( objGroup.a ) != 'undefined' && objGroup.a.length < 1 ) ) {
			nodeSelect.className = 'SQQDropDownSelect SQQDropDownSelectHidden';
			
			return false;
		}
		
		
		// dcl is special.. I don't know why
		if ( strDataName == 'DCLCruises' ) {
			objData = objGroup.a;
		} else if ( typeof( objGroup.t ) == 'undefined') { // if our opt info code doesn't exist, end it
			// well, the target data is null, lets just go back the default selection, if it exists
			if ( !this.objData.Groups[ objPO.SQQDropDown[ objPO.SQQDropDown[ intNode ].child ].xmlPointer ] ) {
				return false;
			} else {
				objData = this.objData.Groups[ objPO.SQQDropDown[ objPO.SQQDropDown[ intNode ].child ].xmlPointer ];
				objPO.SQQDropDown[ objPO.SQQDropDown[ intNode ].child ].targetData = null;
			}
		} else {
			if ( !this.objData.Groups[ objGroup.t ] && !this.objData.OptInfo[ objGroup.t ] ) {
				return false;
			}
			
			// "already shown" logic, if a selected item has the same target data, no need to refresh
			// no need to even force display to visible, because the data should already be visible if it was already changed
			if ( objPO.SQQDropDown[ objPO.SQQDropDown[ intNode ].child ].targetData == objGroup.t ) {
				return false;
			}
			
			objPO.SQQDropDown[ objPO.SQQDropDown[ intNode ].child ].targetData = objGroup.t; // moved here to save data
			
			if ( this.objData.Groups[ objGroup.t ] ) {
				objData = this.objData.Groups[ objGroup.t ];
			} else {
				// if an opt info code was found, lets change our data
				var objOptInfo = this.objData.OptInfo[ objGroup.t ];
				objData = objOptInfo.d;
				
				// does this PO have an SQQTravelDate ?
				if ( typeof( objPO.SQQTravelDates ) != 'undefined' ) {
					// check our calendars and create them if they haven't been created
					this.checkCalendar( this.arrAttributes.qqCalendars[ objPO.SQQTravelDates.arrival ], true );
					this.checkCalendar( this.arrAttributes.qqCalendars[ objPO.SQQTravelDates.departure ], true );
					
					var dtStart = new Date();
					dtStart.setToCalendarDate();
					var dtEnd = new Date( dtStart );
					
					// if our date is set and any month but today, then we can set it
					if ( ( typeof( objOptInfo.travelStartDate ) != 'undefined' && objOptInfo.travelStartDate !== null ) || ( typeof( objOptInfo.travelStartDate ) == 'undefined' && objOptInfo.travelStartMonth != ( dtStart.getMonth() + 1 ) ) ) {
						// lets put the date to 1, then change it if we have a date
						dtStart.setFullYear( objOptInfo.travelStartYear, ( ( objOptInfo.travelStartMonth * 1 ) - 1 ), 1 );
						
						if ( typeof( objOptInfo.travelStartDate ) != 'undefined' && objOptInfo.travelStartDate !== null ) {
							dtStart.setDate( objOptInfo.travelStartDate );
						}
					}
					
					// if our date is set and any month but today, then we can set it
					if ( ( typeof( objOptInfo.travelEndDate ) != 'undefined' && objOptInfo.travelEndDate !== null ) || ( typeof( objOptInfo.travelEndDate ) == 'undefined' && objOptInfo.travelEndMonth != ( dtEnd.getMonth() + 1 ) ) ) {
						// lets put the date to 1, then change it if we have a date
						dtEnd.setFullYear( objOptInfo.travelEndYear, ( ( objOptInfo.travelEndMonth * 1 ) - 1 ), 1 );
						
						if ( typeof( objOptInfo.travelEndDate ) != 'undefined' && objOptInfo.travelEndDate !== null ) {
							dtEnd.setDate( objOptInfo.travelEndDate );
						}
					}
					
					// we can't let them arrive on the last day, because then their departure date would be past the date range
					dtEnd.setDate( dtEnd.getDate() - objOptInfo.minBookTime );
					
					// update our travel dates and date ranges
					this.updateTravelDates( strParentName + '_' + objPO.SQQTravelDates.name + '_arrival', objPO.SQQTravelDates.singleTextField, ( dtStart.getMonth() + 1 ), dtStart.getDate(), dtStart.getFullYear() );
					this.arrAttributes.qqCalendars[ objPO.SQQTravelDates.arrival ].calendar.setDateFromInputs();
					this.arrAttributes.qqCalendars[ objPO.SQQTravelDates.arrival ].calendar.setDateRange( dtStart, dtEnd );
					this.arrAttributes.qqCalendars[ objPO.SQQTravelDates.arrival ].minBookTime = objOptInfo.minBookTime;
					
					// now departure
					var dtDisplay = new Date( dtStart );
					
					if (objPO.SQQTravelDates.displayDateRange >= objOptInfo.minBookTime) {
						dtDisplay.setDate( dtDisplay.getDate() + objPO.SQQTravelDates.displayDateRange );
					} else {
						dtDisplay.setDate( dtDisplay.getDate() + objOptInfo.minBookTime );
					}
					
					dtStart.setDate( dtStart.getDate() + objOptInfo.minBookTime );
					dtEnd.setDate( dtEnd.getDate() + objOptInfo.minBookTime );
					
					this.updateTravelDates( strParentName + '_' + objPO.SQQTravelDates.name + '_departure', objPO.SQQTravelDates.singleTextField, ( dtDisplay.getMonth() + 1 ), dtDisplay.getDate(), dtDisplay.getFullYear() );
					this.arrAttributes.qqCalendars[ objPO.SQQTravelDates.departure ].calendar.setDateFromInputs();
					this.arrAttributes.qqCalendars[ objPO.SQQTravelDates.departure ].calendar.setDateRange( dtStart, dtEnd );
				}
			}
		}
	}
	
	// consolidated loading drop down data
	nodeSelect.className = 'SQQDropDownSelect';
	this.loadDropDown( nodeSelect, objData );
	
	// does this child have another child? if so, lets setup that data too!
	if ( typeof( objPO.SQQDropDown[ objPO.SQQDropDown[ intNode ].child ].child ) != 'undefined' && objPO.SQQDropDown[ objPO.SQQDropDown[ intNode ].child ].child ) {
		return this.updateDropDownSelection( objPO.SQQDropDown[ objPO.SQQDropDown[ intNode ].child ].xmlPointer, strParentName, objPO.SQQDropDown[ intNode ].child, 'inherit', intBU, intPO );
	}
	
	return true;
};

// intializes a calendar for us
// @param objEntry object - Calendar object that we're checking
// @param bPreventAutoCheck boolean - If this is true, we do not check for arrival/departure
DisneyQuickQuote.prototype.checkCalendar = function( objEntry, bPreventAutoCheck ) {
	if ( typeof( objEntry.calendar ) == 'undefined' ) {
		// we should create the arrival calendar first, if it's not and not prevented
		if ( !objEntry.isArrival && !bPreventAutoCheck ) {
			this.checkCalendar( this.arrAttributes.qqCalendars[ objEntry.arrival ], true );
		}
		
		// is the entry a single text field or 3 combos
		if ( objEntry.singleTextField ) {
			objEntry.calendar = new Calendar( objEntry.name + 'Date', objEntry.config );
		} else {
			objEntry.calendar = new Calendar( objEntry.name + 'Month', objEntry.name + 'Day', objEntry.name + 'Year', objEntry.config );
		}
		
		objEntry.calendar.draw(); // draw our calendar into the DOM
		objEntry.calendar.hide(); // hide our calendar after drawing
		objEntry.config = undefined;
		// set our function inside the calendar
		/*
		we should be able to replac ethis bulkier code with setting the variable to the function instead
		objEntry.calendar._fChange = function() {
			objEntry._fChange();
		}*/
		objEntry.calendar._fChange = objEntry._fChange;
		
		// we should create the departure calendar last, if it's not and not prevented
		if ( objEntry.isArrival && !bPreventAutoCheck ) {
			if( typeof(this.arrAttributes.qqCalendars[ objEntry.departure ]) != 'undefined'){
				this.checkCalendar( this.arrAttributes.qqCalendars[ objEntry.departure ], true );
			}
			
		}
		
		return true;
	} else {
		return false;
	}
};

// displays the calendar based on element clicked and the # of which calendar to display
// @param strName string - component name
// @param strParentName string - component name of parents (BU & PO)
// @param strCalendar string - element id of calendar button
// @param intCal integer - key of what calendar is being referenced
// @param strEvent string - the event that fired this function
DisneyQuickQuote.prototype.displayCalendar = function ( objEntry, intCal, strEvent ) {
	// is a calendar already open?
	if ( this.arrAttributes.curOpenCalendar >= 0 ) {
		// if the calendar open is the one we just clicked on, lets close and skip this mess
		if ( this.arrAttributes.qqCalendars[ this.arrAttributes.curOpenCalendar ].name == objEntry.name ) {
			this.hideCal( objEntry );
			return true;
		}
		
		this.hideCal( this.arrAttributes.qqCalendars[ this.arrAttributes.curOpenCalendar ] );
	}
	
	// check our calendar and create it if it hasn't been created
	this.checkCalendar( objEntry );
	
	// if ie6, hide all selects for this product option except the ones we need
	if ( typeof( document.body.style.maxHeight ) == 'undefined' ) {
		if ( document.getElementById( 'SQQMultiBU' ) ) {
			document.getElementById( 'SQQMultiBU' ).style.visibility = 'hidden';
		}
		
		this.displayMessage( '', '', '', true );
		this.loopElementsWithCallback( document.getElementById( objEntry.parentName + '_Container' ).getElementsByTagName( 'select' ), function( node ) {
			if ( node.id != objEntry.name + 'Month' && node.id != objEntry.name + 'Day' && node.id != objEntry.name + 'Year' ) {
				node.style.visibility = 'hidden';
			} else {
				node.style.visibility = 'visible';
			}
		} );
	}
	
	// retrieve our calendar object and set up our top/left
	var nodeElement = document.getElementById( objEntry.name + 'CalendarBtn' );
	nodeElement.className = 'SQQTravelDatesCalendar SQQTravelDatesCalendarOpen';
	
	var objCoords = this.getCoords( nodeElement );
	
	this.arrAttributes.curOpenCalendar = intCal;
	objEntry.calendar._nodeCalendar.style.left = objCoords.right + 'px'; // we want the right hand side of our element so it will be right next to it
	objEntry.calendar._nodeCalendar.style.top = objCoords.top + 'px';
	objEntry.calendar.show();
	
	return true;
};
// hides the calendar with the # provided
DisneyQuickQuote.prototype.hideCal = function( objEntry ) {
	// no calendar is open = -1, don't want this to misfire
	if ( this.arrAttributes.curOpenCalendar < 0 ) {
		return false;
	}
	
	// hide the current open calendar, swipe the location
	document.getElementById( objEntry.name + 'CalendarBtn' ).className = 'SQQTravelDatesCalendar';
	objEntry.calendar.hide();
	this.arrAttributes.curOpenCalendar = -1;
};

// get top, right, bottom, left of a node on the page
DisneyQuickQuote.prototype.getCoords = function( nodeElement ) {
	var objCoords = {
		top: 0,
		right: 0,
		bottom: 0,
		left: 0
	};
	
	objCoords.right = nodeElement.offsetWidth;
	objCoords.bottom = nodeElement.offsetHeight;
	
	// get our element's offsets
	while ( nodeElement !== null ) {
		objCoords.top += nodeElement.offsetTop;
		objCoords.left += nodeElement.offsetLeft;
		nodeElement = nodeElement.offsetParent;
	}
	
	// set our button coords
	objCoords.bottom += objCoords.top;
	objCoords.right += objCoords.left;
	
	return objCoords;
};

// this function fires on a mouse click in the window (not document)
// it determines if a calendar is open, then tracks the mouse click coords
// using the coords it creates a padding around the calendar for a "safe zone"
DisneyQuickQuote.prototype.checkOpenCalendar = function( e, that ) {
	// no calendar is open = -1
	if ( that.arrAttributes.curOpenCalendar < 0 ) {
		return false;
	}
	
	// if the calendar open somehow has no Calendar() reference, set current to -1
	if ( typeof( that.arrAttributes.qqCalendars[ that.arrAttributes.curOpenCalendar ] ) == 'undefined' ) {
		that.arrAttributes.curOpenCalendar = -1;
		return false;
	}
	
	var objEntry = that.arrAttributes.qqCalendars[ that.arrAttributes.curOpenCalendar ];
		
	// for IE, set our event
	if ( !e ) {
		e = window.event;
	}
	
	// get coords of our calendar

	var objCoords = that.getCoords( objEntry.calendar._nodeCalendar );
	
	var intPosX = 0;
	var intPosY = 0;
	
	// add/subtract our padding around our calendar
	objCoords.bottom += ( that.arrAttributes.qqCalendarPadding );
	objCoords.right += ( that.arrAttributes.qqCalendarPadding );
	objCoords.top -= ( that.arrAttributes.qqCalendarPadding );
	objCoords.left -= ( that.arrAttributes.qqCalendarPadding );
	
	// ie/ff checking
	if ( typeof( e.pageX ) != 'undefined' && typeof( e.pageY ) != 'undefined' ) {
		intPosX = e.pageX;
		intPosY = e.pageY;
	} else if ( typeof( e.clientX ) != 'undefined' && typeof( e.clientY ) != 'undefined' ) {
		intPosX = ( e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft );
		intPosY = ( e.clientY + document.body.scrollTop + document.documentElement.scrollTop );
	}
	
	// if it's not in a safe zone of our calendar
	if ( !( intPosX > objCoords.left && intPosX < objCoords.right && intPosY > objCoords.top && intPosY < objCoords.bottom ) ) {
		// we want to add a safe zone from our "executer", e.g. the button that was clicked to bring this up
		var nodeBtn = document.getElementById( objEntry.name + 'CalendarBtn' );
		if ( nodeBtn ) {
			objCoords = that.getCoords( nodeBtn );
			
			// if the user is inside the button too, stop it
			if ( intPosX > objCoords.left && intPosX < objCoords.right && intPosY > objCoords.top && intPosY < objCoords.bottom ) {
				return false;
			}
		}
		
		// add a safe zone for the text field if it exists
		var nodeDate = document.getElementById( objEntry.name + 'Date' );
		if ( nodeDate ) {
			objCoords = that.getCoords( nodeDate );

			// if the user is inside the button too, stop it
			if ( intPosX > objCoords.left && intPosX < objCoords.right && intPosY > objCoords.top && intPosY < objCoords.bottom ) {
				return false;
			}
		}
		
		// if ie6, show all of our select's
		if ( typeof( document.body.style.maxHeight ) == 'undefined' ) {
			this.hidePopup( 'qqWarning', 'auto' );
			this.loopElementsWithCallback( document.getElementById( objEntry.parentName + '_Container' ).getElementsByTagName( 'select' ), function( node ) {
				node.style.visibility = 'visible';
			} );
		}
		
		this.hideCal( objEntry );
	}
	
	return true;
};

// handles updating the travel dates for a single text field
// @param objEntry object - Contains a reference to our calendar data object
// @param bFromCal boolean - This function was called from our calendar, special updating techniques for this
// @param strEvent string - Event that fired this function
DisneyQuickQuote.prototype.updateSingleTravelDate = function( objEntry, bFromCal, strEvent ) {
	// consolidate generic calendar items
	if ( bFromCal ) {
		// if ie6, show all of the select's for this product option
		if ( typeof( document.body.style.maxHeight ) == 'undefined' ) {
			this.hidePopup( 'qqWarning', 'click' );
			this.loopElementsWithCallback( document.getElementById( objEntry.parentName + '_Container' ).getElementsByTagName( 'select' ), function( node ) {
				node.style.visibility = 'visible';
			} );
		}
		
		this.hideCal( objEntry );
	} else {
		bCreated = this.checkCalendar( objEntry );
	}
	
	// we have extensive checks and processing for arrival dates, as it adversely affects our departure
	if ( objEntry.isArrival ) {
		var bUpdateDeparture = false;
		var dtDepart = new Date();
		dtDepart.setToCalendarDate();
		var dtLowest = new Date( dtDepart );
		var intSavedMonth = objEntry.calendar._dtSelected.getMonth();
		var intSavedDate = objEntry.calendar._dtSelected.getDate();
		var intSavedYear = objEntry.calendar._dtSelected.getFullYear();
		var nodeDepartureDate = document.getElementById( this.arrAttributes.qqCalendars[ objEntry.departure ].name + 'Date' );
		var riskFactorDays = 0;

		// The arrival and departure calendars are the same - this is a date-time SQQTravelDate object
		if (nodeDepartureDate.id == objEntry.name + 'Date') {
			//since we are changing the date - enable the time dropdown menu as well
			var newDate = new Date((intSavedMonth+1) +'/'+ intSavedDate +'/'+ intSavedYear);
			var nodeTimeDropdown = objEntry.timeDropDown;

			// Check if the date is changed to a future date - enable the past hours
			if (dtDepart.compare(newDate) == -1) {
				this.enableTimeDropdown(nodeTimeDropdown, objEntry.operationalStartTime);
			} else {
				newDate = new Date();
				newDate.setMonth(intSavedMonth+1);
				newDate.setDate(intSavedDate);
				newDate.setFullYear(intSavedYear);
				riskFactorDays = this.setDefaultTime(nodeTimeDropdown, newDate, objEntry.riskFactorMinutes, objEntry.operationalStartTime, objEntry.operationalEndTime);
				dtDepart.setDate(intSavedDate + riskFactorDays);
			}
			
		}
		
		// forcing update or did they change the month and does our saved match departure month
		if ( bFromCal ) {
			dtDepart.setFullYear( intSavedYear, intSavedMonth, (intSavedDate + riskFactorDays));
			if ( objEntry.displayDateRange ) {
				dtDepart.setDate( dtDepart.getDate() + objEntry.displayDateRange );
			} else {
				dtDepart.setDate( dtDepart.getDate() );
			}
			
			bUpdateDeparture = true;
		} else {
			var nodeArrivalDate = document.getElementById( objEntry.name + 'Date' );
			var dtNew = new Date( dtDepart );
			
			// validate the arrival and departure inputs
			if ( dtNew.validate( nodeArrivalDate.value ) ) {
				dtNew.setTime( Date.parse( nodeArrivalDate.value ) );
				
				if ( dtNew < objEntry.calendar._dtRangeStart ) {
					dtNew.setTime( objEntry.calendar._dtRangeStart.getTime() );
					nodeArrivalDate.value = ( dtNew.getMonth() + 1 ) + '/' + dtNew.getDate() + '/' + dtNew.getFullYear();
				}
				
				dtLowest.setTime( dtNew.getTime() );
			}
			
			if ( dtDepart.validate( nodeDepartureDate.value ) ) {
				dtDepart.setTime( Date.parse( nodeDepartureDate.value ) );
			}
			
			if ( dtNew > dtDepart ) {
				dtDepart.setTime( dtNew.getTime() );
				bUpdateDeparture = true;
			}
			
			dtLowest.setDate( dtLowest.getDate() + objEntry.minBookTime );
			if ( dtLowest > dtDepart ) {
				dtDepart.setTime( dtLowest.getTime() );
				bUpdateDeparture = true;
			} else {
				// if the month is different
				if ( dtNew.getMonth() != intSavedMonth ) {
					dtDepart.setMonth( dtNew.getMonth() );
					dtDepart.setDate( dtNew.getDate() );
					bUpdateDeparture = true;
				} else if ( dtNew.getMonth() == dtDepart.getMonth() && dtNew.getDate() != intSavedDate && dtNew.getDate() >= dtDepart.getDate() ) {
					// if the month is the same and the day is different and the departure date is less than our new arrival date
					// we don't want to update our departure date if they have a different month selected
					dtDepart.setMonth( dtNew.getMonth() );
					dtDepart.setDate( dtNew.getDate() );
					bUpdateDeparture = true;
				} else if ( dtNew.getFullYear() != intSavedYear ) {
					// if the year is different
					dtDepart.setFullYear( dtNew.getFullYear() );
					bUpdateDeparture = true;
				}
				
				if ( bUpdateDeparture ) {
					dtDepart.setDate( dtDepart.getDate() + objEntry.displayDateRange );
				}
			}
			
			// set our arrival calendar object to what we have now
			objEntry.calendar.setDateFromInputs();
		}
		
		// if we updated our departure date, set its calendar object and days in month
		if ( bUpdateDeparture ) {
			nodeDepartureDate.value = ( dtDepart.getMonth() + 1 ) + '/' + dtDepart.getDate() + '/' + dtDepart.getFullYear();
			this.arrAttributes.qqCalendars[ objEntry.departure ].calendar.setDateFromInputs();
		}
		
		// we need to update our date ranges regardless if departure has changed; it's not called in displayCalendar anymore
		this.arrAttributes.qqCalendars[ objEntry.departure ].calendar.setDateRange( dtLowest, this.arrAttributes.qqCalendars[ objEntry.departure ].calendar._dtRangeEnd );
	} else if ( !bFromCal ) { // departures
		// simply update our calendar date objects
		// we do not need to update date range or arrival at all
		objEntry.calendar.setDateFromInputs();
	}
	
	return true;
};

// handles updating the travel dates
// @param objEntry object - Contains a reference to our calendar data object
// @param bFromCal boolean - This function was called from our calendar, special updating techniques for this
// @param strEvent string - Event that fired this function
DisneyQuickQuote.prototype.updateTravelDate = function( objEntry, bFromCal, strEvent ) {
	var bCreated = false;
	
	// consolidate generic calendar items
	if ( bFromCal ) {
		// if ie6, show all of the select's for this product option
		if ( typeof( document.body.style.maxHeight ) == 'undefined' ) {
			this.hidePopup( 'qqWarning', 'click' );
			this.loopElementsWithCallback( document.getElementById( objEntry.parentName + '_Container' ).getElementsByTagName( 'select' ), function( node ) {
				node.style.visibility = 'visible';
			} );
		}
		
		this.hideCal( objEntry );
	} else {
		bCreated = this.checkCalendar( objEntry );
	}
	
	// we have extensive checks and processing for arrival dates, as it adversely affects our departure
	if ( objEntry.isArrival ) {
		var nodeArrivalMonth = document.getElementById( objEntry.name + 'Month' );
		var nodeArrivalDay = document.getElementById( objEntry.name + 'Day' );
		var nodeArrivalYear = document.getElementById( objEntry.name + 'Year' );
		var nodeDepartureMonth = document.getElementById( this.arrAttributes.qqCalendars[ objEntry.departure ].name + 'Month' );
		var nodeDepartureDay = document.getElementById( this.arrAttributes.qqCalendars[ objEntry.departure ].name + 'Day' );
		var nodeDepartureYear = document.getElementById( this.arrAttributes.qqCalendars[ objEntry.departure ].name + 'Year' );
		
		var intSavedMonth = ( objEntry.calendar._dtSelected.getMonth() + 1 );
		var intSavedDate = objEntry.calendar._dtSelected.getDate();
		var intSavedYear = objEntry.calendar._dtSelected.getFullYear();
		
		var dtNew = new Date();
		dtNew.setToCalendarDate();
		var bUpdateDeparture = false;
		
		// forcing update or did they change the month and does our saved match departure month
		if ( bFromCal ) {
			this.updateDaysInMonth( nodeArrivalMonth, nodeArrivalDay, nodeArrivalYear );
			nodeArrivalDay.value = objEntry.calendar._dtSelected.getDate();
			
			dtNew.setFullYear( intSavedYear, ( intSavedMonth - 1 ), intSavedDate );
			dtNew.setDate( dtNew.getDate() + objEntry.displayDateRange );
			
			nodeDepartureMonth.value = ( dtNew.getMonth() + 1 );
			nodeDepartureYear.value = dtNew.getFullYear();
			this.updateDaysInMonth( nodeDepartureMonth, nodeDepartureDay, nodeDepartureYear );
			nodeDepartureDay.value = dtNew.getDate();
			
			bUpdateDeparture = true;
		} else  {
			// set our new date to what we have in our combo boxes, then add our minimum travel length; used to update departure
			dtNew.setFullYear( nodeArrivalYear.value, ( ( nodeArrivalMonth.value * 1 ) - 1 ), nodeArrivalDay.value );
			
			if ( dtNew.compare(objEntry.calendar._dtRangeEnd) == 1 ) { // date is too far away, reset it
				dtNew.setTime( objEntry.calendar._dtRangeEnd.getTime() );
				
				nodeArrivalYear.value = dtNew.getFullYear();
				nodeArrivalMonth.value = ( dtNew.getMonth() + 1 );
				this.updateDaysInMonth( nodeArrivalMonth, nodeArrivalDay, nodeArrivalYear );
				nodeArrivalDay.value = dtNew.getDate();
			}
			
			var intNewDay = -1;
			
			// dtDisplay is only used when changing month/day, if changing year we don't need this, see comment below where the year is checked
			var dtDisplay = new Date( dtNew );
			dtDisplay.setDate( dtDisplay.getDate() + objEntry.displayDateRange ); 
			dtNew.setDate( dtNew.getDate() + objEntry.minBookTime );
			
			if ( bCreated ) {
				intSavedMonth = -1;
			}
			
			// if the month is different
			if ( ( nodeArrivalMonth.value != intSavedMonth ) || ( nodeArrivalMonth.value == nodeDepartureMonth.value && ( nodeArrivalDay.value * 1 ) != intSavedDate && ( nodeArrivalDay.value * 1 ) >= ( nodeDepartureDay.value * 1 ) ) ) {
				// if the month is the same and the day is different and the departure date is less than our new arrival date
				// we don't want to update our departure date if they have a different month selected
				nodeDepartureMonth.value = ( dtDisplay.getMonth() + 1 );
				intNewDay = dtDisplay.getDate();
				bUpdateDeparture = true;
			} else if ( nodeArrivalYear.value != intSavedYear ) {
				// if the year is different
				// see we use dtNew for this, because since the date (read: day) isn't changing, we shouldn't accidently move the year 2 up if the dates near the end of December
				nodeDepartureYear.value = dtNew.getFullYear(); 
				bUpdateDeparture = true;
			}
			
			// if our month or year changed, check the days in the month we have (year because of leap year changes)
			if ( nodeArrivalMonth.value != intSavedMonth || nodeArrivalYear.value != intSavedYear ) {
				this.updateDaysInMonth( nodeArrivalMonth, nodeArrivalDay, nodeArrivalYear );
			}
			
			// we need to update our departure and then set our day if changes happened
			if ( bUpdateDeparture ) {
				this.updateDaysInMonth( nodeDepartureMonth, nodeDepartureDay, nodeDepartureYear );
				
				// if the months are different and the value is 1, updateDaysInMonth resetted it, so lets fix that
				if ( nodeDepartureMonth.value != nodeArrivalMonth.value && nodeArrivalDay.value == 1 ) {
					nodeDepartureMonth.value = nodeArrivalMonth.value;
					this.updateDaysInMonth( nodeDepartureMonth, nodeDepartureDay, nodeDepartureYear );
					dtNew.setMonth( nodeArrivalMonth.value - 1 ); // this is on purpose, we want the previous month (0-11)
				}
				
				if ( intNewDay > 0 ) {
					nodeDepartureDay.value = intNewDay;
					//dtNew.setDate( intNewDay ); // i don't think we use this anymore, since display takes over the intNewDay now
				}
			}
			
			// update our arrival calendar object with our new values
			objEntry.calendar.setDateFromInputs();
		}
		
		// if we updated our departure date, set its calendar object and days in month
		if ( bUpdateDeparture ) {
			this.arrAttributes.qqCalendars[ objEntry.departure ].calendar.setDateFromInputs();
		}
		
		// we need to update our date ranges regardless if departure has changed; it's not called in displayCalendar anymore
		this.arrAttributes.qqCalendars[ objEntry.departure ].calendar.setDateRange( dtNew, this.arrAttributes.qqCalendars[ objEntry.departure ].calendar._dtRangeEnd );
	} else {
		nodeDepartureMonth = document.getElementById( objEntry.name + 'Month' );
		nodeDepartureDay = document.getElementById( objEntry.name + 'Day' );
		nodeDepartureYear = document.getElementById( objEntry.name + 'Year' );
		
		if ( bFromCal ) {
			this.updateDaysInMonth( nodeDepartureMonth, nodeDepartureDay, nodeDepartureYear );
			nodeDepartureDay.value = objEntry.calendar._dtSelected.getDate();
		} else {
			dtNew = new Date();
			dtNew.setToCalendarDate();
			dtNew.setFullYear( nodeDepartureYear.value, ( ( nodeDepartureMonth.value * 1 ) - 1 ), nodeDepartureDay.value );
			
			if ( dtNew.compare(objEntry.calendar._dtRangeEnd) == 1 ) { // date is too far away, reset it
				nodeDepartureYear.value = objEntry.calendar._dtRangeEnd.getFullYear();
				nodeDepartureMonth.value = objEntry.calendar._dtRangeEnd.getMonth();
				this.updateDaysInMonth( nodeArrivalMonth, nodeArrivalDay, nodeArrivalYear );
				nodeDepartureDay.value = objEntry.calendar._dtRangeEnd.getDate();
			}
			// if the month or year changed, update the days accordingly
			if ( nodeDepartureMonth.value != ( objEntry.calendar._dtSelected.getMonth() + 1 ) || nodeDepartureYear.value != objEntry.calendar._dtSelected.getFullYear() ) {
				this.updateDaysInMonth( nodeDepartureMonth, nodeDepartureDay, nodeDepartureYear );
			}
			
			// update our departure calendar object with our new values
			objEntry.calendar.setDateFromInputs();
		}
	}
	
	return true;
};

// this function updates the days in a month based on the inputs we pass
// it will update the oDay object accordingly
// @param nodeMonth string - "month" select box
// @param nodeDay string - "day" select box
// @param nodeYear string - "year" select box
DisneyQuickQuote.prototype.updateDaysInMonth = function( nodeMonth, nodeDay, nodeYear ) {
	if ( nodeMonth.value === null || !( nodeMonth.value >= 1 && nodeMonth.value <= 12 ) ) {
		return false;
	}

	var arrDaysInMonth = Array( 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 );
	var intDaysInMonth = arrDaysInMonth[ ( nodeMonth.value - 1 ) ];
	var intDays = ( nodeDay.options[ ( nodeDay.length - 1 ) ].value * 1 );
	
	if ( nodeMonth.value == 2 ) { // february, check leap year
		if ( ( ( ( nodeYear.value ) % 4 ) === 0 && ( ( nodeYear.value ) % 100 ) !== 0 ) || ( ( nodeYear.value ) % 400 ) === 0 ) {
			intDaysInMonth = 29;
		}
	}
	
	// only add/remove dates that we need, they match so stop
	if ( intDays == intDaysInMonth ) {
		return true;
	} else if ( intDays < intDaysInMonth ) { // if we have less days than we need, add more
		var nodeOption = null;
		++intDays; // start the day after we currently have
		
		// add all days beyond what we have
		do {
			nodeOption = document.createElement( 'option' );
			nodeOption.value = intDays;
			nodeOption.text = intDays;
			
			// ie catch, firefox, safari, etc. first
			try {
				nodeDay.add( nodeOption, null );
			} catch ( e ) {
				nodeDay.add( nodeOption );
			}
			
			++intDays;
		} while ( intDays <= intDaysInMonth );
	} else if ( intDays > intDaysInMonth ) { // if we have more days than we need, remove the ones we don't
		intDays = ( intDays - intDaysInMonth );
		
		do {
			nodeDay.remove( intDaysInMonth );
		} while ( --intDays );
	}
	
	return true;
};

// our event controlling function, this is used to add all events
// @param nodeElement object - reference to element to add event to
// @param strEvent string - event that we're attaching to our nodeElement (minus the "on")
// @param funcFunction function - attached (referenced) function when this event fires
// @param bCapture boolean - capturing the bubble or not
DisneyQuickQuote.prototype.addEvent = function( nodeElement, strEvent, funcFunction, bCapture ) {
	if ( nodeElement.addEventListener ) {
		nodeElement.addEventListener( strEvent, funcFunction, bCapture );
		return true;
	} else if ( nodeElement.attachEvent ) {
		var bReturn = nodeElement.attachEvent( 'on' + strEvent, funcFunction );
		return bReturn;
	} else {
		nodeElement[ 'on' + strEvent ] = funcFunction;
	}
};

// create the instance of quick quote we're using and load
qqModule = new DisneyQuickQuote();

// if the wdpro loader exists, attach to that instead, NextGen implementation
if ( typeof( WDPRO_LOADER ) != 'undefined' ) {
	WDPRO_LOADER.addCallback( function(){
		qqModule.startOnload();
	} );
} else {
	qqModule.addEvent( window, 'load', function() { qqModule.startOnload(); }, false );
}

// JavaScript: inputCalendar.js
// OriginalAuthor: Michael Gallagher
// Copywrite: 2008 Disney Interactive Media Group
// 
// Note: All methods and properties prefixed with an _ are considered private and
// should not be accessed from outside the Calendar class.

// ** Helper functions **

// this function resets the time dropdown menu to have all hours enabled
// @param nodeElement - references the dropdown menu object
// @param strStartTime - string representing the first possible booking time
DisneyQuickQuote.prototype.enableTimeDropdown = function(nodeElement, strStartTime) {
	for ( var i = 0; i < nodeElement.length; i++ ) {
		if (nodeElement.options[i].text.indexOf(":") != -1) {
			nodeElement.options[i].value = nodeElement.options[i].text;
			nodeElement.options[i].disabled = false;
			nodeElement.options[i].className = 'SQQDropDownEnabledOption';
			nodeElement.options[i].style.color='black'; //className switch does not work for IE
		}
	}
};

// this function disables all hours past the current time
// @param nodeElement - references the dropdown menu object
// @param currTimeStr - String representing the current available time to book reservation
DisneyQuickQuote.prototype.disableTimeDropdown = function(nodeElement, currTimeStr ) {
	for( var i=0; i < nodeElement.length; i++){
		if( nodeElement.options[i].text.toLowerCase() == currTimeStr.toLowerCase() ) {
			nodeElement.options[i].selected = true;
			return;
		}
		// Disable all hours past the current hour
		if( nodeElement.options[i].text.indexOf(":") != -1 ) {
			nodeElement.options[i].disabled = true;
			nodeElement.options[i].value = ""; //removed value for IE cannot use DISABLED.
			nodeElement.options[i].className = "SQQDropDownDisabledOption";
			nodeElement.options[i].style.color='lightgrey';  //className switch does not work for IE
		}		
		//Disable divider
		if( nodeElement.options[i].value.toLowerCase() == 'divider' ) {
			nodeElement.options[i].disabled = true;
			nodeElement.options[i].value = "";
			nodeElement.options[i].className = "SQQDropDownDisabledOption";
		}
	}
	return true;	
};

// this function sets the minutes based on the riskFactorMinutes - rounding them to "30" or "00"
// @param currDate - Date object cuntaining the new minutes
DisneyQuickQuote.prototype.setNewTimeMinutes = function(currDate) {	

var currMin = currDate.getMinutes();
var currHour = currDate.getHours();

	if ( currMin > 44 ) {
		currHour++;
		currMin = 0;
	} else {
	
		currMin = (Math.round(currMin/30) * 30);
	}
	
	currDate.setHours(currHour);
	currDate.setMinutes(currMin);

	return currDate;
};

// this function sets the time to an AM/PM format
// @param currHour - string representing the current hour
DisneyQuickQuote.prototype.setAMPM = function(currHour) {	
	if (currHour < 12) {
	   	a_p = "am";
	} else {
	   a_p = "pm";
	}
	
	return a_p;
};

// this function sets the hour to AM/PM format
// @param currHour - string representing the changed hour
DisneyQuickQuote.prototype.setAMPMCurrentHour = function(currHour) {	

	if (currHour == 0) {
	      currHour = 12;
	}else if (currHour > 12) {
	      currHour -= 12;
	}
	
	return currHour;
	
};

// toElement(stringOrId)
// @param elmOrId - string ID or a reference to an Element 
// @Description: returns a reference to an element
function toElement( nodeElement ) {
	if ( typeof( nodeElement ) != 'object' ) {
		nodeElement = document.getElementById( nodeElement );
	}
	
	return nodeElement;
}

// **** Extend Date Class with methods used in calendar Class ****
// Date.setToNextMonth()
// @Description - Sets date to the 1st day of the previous month
Date.prototype.setToNextMonth = function() {
	this.setDate( 1 );
	this.setMonth( this.getMonth() + 1 );
};

// Date.setToNextMonth()
// @Description - Sets date to the 1st day of the next month
Date.prototype.setToPreviousMonth = function() {
	this.setDate( 1 );
	this.setMonth( this.getMonth() - 1 );
};

// Date.setToNextMonth()
// @Description - returns the number of days in a month
Date.prototype.getDaysInMonth = function() {
	// copy the object so that we may set dates without affecting the original (this is a get method not a set)
	var that = this;
	that.setDate( 1 );
	that.setMonth( that.getMonth() + 1 );
	that.setDate( that.getDate() - 1 );
	return that.getDate();
};

// Date.getFirstDayOfMonth()
// @Description - returns the day of week (zero based) on which the month begins (0 = sunday ...  6 = saturday)
Date.prototype.getFirstDayOfMonth = function() {
	var that = this;
	that.setDate( 1 );
	return that.getDay();
};

// Date.setToCalendarDate()
// @Description - removes time of day from the date
// usful for making it easier to compare dates
Date.prototype.setToCalendarDate = function() {
	this.setHours( 0 );
	this.setSeconds( 0 );
	this.setMinutes( 0 );
	this.setMilliseconds( 0 );
};


// Date.getCalendarDate()
// @Description - removes time of day from the date
// same as setToCalendarDate but instead of modifing the date object it returns a new one.
Date.prototype.getCalendarDate = function() {
	var t = new Date( this );
	t.setToCalendarDate();
	return t;
};

// Date.validate()
// @Description - validates a given text input, returns true/false
Date.prototype.validate = function( strInput ) {
	var bSet = false;
	
	try {
		bSet = ( typeof( strInput ) == 'string' && strInput.match(/^(0?[1-9]|1[012])[\.\-\/](0?[1-9]|[12]?[0-9]|3[01])[\.\-\/](\d\d)?\d\d$/) !== null );
	} catch( e ) {
		bSet = false;
	}
	
	return bSet;
};

// Compare a date to another date in order to be equivilent both date objects must match to the MS
// Use setToCalendarDate before calling this method to ensure that both dates' times are in sync
// d1.compare(d2)
// if d1 is lt d2 returns -1
// if d1 is eq d2 returns 0
// if d1 is gt d2 returns 1
Date.prototype.compare = function( dtCompare ) {
	var intReturn = null;
    var intCompareTime = dtCompare.getTime();
	var intThisTime = this.getTime();
	
    if ( intThisTime > intCompareTime ) {
		intReturn = 1;
	} else if ( intThisTime == intCompareTime ) {
		intReturn = 0;
	} else {
		intReturn = -1;
	}
	
	return intReturn;
};

// **** Calendar Class ****
// @constructor - Calendar()
// @param * - if using text field, up to 2 arguments, optional 2nd is config object
//          - if using combo boxes (or multiple text fields), up to 4 arguments, optional 4th is config object
// methods and params starting with _ are private and should not be accessed directly from outside the class
function Calendar( varA, varB, varC, varD ) {
	// init private vars
	this._arrDayLabels = ['S','M','T','W','T','F','S'];
	this._arrMonthLabels = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
	this._arrCalendarDays = [];		// Array of references to td elements used for calendar days
	this._dtNow = new Date();					// Todays date
	this._dtNow.setToCalendarDate();			// Remove time from date
	this._dtCurrentMonth = new Date(this._dtNow);	// Current month in view 
	this._dtCurrentMonth.setDate(1);
	this._dtRangeStart = null;					// starting date range
	this._dtRangeEnd = null;					// ending date range
	this._dtSelected = new Date(this._dtNow);		// Selected date
	this._fChange = null;						// function called on "_setValue()" if hiding the calendar
	this._nodeCalendar = null;					// Reference to calendar element.
	this._nodeTarget = null;
	this._nodeMonthYear = null;  				// Reference to element used for month / year label
	this._nodeSelectedDateCell = null;			// Reference to table cell for selected day
	this._nodeSelectInputDay = null;
	this._nodeSelectInputMonth = null;
	this._nodeSelectInputYear = null;
	this._nodeShow = false;						// If set to true, shows the element after it draws
	this._nodeTextInput = null;
	this._strID = null;
	
	// txtInpt can either be an id of or reference to an input of type text
	// init from param, if 3+ params, they're specifying multiple inputs/select
	var that = this;
	if ( arguments.length >= 3 ) {
		this._nodeSelectInputMonth = toElement( varA );
		this._nodeSelectInputDay = toElement( varB );
		this._nodeSelectInputYear = toElement( varC );
		
		// if we have a config object
		if ( arguments.length == 4 ) {
			this.setConfig(varD);
		}
	} else if ( arguments.length >= 1 ) { // 1+ param, only 1 input
		this._nodeTextInput = toElement( varA );
		
		// if we have a config object
		if ( arguments.length == 2) {
			this.setConfig(varB);
		}
		
		if ( this._dtSelected.validate( this._nodeTextInput.value ) ) {
			this._dtSelected.setTime( Date.parse( this._nodeTextInput.value ) );
			this._dtCurrentMonth = this._dtSelected;
			this._dtCurrentMonth.setDate(1);
		} else {
			// init text input to current date
			this._setValue();
		}
	}
}
Calendar.prototype.addEvent = function( nodeElement, strEvent, funcFunction, bCapture ) {
	if ( nodeElement.addEventListener ) {
		nodeElement.addEventListener( strEvent, funcFunction, bCapture );
		return true;
	} else if ( nodeElement.attachEvent ) {
		var bReturn = nodeElement.attachEvent( 'on' + strEvent, funcFunction );
		return bReturn;
	} else {
		nodeElement[ 'on' + strEvent ] = funcFunction;
	}
};
// Calendar.setConfig()
// @Description - initializes private members from config object
Calendar.prototype.setConfig = function(objConfig) {
	// if a select input is used then we need to limit to the available years
	if ( this._nodeSelectInputYear !== null ) {
		this._dtRangeStart = new Date('January 01, ' + this._nodeSelectInputYear.options[0].value); 
		this._dtRangeEnd = new Date('December 31, ' + this._nodeSelectInputYear.options[this._nodeSelectInputYear.options.length - 1].value);
	}
	
	// get our calendar id
	if ( objConfig.id !== null ) {
		this._strID = objConfig.id;	
	}
	
	// get our target object
	if ( objConfig.target !== null ) {
		this._nodeTarget = toElement( objConfig.target );
	}
	
	// get our starting date range
	if ( objConfig.dateRangeStart !== null ) {
		this._dtRangeStart = new Date( objConfig.dateRangeStart );
		this._dtRangeStart.setToCalendarDate();
	}
	
	// get our ending date range
	if ( objConfig.dateRangeEnd !== null ) {
		this._dtRangeEnd = new Date( objConfig.dateRangeEnd );
		this._dtRangeEnd.setToCalendarDate();
	}
	
	// get our "on change date" function
	if ( objConfig.onChangeDate !== null ) {
		this._fChange = objConfig.onChangeDate;
	}
	
	// get whether or not we're showing the input
	if ( objConfig.showInput !== null ) {
		this._nodeShow = objConfig.showInput;
	}
	
	// get our day labels
	if ( objConfig.dayLabels !== undefined ) {
		this._arrDayLabels = objConfig.dayLabels.split( ',' );
	}
	
	// get our month labels
	if ( objConfig.monthLabels !== null ) {
		this._arrMonthLabels = objConfig.monthLabels.split( ',' );
	}
};

// Calendar.setDateFromInputs()
// @Description - sets the calendar to a new date if the combo boxes have changed
Calendar.prototype.setDateFromInputs = function() {
	if ( this._nodeTextInput !== null ) {
		if ( this._dtSelected.validate( this._nodeTextInput.value ) ) {
			this._dtSelected = new Date( this._nodeTextInput.value );
		}
	} else {
		this._dtSelected = new Date( this._nodeSelectInputMonth.value + '/' + this._nodeSelectInputDay.value + '/' + this._nodeSelectInputYear.value );
	}
	
	this._dtSelected.setToCalendarDate();
	this._dtCurrentMonth = new Date( this._dtSelected );
	this._dtCurrentMonth.setDate( 1 );
	this._populateMonth();
};

// Calendar.getDateSelected()
// @Description - returns a copy of the currently selected calendar date
Calendar.prototype.getDateSelected = function(){
	return new Date( this._dtSelected );
};

// Calendar.draw()
// @Description - draws the calendar
Calendar.prototype.draw = function() {
	if ( this._nodeCalendar === null ) {
		// outermost wrapper for calendar calendar
		var nodeContainer = document.createElement('div');
		nodeContainer.className = 'DisneyCal';
		
		if ( this._strID !== null ) {
			nodeContainer.id = this._strID;
		}
		
		// reference to self for use in onclick events
		var that = this;
		
		// create the navigation and month elements
		var nodeHead = nodeContainer.appendChild(document.createElement('div'));
		nodeHead.className = 'DisneyCalHead';
		
		var nodeChild = nodeHead.appendChild(document.createElement('div'));
		nodeChild.className = 'DisneyCalTLNav';
		
		var nodeData = nodeChild.appendChild(document.createElement('a'));
		nodeData.innerHTML = '&lt;';
		nodeData.href = 'javascript:void(0);';
		this.addEvent( nodeData, 'click', function() { that.setToPreviousMonth(); }, false );
		
		nodeChild = nodeHead.appendChild(document.createElement('span'));
		nodeChild.className = 'DisneyCalMonth';
		this._nodeMonthYear = nodeChild;
		
		nodeChild = nodeHead.appendChild(document.createElement('div'));
		nodeChild.className = 'DisneyCalTRNav';
		
		nodeData = nodeChild.appendChild(document.createElement('a'));
		nodeData.href = 'javascript:void(0);';
		nodeData.innerHTML = '&gt;';
		
		this.addEvent( nodeData, 'click', function() { that.setToNextMonth(); }, false );
		
		// create the table row and cell elements used for the calendar 
		nodeHead = nodeContainer.appendChild(document.createElement('table'));
		nodeHead.className = 'DisneyCalTable';
		
		// create day labels in the thead
		nodeChild = nodeHead.appendChild(document.createElement('thead'));
		nodeChild = nodeChild.appendChild(document.createElement('tr'));
		
		// write the day labels
		var intDaysInWeek = 7;
		var i = 0;
		do{
			nodeData = nodeChild.appendChild(document.createElement('th'));
			nodeData.innerHTML = this._arrDayLabels[i];
			i++;
		} while (--intDaysInWeek);
		
		// day numbers in the tbody
		nodeHead = nodeHead.appendChild(document.createElement('tbody'));
		var intWeeksInMonth = 6;
		do {
			intDaysInWeek = 7;
			nodeChild = nodeHead.appendChild(document.createElement('tr'));
			
			do {
				nodeData = nodeChild.appendChild(document.createElement('td'));
				this._addHandleClick(nodeData);
				this._arrCalendarDays.push(nodeData);
			} while (--intDaysInWeek);
		} while (--intWeeksInMonth);
		
		// insert the calendar just before the form field it controls
		// init cal
		if ( this._nodeTarget ) {
			if ( this._nodeTarget.childNodes.length > 0 ) {
				this._nodeCalendar = this._nodeTarget.insertBefore( nodeContainer, this._nodeTarget.childNodes[0] );
			} else {
				this._nodeCalendar = this._nodeTarget.appendChild( nodeContainer );
			}
		} else {
			if ( this._nodeTextInput !== null ) {
				this._nodeCalendar = this._nodeTextInput.parentNode.insertBefore(nodeContainer, this._nodeTextInput);
			} else {
				this._nodeCalendar = this._nodeSelectInputMonth.parentNode.insertBefore(nodeContainer, this._nodeSelectInputMonth);
			}
		}
		// fill calendar with days for the current  month
		this.setDateFromInputs();
		
		if ( ! this._nodeShow ) {
			if ( this._nodeTextInput !== null ) {
				this._nodeTextInput.style.display = 'none';
			} else if ( this._nodeSelectInputMonth !== null && this._nodeSelectInputDay !== null && this._nodeSelectInputYear !== null) {
				this._nodeSelectInputMonth.style.display = 'none';
				this._nodeSelectInputDay.style.display = 'none';
				this._nodeSelectInputYear.style.display = 'none';
			}
		}
		
		this._nodeCalendar.style.display = 'block';
	}
};

// Calendar._addHandleClick( node )
// @Param nodeData (type Object) - the object to add the click event to
Calendar.prototype._addHandleClick = function( nodeData ) {
	var that = this;
	this.addEvent( nodeData, 'click', function() { that._handleClick( nodeData ); }, false );
};

// Calendar.setDateRange(s, e)
// @Param s (type Date)- date for the start of the range
// @Param e (type Date)- date for the end of the range
// @Param bReset (type Boolean); optional - if set to true, it will not reset the date if it is out of range
// Restrict dates between a set of dates
// When initialized ensure that the selected value is not out of bounds by resetting it to the nearest boundary
// Then set the month view to the month of the selected date
Calendar.prototype.setDateRange = function(dtStart, dtEnd, bStopReset) {
	this._dtRangeStart = new Date(dtStart);
	this._dtRangeEnd = new Date(dtEnd);
	this._dtRangeStart.setToCalendarDate();
	this._dtRangeEnd.setToCalendarDate();
	
	if (this._dtRangeStart.compare(this._dtRangeEnd) == 1) {
		var e = new Error('setDateRange: second Date may not occur before first Date:' + this._dtRangeStart + ' - ' + this._dtRangeEnd);
		throw(e);	
	}
	
	// if either the date is before the range start or after the range end, reset it
	if (this._dtSelected.compare(this._dtRangeStart) == -1 || this._dtSelected.compare(this._dtRangeEnd) == 1) {
		this._dtSelected = new Date(this._dtRangeEnd);
		this._dtSelected.setToCalendarDate();
		this._setValue();
	}
	
	this._dtCurrentMonth = new Date(this._dtSelected);
	this._dtCurrentMonth.setDate(1);
	this._dtCurrentMonth.setToCalendarDate();
	this._populateMonth();
};

// Calendar.show()
// @Description - show the calendar
Calendar.prototype.show = function() {
	this._nodeCalendar.style.display = 'block';
	
};

// Calendar.hide()
// @Description - hide the calendar
Calendar.prototype.hide = function() {
	this._nodeCalendar.style.display = 'none';	
};

// Calendar.toggleVisibility()
// @Description - toggle between display block and display none
Calendar.prototype.toggleVisibility = function() {
	if (this._nodeCalendar.style.display != 'block') {
		this._nodeCalendar.style.display ='block';
	} else {
		this._nodeCalendar.style.display = 'none';
	}
};

// Calendar.setToNextMonth()
// @Description - moves the calendar to the next month
Calendar.prototype.setToNextMonth = function() {
	this._dtCurrentMonth.setToNextMonth();
	this._populateMonth();
};

// Calendar.setToPreviousMonth()
// @Description - moves the calendar to the previous month
Calendar.prototype.setToPreviousMonth = function() {
	this._dtCurrentMonth.setToPreviousMonth();
	this._populateMonth();
};
// Calendar._handleClick()
// @Description - Handles the click event and checks if the date clicked is inside this month
Calendar.prototype._handleClick = function( nodeData ) {
	if ( nodeData.className.indexOf( 'DisneyCalDateEnabled' ) > -1 || nodeData.className.indexOf( 'DisneyCalDateSelected' ) > -1 ) {
		this._selectDate( nodeData );
		this._setValue();
	}
};

// Calendar._populateMonth()
// @Description - populates calendar with days in currently viewed month
Calendar.prototype._populateMonth = function() {
	// set that = this. Used in the onclick event of various calendar elements.
	// This is nessisary to keep the onclick from refering to its parent
	// element and instead make it refer back to this original calendar object
	var that = this;
	var strClassName = '';
	var bOutOfBounds = false;

	// set current date at the begining of the month
	var dtCurrent = new Date(this._dtCurrentMonth);
	dtCurrent.setToCalendarDate();
	dtCurrent.setDate(1);

	// get the first day  (0 - 6) in the month
	var intFirstDay = dtCurrent.getFirstDayOfMonth();
	
	// subtract the first day from the first date to get the date at
	// begining of the week even if it occurs within in the previous month
	dtCurrent.setDate( dtCurrent.getDate() - intFirstDay );
	this._nodeMonthYear.innerHTML = this._arrMonthLabels[this._dtCurrentMonth.getMonth()] + ' ' + this._dtCurrentMonth.getFullYear();
	
	// loop through  callendar day elements to populated the month
	// increment the current date by 1 on each pass through
	var i = 0;
	var arrCalDayLength = this._arrCalendarDays.length;
	this._dtSelected.setToCalendarDate();
	
	while (i < arrCalDayLength) {
		bOutOfBounds = false;
		strClassName = '';
		
		// clear the calendar cell
		this._arrCalendarDays[i].innerHTML = dtCurrent.getDate();
		
		if (dtCurrent.getMonth() == this._dtCurrentMonth.getMonth() && dtCurrent.getFullYear() == this._dtCurrentMonth.getFullYear()) {
			// filter out invalid dates based on range if range is defined
			if (dtCurrent.compare(this._dtNow) == -1) {
				// date occurred in the past
				strClassName += ' DisneyCalDatePast';
			} else if (dtCurrent.compare(this._dtNow) === 0) {
				// date is today
				strClassName += ' DisneyCalDateToday';
			}

			if (this._dtRangeStart !== null && dtCurrent.compare(this._dtRangeStart) == -1) {
				// out of lower range
				strClassName += ' DisneyCalDateOutOfBounds';
				bOutOfBounds = true;
			}

			if (this._dtRangeEnd !== null && dtCurrent.compare(this._dtRangeEnd) == 1) {
				// out of upper range
				strClassName += ' DisneyCalDateOutOfBounds';
				bOutOfBounds = true;
			}
			
			if (!bOutOfBounds) {
				// if the date is not out of bounds they should be enabled or selected
				if (dtCurrent.compare(this._dtSelected) === 0) {
					// currently selected date
					// set the reference to selected cell element
					strClassName += ' DisneyCalDateSelected ';
					this._nodeSelectedDateCell = this._arrCalendarDays[i];
				} else {
					// clickable active dates
					strClassName += ' DisneyCalDateEnabled ';
				}
			}
		} else {
			// date occurs outside of the active month
			strClassName = 'DisneyCalDateDisabled';
		}
		
		this._arrCalendarDays[i].className = strClassName;
		dtCurrent.setDate(dtCurrent.getDate() + 1);
		i++;
	}
};

// Calendar._setValue()
// @Description - sets the form value to the current selected date
Calendar.prototype._setValue = function() {
	if ( this._nodeTextInput !== null ) {
		this._nodeTextInput.value = this._dtSelected.getMonth() + 1 + '/' + this._dtSelected.getDate() + '/'  + this._dtSelected.getFullYear();
	} else {
		this._resetSelect(this._nodeSelectInputMonth);
		this._resetSelect(this._nodeSelectInputDay);
		this._resetSelect(this._nodeSelectInputYear);
		this._nodeSelectInputMonth.options[this._dtSelected.getMonth()].selected = true;
		
		if ( typeof( this._nodeSelectInputDay.options[this._dtSelected.getDate() - 1] ) != 'undefined' ) {
			this._nodeSelectInputDay.options[this._dtSelected.getDate() - 1].selected = true;
		}
		
		var strYear = this._dtSelected.getFullYear();
		for ( var i = 0; ( nodeChild = this._nodeSelectInputYear.options[i] ); ++i ) {
			if (nodeChild.value == strYear) {
				nodeChild.selected = true;
				break;	
			}
		}
	}

	if ( typeof( this._fChange ) == 'function' ) {
		this._fChange();
	}
};

// Calendar._resetSelect(elm)
// @Param elm - element of a select input used for date information (ie month, day, or year) 
// @Description - sets all option childnodes to deselected
Calendar.prototype._resetSelect = function(nodeElement) {
	for ( var i = 0; ( nodeChild = nodeElement.options[i]); ++i ) {
		nodeChild.selected = false;
	}
};

// Calendar._selectDate(elm)
// @Param elm - reference to a TD element in the calendar
// @Description - sets selected date to the value indicated by the contents of a clicked td
Calendar.prototype._selectDate = function(nodeElement) {
	this._dtSelected = new Date(this._dtCurrentMonth);
	this._dtSelected.setDate(nodeElement.innerHTML);
	this._populateMonth();
};


