// Presentation Block Functions

/**
 * When 'amend' or 'Add Room' links are clicked
 * it is populated with index of a room that is going to be amended or added.
 */
var currentRoomIndex = 0;

/**
 * When page is loaded this function displays already selected party. Strongly dependent on HTML.
 */
function displayInitialPartySelected(roomDivId, roomIndex) {
	jQuery('#' + roomDivId).show();
	divHTML = jQuery('#' + roomDivId + ' div').html();

	var linkHTML = divHTML.substring(divHTML.indexOf("<"));

	if (initialPaxCombination[roomIndex].adults == "1") {
		divHTML = initialPaxCombination[roomIndex].adults + ' adult';
	} else {
		divHTML = initialPaxCombination[roomIndex].adults + ' adults';
	}

	if (initialPaxCombination[roomIndex].children == "1") {
		divHTML += ', ' + initialPaxCombination[roomIndex].children + ' child';
	} else if (initialPaxCombination[roomIndex].children != "0") {
		divHTML += ', ' + initialPaxCombination[roomIndex].children + ' children';
	}

	if (initialPaxCombination[roomIndex].infants == "1") {
		divHTML += ', ' + initialPaxCombination[roomIndex].infants + ' infant';
	} else if (initialPaxCombination[roomIndex].infants != "0") {
		divHTML += ', ' + initialPaxCombination[roomIndex].infants + ' infants';
	}

	divHTML += linkHTML;

	jQuery('#' + roomDivId + ' div').html(divHTML);
}

/**
 * When 'amend' link is clicked this function displays pop-up
 * populating all necessary variables with actual data.
*/
function amendPartyRoom(amendLink) {
	if (!checkPageLoaded()) return;
	jQuery('#faddroom').show();
	jQuery('#party-overlay').show();

	// Checks and displays (or not) 'Delete Room' link. Strongly dependent on HTML.
	var currentRoomNumber = amendLink.parentNode.parentNode.getElementsByTagName("h4")[0].innerHTML.substring(5);
	if (currentRoomNumber == "1" && initialPaxCombination.length == 1) {
		document.getElementById('fdeleteroom').style.display = 'none';
	} else {
		document.getElementById('fdeleteroom').style.display = 'block';
	}

	currentRoomIndex = parseInt(currentRoomNumber) - 1;

	currentPaxCombination[currentRoomIndex] = initialPaxCombination[currentRoomIndex].clone();
	displayRoomPopup(currentRoomNumber, currentPaxCombination[currentRoomIndex].adults, currentPaxCombination[currentRoomIndex].children, currentPaxCombination[currentRoomIndex].infants, currentPaxCombination[currentRoomIndex].maxChildAge, currentPaxCombination[currentRoomIndex].childAges);
}

/**
 * When 'Add Room' link is clicked this function displays pop-up
 * populating all necessary variables with actual data.
*/
function addRoomToParty() {
	if (!checkPageLoaded()) return;
	jQuery('#faddroom').show();
	jQuery('#party-overlay').show();

	var currentAddingRoomNumber;
	if (jQuery('#froom2').is(":visible")) { // Checks for display:[none|block], ignores visible:[true|false]
		currentAddingRoomNumber = "3";
	} else {
		currentAddingRoomNumber = "2";
	}
	document.getElementById('fdeleteroom').style.display = 'none'; // Do not displays 'Delete Room' link 

	currentRoomIndex = parseInt(currentAddingRoomNumber) - 1;

	currentPaxCombination[currentRoomIndex] = new PaxCombination(2, 0, 0, 12, new Array()); // By default: 2 adults, 0 children, 0 infants
	displayRoomPopup(currentAddingRoomNumber, currentPaxCombination[currentRoomIndex].adults, currentPaxCombination[currentRoomIndex].children, currentPaxCombination[currentRoomIndex].infants, currentPaxCombination[currentRoomIndex].maxChildAge, currentPaxCombination[currentRoomIndex].childAges);
}

/**
 * Displays pop-up and defines possible options for dropdowns.
*/
function displayRoomPopup(roomNumber, adults, children, infants, maxChildAge, childAges) {
	definePossibleOptions(adults);

	// Avoids blank dropdowns in case we got nothing from Back-End
	if (paxCombinations == 0) { // Just checks if it is empty Array
		possibleAdultsOptions[adults] = true;
		possibleChildrenOptions[children] = true;
		possibleInfantsOptions[infants] = true;
	}

	populateOptionsForSelect('fnadult3', possibleAdultsOptions, adults);
	populateOptionsForSelect('fnchild3', possibleChildrenOptions, children);
	populateOptionsForSelect('fninfant3', possibleInfantsOptions, infants);
	populateOptionsForChildAgeSelects(children, childAges, maxChildAge);

	displayChildAgeDropdowns(children);
	checkChildrenAgeSelected(children);

	var facetAddRoomPopup = document.getElementById('faddroom');
	facetAddRoomPopup.getElementsByTagName("h4")[0].innerHTML = "Room " + roomNumber;
	facetAddRoomPopup.style.display = 'block';
}

function displayChildAgeDropdowns(children) {
	if (children != "0") {
		document.getElementById('fchildages').style.display = 'block';
		for (var i = 7; i >= 1; i--) {
			if (i <= eval(children)) {
				document.getElementById('fnchage' + i).parentNode.style.display = 'block';
			} else {
				document.getElementById('fnchage' + i).parentNode.style.display = 'none';
			}
		}
	} else {
		document.getElementById('fchildages').style.display = 'none';
	}
}

/**
 * Checks whether all child age dropdowns are selected and displays error message if not.
*/
function checkChildrenAgeSelected(children) {
	if (children == null) {
		children = currentPaxCombination[currentRoomIndex].children;
	}

	jQuery('label', 'div#fchildages').css('color', 'black');

	var isAllChildrenAgesSelected = true;
	for (var i = 1; i <= eval(children); i++) {
		var childAgeSelect = document.getElementById('fnchage' + i);
		if (childAgeSelect[childAgeSelect.selectedIndex].value == "?") {
			isAllChildrenAgesSelected = false;
			jQuery('label', 'div#fchildages').eq(i - 1).css('color', 'red');
		} else {
			jQuery('label', 'div#fchildages').eq(i - 1).css('color', 'black');
		}
	}

	var errorDiv = document.getElementById('ffaceterror');
	if (children == "0" || isAllChildrenAgesSelected == true) {
		errorDiv.style.display = 'none';
	} else {
		errorDiv.style.display = 'block';
	}

	return isAllChildrenAgesSelected;
}

// Party Facet Business Logic Block Functions

PaxCombination = function (adults, children, infants, maxChildAge, childAges) {
	this.adults = adults;
	this.children = children;
	this.infants = infants;
	this.maxChildAge = maxChildAge;
	this.childAges = childAges;
};

PaxCombination.prototype = {
	adults : 2,
	children : 0,
	infants : 0,
	maxChildAge : null,
	childAges : null,

	/**
	 * Returns string in form of X_Y_Z_A_B_C_...
	 * where X - number of adults,
	 *       Y - number of children,
	 *       Z - number of infants,
	 *       A - max child age,
	 *       B, C, ... - children ages if children are present 
	*/
	trailString : function() {
		var minPossibleChildAge = 999;
		for (var i in paxCombinations) {
			if (paxCombinations[i].adults == this.adults && paxCombinations[i].children == this.children && paxCombinations[i].infants == this.infants) {
				var maxChosenChildAge = 0;
				for (var j in this.childAges) {
					if (parseInt(this.childAges[j]) > parseInt(maxChosenChildAge)) {
						maxChosenChildAge = this.childAges[j];
					}
				}
				if (this.maxChildAge == null || ((parseInt(paxCombinations[i].maxChildAge) >= parseInt(maxChosenChildAge)) && (parseInt(paxCombinations[i].maxChildAge) < parseInt(minPossibleChildAge)))) {
					minPossibleChildAge = paxCombinations[i].maxChildAge;
					this.maxChildAge = paxCombinations[i].maxChildAge;
				}
			}
		}
		var resultTrailString = facetId + '%3A' + this.adults + '_' + this.children + '_' + this.infants  + '_' + this.maxChildAge;
		for (var i in this.childAges) {
			resultTrailString += '_' + this.childAges[i];
		}
		return resultTrailString;
	},

	clone : function() {
		return new PaxCombination(this.adults, this.children, this.infants, this.maxChildAge, this.childAges.slice(0));
	}
};

var paxCombinations = new Array(); // All available PAX Combinations received from Back-End
var initialPaxCombination = [new PaxCombination(2, 0, 0, 12, new Array())]; // By default: 1 room, 2 adults, 0 children, 0 infants
var currentPaxCombination = [new PaxCombination(2, 0, 0, 12, new Array())]; // By default: 1 room, 2 adults, 0 children, 0 infants
var possibleMaxChildAge = 0;
var possibleAdultsOptions = new Object();
var possibleChildrenOptions = new Object();
var possibleInfantsOptions = new Object();

/**
 * Parses initial PAX Combinations received from Back-End into PaxCombination objects.
 * Parses and displays previously selected combination(s).
 * Populate all necessary variables with actual data.
*/
function parseInitialPaxValues() {
	for (var i in initialPaxValues) {
		var values = (initialPaxValues[i].substring(initialPaxValues[i].indexOf(":") + 1)).split("_");
		paxCombinations[i] = new PaxCombination(values[0], values[1], values[2], values[3]);
	}
	var initialTrailValues = (activeTrailValue.substring(activeTrailValue.indexOf(facetId))).split(":");
	var index = 0;
	for (var i = 0; i < initialTrailValues.length; i++) {
		if (initialTrailValues[i] != null && initialTrailValues[i].indexOf("_") != -1 && initialTrailValues[i - 1] == facetId) {
			var partyValues = initialTrailValues[i].split("_");
			var childAgeArray = new Array();
			for (var j = 4; j < partyValues.length; j++) {
				childAgeArray.push(partyValues[j]);
			}
			initialPaxCombination[index] = new PaxCombination(partyValues[0], partyValues[1], partyValues[2], partyValues[3], childAgeArray);
			currentPaxCombination[index] = initialPaxCombination[index].clone();
			displayInitialPartySelected('froom' + (index + 1), index);
			index++;
		} else {
			displayInitialPartySelected('froom1', 0);
		}
	}
	if (index == 3) {
		jQuery('#faddroomlink').hide();
	}
}

/**
 * Searches through possible paxCombinations and dynamically defines
 * possible values for adults, children, infants and max child age.
 *
 * CORE method !!! Think twice or better thrice before changing anything here.
 *
*/
function definePossibleOptions(adults, children, infants, maxChildAge) {
	possibleMaxChildAge = 0;
	possibleAdultsOptions = new Object();
	possibleChildrenOptions = new Object();
	possibleInfantsOptions = new Object();

	for (var i in paxCombinations) {
		possibleAdultsOptions[paxCombinations[i].adults] = true;

		if (adults != null && paxCombinations[i].adults != adults) {
			continue;
		}
		if (children != null && paxCombinations[i].children != children) {
			continue;
		}
		if (infants != null && paxCombinations[i].infants != infants) {
			continue;
		}

		possibleChildrenOptions[paxCombinations[i].children] = true;
		possibleInfantsOptions[paxCombinations[i].infants] = true;

		if (paxCombinations[i].maxChildAge > possibleMaxChildAge) {
			possibleMaxChildAge = paxCombinations[i].maxChildAge;
		}
	}
}

/**
 * Populates dropdown (adults\children\infants) with given values.
*/
function populateOptionsForSelect(selectId, possibleOptions, currentOption) {
	var hasCurrentOption = false;
	var select = jQuery('#' + selectId);
	jQuery('option', select).remove();
	for (var i in possibleOptions) {
		if (possibleOptions[i] == true) {
			select.append(jQuery('<option></option>').val(i).html(i));
			if (currentOption == i) {
				select.val(i);
				hasCurrentOption = true;
			}
		}
	}
	select.show();
	return hasCurrentOption;
}

/**
 * Populates child age dropdowns with given values.
*/
function populateOptionsForChildAgeSelects(children, currentOptions, maxChildAge) {
	if (maxChildAge == null) {
		maxChildAge = possibleMaxChildAge;
	}
	for (var i = 1; i <= eval(children); i++) {
		var childAgeSelect = jQuery('#fnchage' + i);
		jQuery('option', childAgeSelect).remove();
		childAgeSelect.append(jQuery('<option></option>').val("?").html("?"));
		for (var j = 2; j <= maxChildAge; j++) {
			childAgeSelect.append(jQuery('<option></option>').val(j).html(j));
		}
		if (currentOptions != null && currentOptions[i - 1] != null) {
			childAgeSelect.val(currentOptions[i - 1]);
		} else {
			childAgeSelect.val("?");
		}
	}
}

/**
 * Dynamically redefines possible values for children\infants with selected adults.
*/
function changeSelectedAdults(adults) {
	currentPaxCombination[currentRoomIndex].adults = adults;

	// Checks whether previously selected children\infants suit newly selected adults
	definePossibleOptions(adults);
	if (possibleChildrenOptions[currentPaxCombination[currentRoomIndex].children] == true) {
		definePossibleOptions(adults, currentPaxCombination[currentRoomIndex].children);
		if (possibleInfantsOptions[currentPaxCombination[currentRoomIndex].infants] != true) {
			currentPaxCombination[currentRoomIndex].children = "0"; // If not sets children\infants to '0'
			currentPaxCombination[currentRoomIndex].infants = "0";
			currentPaxCombination[currentRoomIndex].childAges = new Array();
		}
	} else {
		currentPaxCombination[currentRoomIndex].children = "0"; // If not sets children\infants to '0'
		currentPaxCombination[currentRoomIndex].infants = "0";
		currentPaxCombination[currentRoomIndex].childAges = new Array();
	}

	definePossibleOptions(currentPaxCombination[currentRoomIndex].adults, currentPaxCombination[currentRoomIndex].children, currentPaxCombination[currentRoomIndex].infants);
	currentPaxCombination[currentRoomIndex].maxChildAge = possibleMaxChildAge;

	// Defines and populates children\infants\child age dropdowns with possible values for selected adults
	definePossibleOptions(adults);
	populateOptionsForSelect('fnchild3', possibleChildrenOptions, currentPaxCombination[currentRoomIndex].children);
	populateOptionsForSelect('fninfant3', possibleInfantsOptions, currentPaxCombination[currentRoomIndex].infants);
	populateOptionsForChildAgeSelects(currentPaxCombination[currentRoomIndex].children, currentPaxCombination[currentRoomIndex].childAges, currentPaxCombination[currentRoomIndex].maxChildAge);
	displayChildAgeDropdowns(currentPaxCombination[currentRoomIndex].children);
}

/**
 * Dynamically redefines possible values for infants with selected adults\children.
*/
function changeSelectedChildren(children) {
	currentPaxCombination[currentRoomIndex].children = children;

	// Checks whether previously selected adults\infants suit newly selected children
	definePossibleOptions(currentPaxCombination[currentRoomIndex].adults, children);
	if (possibleInfantsOptions[currentPaxCombination[currentRoomIndex].infants] != true) {
		currentPaxCombination[currentRoomIndex].infants = "0"; // If not sets infants to '0'
	}

	// Adjusts child age values according to newly selected children
	if (children == "0") {
		currentPaxCombination[currentRoomIndex].childAges = new Array();
	} else {
		if (currentPaxCombination[currentRoomIndex].childAges.length > eval(children)) {
			var size = currentPaxCombination[currentRoomIndex].childAges.length;
			for (var i = 0; i < (size - eval(children)); i++) {
				currentPaxCombination[currentRoomIndex].childAges.pop();
			}
		}
	}

	definePossibleOptions(currentPaxCombination[currentRoomIndex].adults, children, currentPaxCombination[currentRoomIndex].infants);
	currentPaxCombination[currentRoomIndex].maxChildAge = possibleMaxChildAge;

	// Defines and populates infants\child age dropdowns with possible values for selected adults\children
	definePossibleOptions(currentPaxCombination[currentRoomIndex].adults, children);
	populateOptionsForSelect('fninfant3', possibleInfantsOptions, currentPaxCombination[currentRoomIndex].infants);
	populateOptionsForChildAgeSelects(children, currentPaxCombination[currentRoomIndex].childAges, currentPaxCombination[currentRoomIndex].maxChildAge);
	displayChildAgeDropdowns(children);
}

/**
 * Dynamically redefines possible values for children with selected adults\infants.
*/
function changeSelectedInfants(infants) {
	currentPaxCombination[currentRoomIndex].infants = infants;

	// Checks whether previously selected adults\children suit newly selected infants
	definePossibleOptions(currentPaxCombination[currentRoomIndex].adults, null, infants);
	if (possibleChildrenOptions[currentPaxCombination[currentRoomIndex].children] != true) {
		currentPaxCombination[currentRoomIndex].children = "0"; // If not sets children to '0' 
		currentPaxCombination[currentRoomIndex].childAges = new Array();
	}

	definePossibleOptions(currentPaxCombination[currentRoomIndex].adults, currentPaxCombination[currentRoomIndex].children, infants);
	currentPaxCombination[currentRoomIndex].maxChildAge = possibleMaxChildAge;

	// Defines and populates children\child age dropdowns with possible values for selected adults\infants
	definePossibleOptions(currentPaxCombination[currentRoomIndex].adults, null, infants);

	populateOptionsForSelect('fnchild3', possibleChildrenOptions, currentPaxCombination[currentRoomIndex].children);
	populateOptionsForChildAgeSelects(currentPaxCombination[currentRoomIndex].children, currentPaxCombination[currentRoomIndex].childAges, currentPaxCombination[currentRoomIndex].maxChildAge);
	displayChildAgeDropdowns(currentPaxCombination[currentRoomIndex].children);
}

function changeSelectedChildAge(childAgeSelect, childAgeSelectedValue) {
	var childAgeIndex = parseInt(childAgeSelect.id.substring(childAgeSelect.id.length - 1));
	currentPaxCombination[currentRoomIndex].childAges[childAgeIndex - 1] = childAgeSelectedValue;
}

// JQuery functions 

$(function() {
	var windowSize = getDimensions();
	
	// Overlay
	jQuery('<div></div>')
				.attr('id', 'party-overlay')
				.css({
					display: 'none',
					backgroundColor: '#000000',
					opacity: 0.3,
					height: windowSize[0],
					width: windowSize[1],
					position: 'fixed',
					left: 0,
					top: 0,
					zIndex: 10
				})
				.appendTo('body');

	// Update Results Button Click checks whether all child age selected and submits the search if so
	jQuery('#fbuttonlink').click(function(e) {
		var childrenSelected = checkChildrenAgeSelected();
		if (childrenSelected == true) {
			composeLocationHref();
			jQuery('#faddroom').hide();
			jQuery('#froom' + (currentRoomIndex + 1)).addClass('pleasewait');
			location.href = locationHref  + '&expand=' + getFacetsToExpand();
		}
		return false;
	});

	// Closes Pop-Up and reverts changes in variables to initial state
	jQuery('#fpartyclosebutton').click(function(e) {
		jQuery('#faddroom').hide();
		jQuery('#party-overlay').hide();
		if (initialPaxCombination[currentRoomIndex] != null) {
			currentPaxCombination[currentRoomIndex] = initialPaxCombination[currentRoomIndex].clone();
		} else if (currentPaxCombination[currentRoomIndex] != null) {
			currentPaxCombination.splice(currentRoomIndex, 1);
		}
		return false;
	});

	// Deletes room and submits the search
	jQuery('#fdeleteroom').click(function(e) {
		currentPaxCombination.splice(currentRoomIndex, 1);
		composeLocationHref();
		jQuery('#faddroom').hide();
		jQuery('#froom' + (currentRoomIndex + 1)).addClass('pleasewait');
		location.href = locationHref + '&expand=' + getFacetsToExpand();
		return false;
	});

	/**
	 * Composes href for a search substituting actual values
	*/
	function composeLocationHref() {
		var resultTrailString = "";
		for (var i in currentPaxCombination) {
			if (i > 0) {
				resultTrailString += '%3A';
			}
			resultTrailString += currentPaxCombination[i].trailString();
		}
		locationHref = locationHref.replace("currentPaxCombination.trailString()", resultTrailString);
	};
});
