// Search Engine Utilities
// requiere :
//	-commons.js
// 	-NHGoogleMaps.js
//  -mootools.js/multibox.js [for click to call launching when more than six rooms selected. I'm sorry :(]
//  -searchMini.js [if we use a 'mini' search form]

// COUNTRIES, CITIES AND HOTELS

var NO_VALUE = '0';
var SEARCH_FORM_NAME = 'searchForm';
var SEARCH_FORM_COUNTRY_ELEMENT_NAME = 'country';
var SEARCH_FORM_CITY_ELEMENT_NAME = 'city';
var SEARCH_FORM_HOTEL_ELEMENT_NAME = 'hotel';
var SEARCH_FORM_QUICK_SEARCH_ELEMENT_NAME = 'quick';
var SEARCH_FORM_DATE_FROM_ELEMENT_NAME = 'calendar|hidden|from';
var SEARCH_FORM_DATE_TO_ELEMENT_NAME = 'calendar|hidden|to';
var SEARCH_FORM_N_ROOMS_ELEMENT_NAME = 'nRooms';
var SEARCH_FORM_LOCATION_ELEMENT_NAME = 'location';
var SEARCH_FORM_PROMOTIONS_CATEGORY = 'category';
var SEARCH_ERROR_PROMOTIONAL_CODE_ID = 'promotionalCodeErrorId';
var SEARCH_FORM_BUTTON_ID = 'searchButton';
var HELP_ID = 'help';

var searchButtonClass = "";
var searchButtonTxt = "";

// CPTP values
var PARTY_ID_ELEMENT_NAME = 'partyId';
var BRANCH_ID_ELEMENT_NAME = 'branchId';
var CLIENT_ID_ELEMENT_NAME = 'clientId';

var SEARCH_ERROR_BOX = 'errorBoxId';

var SEARCH_FORM_PRICE_CONTROL_ID = 'priceControl';
var SEARCH_FORM_PRICE_ID = 'priceId';

// OMNITURE values
var DEFAULT_SEARCH_LAUNCHER = 'home';
var RESULT_SEARCH_LAUNCHER = 'result';
var RESERVATION_SEARCH_LAUNCHER = 'reservation';
var MISSING_DATA_ERROR = 'Missing data';
var INPUT_ERRORS = 'Input errors';
if (!searchLauncher) var searchLauncher = DEFAULT_SEARCH_LAUNCHER; 

// ESTARA
var ESTARA_SPECIAL_BOX_ID = 'clickToCallLayerReference';

// cptp mode var initialization
if (!cptpMode) var cptpMode = false;
if (!mandatoryFieldCheck) var mandatoryFieldCheck = false;

// campaigns mode var initialization
if (!campaignsMode) var campaignsMode = false;

// To access the map from the parent document
var mapParentDocument = null;

var DIV_FILTER = "divFilter";

var isSearchMini = false;

function RoomData(nAdults, nChilds) {
	this.nAdults = nAdults;
	this.nChilds = nChilds;
}

// init functions: this functions [and no others] should be called in onload event [or alike]
// a init function should end in a 'searchValuesReady = true' sentence, necesary for an error-free behaviour of out functions 
var searchValuesReady = false;
function initSearch() {
	var countrySelect = get(SEARCH_FORM_COUNTRY_ELEMENT_NAME);
	var citySelect = get(SEARCH_FORM_CITY_ELEMENT_NAME);
	var hotelSelect = get(SEARCH_FORM_HOTEL_ELEMENT_NAME);
	var dateFrom = get(SEARCH_FORM_DATE_FROM_ELEMENT_NAME);
	var dateTo = get(SEARCH_FORM_DATE_TO_ELEMENT_NAME);
	var numRooms = get(SEARCH_FORM_N_ROOMS_ELEMENT_NAME);
	
	// Initialize countries combo
	repaintCountries();

	if (citySelect != null) { // Initialize cities combo
		markComboAsDisabled(citySelect);
		if (!isSelectedCodeNoValue(selectedCountryCode))
			repaintCities(selectedCountryCode, selectedCityCode);
	}

	if (hotelSelect != null) { // Initialize hotels combo 
		markComboAsDisabled(hotelSelect);
		if (!isSelectedCodeNoValue(selectedCityCode))
			repaintHotels(selectedCityCode, selectedHotelId);
	}
		
	// Init search type
	changeSearchType(selectedSearchType, selectedLocationText);
		
	// Init Rooms
	if(numRooms != null && !isSearchMini) 
		changeRooms(numRooms.value, null, selectedUserRoomingData);

    // Init Promotional Code
    if (selectedPromotionalCode != "") {
        get(SEARCH_FORM_PROMOTIONAL_CODE_ELEMENT_ID).value = selectedPromotionalCode;
        get(SEARCH_FORM_PROMOTIONAL_CODE_SELECTOR_ELEMENT_ID).checked = true;
        showHidePromocionalCodeForm(true);
    }
    
    // Init Category Promotions
    if (selectedPromotionCategory != null && selectedPromotionCategory != "" && get(SEARCH_FORM_PROMOTIONS_CATEGORY) != null) {
    	get(SEARCH_FORM_PROMOTIONS_CATEGORY).value = selectedPromotionCategory;
    }
    
    // Init Price Filter
	if (get(SEARCH_FORM_PRICE_CONTROL_ID) != null) {
	    if (maxPrice != '') {
	    	var position;
	    	for(id in priceRanges) {
	    		if (priceRanges[id] == maxPrice) { position = id; break; }
	    	} 
	    	if (position == null) { /* Si usuario modifica la URL, ï¿½ajustamos la barra al punto mï¿½s prï¿½ximo?*/ }
	       	movePriceControlElement(position,getControlElementPosition(position));
	    } else {
			get(SEARCH_FORM_PRICE_ID).innerHTML = FILTER_NO_LIMIT;
		}
    }
    
    // init CPTP mode
    if (cptpMode) {
    	changeCompany(selectedPartyId, selectedBranchId);
    	if (selectedBranchId != NO_VALUE)
    		changeBranch(selectedClientId);
    	if(!isSearchMini){
    		showCPTPInfo();
    		fillOnlyOneBranch();
    	}
    }
    searchValuesReady = true;
}

function initRooms(nRooms, roomElementIdParam, selectedUserRoomingData) {
	changeRooms(nRooms, roomElementIdParam, selectedUserRoomingData);
	searchValuesReady = true;
}
// end of init functions

function repaintCountries(){
	var countrySelect = get(SEARCH_FORM_COUNTRY_ELEMENT_NAME);
	if (countrySelect == null || !isSelect(countrySelect)) return;
		
	for (id in jsCountries) {
		var country = jsCountries[id];
		if (countryMatchConditions(country.code) == true){
			countrySelect[countrySelect.length] = createOption(country.code, country.name, (country.code == selectedCountryCode))
		}
	}
	if (countrySelect.options.length == 2) { 
		markOptionAsSelected(countrySelect, 1);
	}
	selectedCountryCode = countrySelect.options[countrySelect.selectedIndex].value;
}

function repaintCities(countryCode, cityCode) {
	var citySelect = get(SEARCH_FORM_CITY_ELEMENT_NAME);
	var hotelSelect = get(SEARCH_FORM_HOTEL_ELEMENT_NAME);
	if (citySelect == null || !isSelect(citySelect)) return;
	var hotelComboExists = (hotelSelect != null && isSelect(hotelSelect)); 
	
	resetCombo(citySelect, true);
	if (hotelComboExists) resetCombo(hotelSelect, true);
		
	if (isSelectedCodeNoValue(countryCode)) {
		checkPOIState();
		return;
	}
	var citySelectedIndex = 0;
	for (id in jsCities) {
		var city = jsCities[id];
		if (cityMatchConditions(city.code) == true){
			if (countryCode == city.countryCode) {
				if (city.code == cityCode) citySelectedIndex = citySelect.length;
				citySelect[citySelect.length] = createOption(city.code, city.name, (city.code == cityCode));
			}
		}
	}
	citySelect.selectedIndex = citySelectedIndex;
	markComboAsEnabled(citySelect);
	
	selectedCityCode = citySelect.options[citySelect.selectedIndex].value;
	 
	if (hotelComboExists && checkComboState(citySelect)) {
		selectedCityCode = citySelect.options[citySelect.selectedIndex].value;
		repaintHotels(selectedCityCode);
	}
	
	checkPOIState();
}

function repaintHotels(cityCode, hotelId) {
	var hotelSelect = get(SEARCH_FORM_HOTEL_ELEMENT_NAME);
	if (hotelSelect == null || !isSelect(hotelSelect)) return;
	
	resetCombo(hotelSelect, true);
	
	checkPOIState();
	
	showHideFilter(cityCode);
	if (isSelectedCodeNoValue(cityCode)) return;
	
	var hotelSelectedIndex = 0;
	for (id in jsHotels) {
		var hotel = jsHotels[id];
		if (hotelMatchConditions(hotel.id) == true){
			var townCode = hotel.cityCode;
			if (hotel.town != null && hotel.town != '') 
				townCode += (TOWN_SUFIX + hotel.town);
			if (cityCode == hotel.cityCode || cityCode == townCode) {
				if (hotel.id == hotelId) hotelSelectedIndex = hotelSelect.length;
				hotelSelect[hotelSelect.length] = createOption(hotel.id, hotel.name, (hotel.id == hotelId));
			}
		}
	}
	hotelSelect.selectedIndex = hotelSelectedIndex;
	markComboAsEnabled(hotelSelect);
	
	if (hotelSelect.options.length == 1 || (getSearchType() == SEARCH_TYPE_GEO_SEARCH)){  // Just one option, no hotels
		markComboAsDisabled(hotelSelect);
	} else if (hotelSelect.options.length == 2) { // Just one option, appart from 'select one' option
		markOptionAsSelected(hotelSelect, 1);
	}
}

function resetCombo(combo, disabled) {
	if (combo.length == 0) return; 
	var firstText = combo.options[0].text;
	var firstValue = combo.options[0].value;
	combo.innerHTML = "";
	combo[combo.length] = createOption(firstValue, firstText);
	if(disabled) 
		markComboAsDisabled(combo);
	else 
		markComboAsEnabled(combo);
}

function checkComboState(htmlCombo) {
	var itemHasBeenSelected = false;
	
	markComboAsEnabled(htmlCombo);
	
	if (htmlCombo.options.length == 1){  // Just one option, no data in combo
		markComboAsDisabled(htmlCombo)
	} else if (htmlCombo.options.length == 2) { // Just one option, appart from 'select one' option (the first)
		markOptionAsSelected(htmlCombo, 1);
		itemHasBeenSelected = true;
	}
	return itemHasBeenSelected;
}

function swithComboAvailability(htmlCombo, disableIt) {
	htmlCombo.disabled = disableIt;
	var DISABLED_CLASS_NAME = "disabled";
	if (disableIt) addClass(htmlCombo, DISABLED_CLASS_NAME);
	else removeClass(htmlCombo, DISABLED_CLASS_NAME);
}

function markComboAsDisabled(htmlCombo) {
	htmlCombo.disabled = true;
	addClass(htmlCombo,"disabled");
}

function markComboAsEnabled(htmlCombo) {
	htmlCombo.disabled = false;
	removeClass(htmlCombo,"disabled");
}

function deleteCondition(condition, divId){
	applyCondition(condition, false);
	get(divId).style.display='none';
}

// ROOMING

var DEFAULT_ROOM_ELEMENT_ID = 'rooms';
var NADULTS_ELEMENT_ID_PREFIX = 'nAdults';
var NCHILDS_ELEMENT_ID_PREFIX = 'nChilds';
var ROOMING_INFO_ELEMENT_ID = 'roomsInfo';

var DEFAULT_ROOM_VALUE_AFTER_CTC = 1;

var MAX_ROOMS = 6;
var NUM_MIN_ADULTS = 1;
var NUM_MAX_ADULTS = 3;
var NUM_MIN_CHILDS = 0;
var NUM_MAX_CHILDS = 2;
var NUM_MAX_PERSONS = 3;

var DEFAULT_ADULTS_SELECTED = 2;
var DEFAULT_CHILDS_SELECTED = 0;

function changeRooms(nRooms, roomElementIdParam, selectedUserRoomingData) {
	var roomElementId = (roomElementIdParam != null)?roomElementIdParam:DEFAULT_ROOM_ELEMENT_ID;
	// if 'selectedUserRoomingData' is defined, then nRooms is pre-established and depends on it
	if (isDefined(selectedUserRoomingData) && selectedUserRoomingData.length > 0) {
		nRooms = (selectedUserRoomingData.length-1);
		get(SEARCH_FORM_N_ROOMS_ELEMENT_NAME).value=nRooms;
	} else {
		nRooms = parseInt(nRooms);
	}
	var rooms = get(roomElementId);
	
	if (nRooms >= MAX_ROOMS) {// max num rooms exceeded: launch click-to-call
		rooms.innerHTML = "";
		clickToCall(nRooms);
		nRooms = DEFAULT_ROOM_VALUE_AFTER_CTC;
		get(SEARCH_FORM_N_ROOMS_ELEMENT_NAME).value=nRooms;
	}
	// Gather every data, already inputted
	// if 'selectedUserRoomingData' is defined, then rooming is to be pre-setted
	var userRoomingData = (isDefined(selectedUserRoomingData) && selectedUserRoomingData.length > 0)?selectedUserRoomingData:getRoomingUserInfo(roomElementId);
	rooms.innerHTML = "";
	var content = "";
	for (var i = 1; i <= nRooms; i++) {
		content+= createNewRoom(i, userRoomingData[i], roomElementId);
	}
	rooms.innerHTML = content;
}

function getRoomingUserInfo(roomElementId) {
	var userRoomingData = new Array();
	for (var i = 1; i < MAX_ROOMS; i++) {
		var nAdults = get(getAdultElementIdFromPrefix(roomElementId, i), mapParentDocument);
		var nChilds = get(getChildElementIdFromPrefix(roomElementId, i), mapParentDocument);
		if (nAdults == null || nChilds == null) break; // no more rooms defined right now 
		userRoomingData[i] = new RoomData(nAdults.value, nChilds.value);
	}
	return userRoomingData;
}

function createNewRoom(num, roomingDataParam, roomElementId) {
	var roomingData;
	if (roomingDataParam == null) {
		roomingData = new RoomData(DEFAULT_ADULTS_SELECTED, DEFAULT_CHILDS_SELECTED);
	} else { 
		roomingData = roomingDataParam;
	}
	var nChildsAllowed = getNumChildsAllowed(roomingData.nAdults);
	
	var classSelect = (LANGUAGE_PAGE == 'nl')?'holandeslong2':'long2';
	
	var newRoomContent = "";
	newRoomContent+= ' <div class="sep02"></div><br class="hide" /><span class="room"><strong>' + ROOM_TXT + ' ' + num + '</strong></span><br class="hide" />';
	newRoomContent+= ' <label for="' + getAdultElementIdFromPrefix(roomElementId, num) + '">' + ADULTS_TXT + '<br />';
	newRoomContent+= ' <select class="' + classSelect + '" id="' + getAdultElementIdFromPrefix(roomElementId, num) + '" onchange="checkNumChilds(' + num + ', \'' + roomElementId + '\');" onclick="stop(event)">';
	newRoomContent+= createPersonsOptions(NUM_MIN_ADULTS, NUM_MAX_ADULTS, roomingData.nAdults, 'ADULTS_OPTION_TXT');
	newRoomContent+= ' </select>';
	newRoomContent+= ' </label>';
	newRoomContent+= '<br class="hide" /><span class="space"></span>';
	newRoomContent+= ' <label for="' + getChildElementIdFromPrefix(roomElementId, num) + '">' + CHILDS_TXT;
	newRoomContent+= ' <span class="tip"><a class="tip_lnk" href="javascript:;" onclick="closeAllToolTips(\'childTip|' + num + '\');showHideToolTip(\'childTip|' + num + '\', event)" title="' + BABIES_FREE_TXT + RESERVE_COT_PRE_TXT + RESERVE_COT_POST_TXT + '">[?]</a>';
	newRoomContent+= ' <span class="tip_layer" id="childTip|' + num + '" onclick="stop(event)"><span class="deco"></span><span class="right"><a href="javascript:;" class="lnk_cerrar" onclick="hideToolTip(\'childTip|' + num + '\');">' + CERRAR_TXT + '</a></span><span class="clear"></span>' + BABIES_FREE_TXT + RESERVE_COT_PRE_TXT + RESERVE_COT_POST_TXT + '</span></span><br/>';
	var disabled = ((nChildsAllowed == 0)?'disabled':'');
	var classDisabled = ((disabled == '')?'':' disabled');
	newRoomContent+= '	<select class="'+ classSelect + classDisabled +'" id="' + getChildElementIdFromPrefix(roomElementId, num) + '" ' + disabled + ' onclick="stop(event)">';
	newRoomContent+= createPersonsOptions(NUM_MIN_CHILDS, nChildsAllowed, roomingData.nChilds, 'CHILDS_OPTION_TXT');
	newRoomContent+= '	</select>';
	newRoomContent+= '</label>';
	return newRoomContent;
}
function createPersonsOptions(min, max, numPreviousSelected, msg) {
	// Fix in IE, when HTML available 
	var content = "";
	for (var i = min; i <= max; i++) {
		content+= '<option value="' + i + '" ' + ((numPreviousSelected == i)?"selected":"") + '>' + getOptionMessage(i, msg);
		content+= '</option>';
	}
	return content;
}
function getOptionMessage(num, msg) {
	msg+= (num == 1)?"_SINGLE":"";
	return num + " " + eval(msg); 
}
function checkNumChilds(numRoom, roomElementId) {
	var adultElementId = getAdultElementIdFromPrefix(roomElementId, numRoom);
	var childElementId = getChildElementIdFromPrefix(roomElementId, numRoom);
	var nAdults = parseInt(get(adultElementId).value);
	var nChildsAllowed = getNumChildsAllowed(nAdults);
	
	var nChilds = get(childElementId);
	markComboAsEnabled(nChilds);
	nChilds.innerHTML = "";

	for (var i = NUM_MIN_CHILDS; i <= nChildsAllowed; i++) {
		nChilds[nChilds.length] = createOption(i, getOptionMessage(i, 'CHILDS_OPTION_TXT'), false);
	}
	
	if (nChildsAllowed == 0){
		markComboAsDisabled(nChilds);
	}
}
function getNumChildsAllowed(adults) {
	return (NUM_MAX_PERSONS - adults);
}

function selectRoomDistribution(roomElementIdParam) {
	var roomElementId = (roomElementIdParam != null)?roomElementIdParam:DEFAULT_ROOM_ELEMENT_ID;
	var roomElement = get(roomElementId);
	var txt = '';
	var userRoomingData = getRoomingUserInfo(roomElementId);
	for (var i = 1; i < userRoomingData.length; i++) {
		var adults = parseInt(userRoomingData[i].nAdults, 10); 
		var childs = parseInt(userRoomingData[i].nChilds, 10);
		txt+= ROOM_TXT + ' ' + i;
		txt+= ' (';
		txt += getOptionMessage(adults, 'ADULTS_OPTION_TXT');
		if (childs != 0) 
			txt += "," + getOptionMessage(childs, 'CHILDS_OPTION_TXT');
		txt+= ') ';
	}
	get(ROOMING_INFO_ELEMENT_ID).innerHTML = txt;
}
function getAdultElementIdFromPrefix(prefix, index) {
	return getPersonElementIdFromPrefix(prefix, NADULTS_ELEMENT_ID_PREFIX, index);
}
function getChildElementIdFromPrefix(prefix, index) {
	return getPersonElementIdFromPrefix(prefix, NCHILDS_ELEMENT_ID_PREFIX, index);
}
function getPersonElementIdFromPrefix(prefix, elementType, index) {
	return prefix + elementType + index;
}

function clickToCall(nRooms) {
	if (nRooms >= MAX_ROOMS) {
		var element = get(ESTARA_SPECIAL_BOX_ID);
		if (element == null) return;
		element.href = URL_ESTARA;
		if (!specialBox)
			var specialBox = new MultiBox('smb', {descClassName: false, useOverlay: true});
		specialBox.open(element);
	}
}

// FILTERS

var SEARCH_FORM_FILTER_PARENT_ELEMENT_ID = 'serviceFilter';
var SEARCH_FORM_FILTER_NUMBER_OF_HOTELES_ELEMENT_ID = 'numberOfHotelsFiltered';
var SEARCH_FORM_FILTER_SERVICE_ID_PREFIX = 'service_';
var SEARCH_FORM_FILTER_NUMBER_HOTELS_INPUT_TEXT = 'numberOfHotels';
var SEARCH_FORM_FILTER_BUTTON = 'searchFilterButton';

function applyFilters(url) {
	var servicesSelected = getServicesSelected();
	url += '?services=' + separateByComas(servicesSelected);
	url += '&maxPrice=' + getMaxPriceSelected();
	sendXMLRequest(url, updateNumberOfHotels);
}

function updateNumberOfHotels(xmlObject, request) {
	var numberOfHotelsFiltered = get(SEARCH_FORM_FILTER_NUMBER_OF_HOTELES_ELEMENT_ID);
	numberOfHotelsFiltered.innerHTML = cleanResponse(request.responseText);
	var inputNumberOfHotels = get(SEARCH_FORM_FILTER_NUMBER_HOTELS_INPUT_TEXT);
	var button = get(SEARCH_FORM_FILTER_BUTTON);
	button.disabled = false;
	button.className = 'btn';
	if (inputNumberOfHotels.value.substring(0,1) == '0') {
		button.disabled = true;
		button.className = 'btn-disabled';
	}
}

// FILTERS.SERVICES

function Service(id, selected) {
	this.id = id.substr(SEARCH_FORM_FILTER_SERVICE_ID_PREFIX.length);
	this.selected = selected;
}

function getServicesSelected() {
	var serviceElement = get(SEARCH_FORM_FILTER_PARENT_ELEMENT_ID);
	if (serviceElement == null) return;
	
	var serviceCheckboxes = serviceElement.getElementsByTagName('input');
	if (serviceCheckboxes.length == 0) return;
	
	var allServices = new Array();
	for (var i = 0; i < serviceCheckboxes.length; i++) {
		var service = serviceCheckboxes[i];
		if (service.checked == true && service.disabled == false)
			allServices.push(new Service(service.id, (service.checked)));
	}
	return allServices;
}

// FILTERS.PRICES

function getMaxPriceSelected(index) {
	var controlElement = get(SEARCH_FORM_PRICE_CONTROL_ID);
	if(index == null) index = getIndexOfPriceRange(controlElement.offsetLeft);
	var price = priceRanges[index];
	return (price == null)?'':price;
}

/*
 * Get index of array priceRange by controlElement.offsetLeft
 */
function getIndexOfPriceRange(offsetLeft){
	switch(offsetLeft){
		case 11: return 0;
		case 60:  return 1;
		case 110: return 2;
		case 156: return 3;
		case 206: return 4; 
	}
	return 4;
}

/*
 * Get controlElement position by inde of array priceRange.
 */
function getControlElementPosition(priceRangeIndex){
	switch(parseInt(priceRangeIndex)){
		case 0: return 11;
		case 1: return 60;
		case 2: return 110;
		case 3: return 156;
		case 4: return 206; 
	}
	return 206;
}

function movePriceControlElement(index, position) {
	var controlElement = get(SEARCH_FORM_PRICE_CONTROL_ID);
	controlElement.style.left = position + 'px';
	var priceElement = get(SEARCH_FORM_PRICE_ID);
	var value = FILTER_NO_LIMIT;
	var searchCurrency = (searchLauncher == RESERVATION_SEARCH_LAUNCHER)?"EUR":currency;
	if(getMaxPriceSelected(index) != '') {
		value = getMaxPriceSelected(index) + ' ' + searchCurrency;
	}
	priceElement.innerHTML = value;
}
// PROMOTIONAL CODES 

var SEARCH_FORM_PROMOTIONAL_CODE_SELECTOR_ELEMENT_ID = 'promotionalCodeSelector';
var SEARCH_FORM_PROMOTIONAL_CODE_FORM_ELEMENT_ID = 'promotionalCodeForm';
var SEARCH_FORM_PROMOTIONAL_CODE_ELEMENT_ID = 'promotionalCode';

function showHidePromocionalCodeForm(isChecked) {
	if (isChecked) show(get(SEARCH_FORM_PROMOTIONAL_CODE_FORM_ELEMENT_ID));
	else hide(get(SEARCH_FORM_PROMOTIONAL_CODE_FORM_ELEMENT_ID));
}

// SEARCH EXECUTION

var SEARCH_TYPE_SELECTOR_ELEMENT_ID = 'searchType';
var SEARCH_TYPE_SELECTOR_ELEMENT_PREFIX = 'searchType_';
var SEARCH_TYPE_DEFAULT = 'default';
var SEARCH_TYPE_GEO_SEARCH = 'geo';

function searchGeoLocation(queryString){
	var countryName = get(SEARCH_FORM_COUNTRY_ELEMENT_NAME).options[get(SEARCH_FORM_COUNTRY_ELEMENT_NAME).selectedIndex].text;
	var cityName = get(SEARCH_FORM_CITY_ELEMENT_NAME).options[get(SEARCH_FORM_CITY_ELEMENT_NAME).selectedIndex].text;
	var freeText = get(SEARCH_FORM_LOCATION_ELEMENT_NAME).value;
	var addressPoint = new NHAddressPoint (countryName, cityName, freeText);
	searchLocations(addressPoint, queryString, false, null, null);
};

//out function
function sendSearchForm(filtersActive, roomElementIdParam) {
	if (!validate()) return false;
	
	var loading = loadForm(filtersActive);
	if (loading) return false;
	
	var searchType = getSearchType();
	
	// 1. url
	var url = getUrl(searchType);
	
	// 2. query string
	var params = '';
	
	params += getAction(url);
		
	params += "&stype=" + searchType;	
	
	// 2.1 bookig params
	params += getBookingParams(roomElementIdParam);
	
	// 2.2 promotional code
	var promotionalCodeSelector = get(SEARCH_FORM_PROMOTIONAL_CODE_SELECTOR_ELEMENT_ID);
	if (promotionalCodeSelector != null && promotionalCodeSelector.checked) {
		var promotionalCode = get(SEARCH_FORM_PROMOTIONAL_CODE_ELEMENT_ID);
		if (!isEmpty(promotionalCode.value)) {
			var urlValidatePCode = VALIDATE_PROMOTIONAL_CODE_URL + "?code=" + promotionalCode.value;;
			var response = cleanResponse(sendXMLRequestSync(urlValidatePCode));
			var promotionalCodeError = (response != "true")?response:"";
			if (promotionalCodeError != "") {
				// Invalid promotional code
				loadingProcess(SEARCH_FORM_BUTTON_ID, searchButtonClass, searchButtonTxt);
				get(SEARCH_ERROR_BOX).style.display='block';
				get(SEARCH_ERROR_PROMOTIONAL_CODE_ID).innerHTML = (promotionalCodeError == 'OverUsedLimit')?USED_PROMOTIONAL_CODE:INVALID_PROMOTIONAL_CODE;
				return false;
			}
			params+= "&pcode=" + promotionalCode.value;
		}
	} else if (!isEmpty(selectedPromotionalCode)) {
		params+= "&pcode=" + selectedPromotionalCode;
	}
	
	if (filtersActive) { // if filtersActive, include filter user specification in queryString 
		// 2.3 services
		var services = getServicesSelected();
		if (services != null) {
			params+= "&services=" + separateByComas(services);
		}
		
		// 2.4 price
		params+= "&maxPrice=" + getMaxPriceSelected();
	} else { // if filtersActive is unset or false, reset filters
		params+= "&services=&maxPrice=";
	}
	
	// 3. CPTP 
	if (cptpMode) params += getCPTPParams();
	
	// 4. Omniture  
	params += "&searchLauncher=" + searchLauncher;
	
	// LAST -> location search text
	if (searchType == SEARCH_TYPE_GEO_SEARCH) {
		params += "&stext=" + get(SEARCH_FORM_LOCATION_ELEMENT_NAME).value;
		url = (url + params).replace(/\?&/,"?");
		searchGeoLocation(url);		
	} else {
		params += "&stext=";
		if(isSearchMini) go((url + params).replace(/\?&/,"?"), window.parent);
		else go((url + params).replace(/\?&/,"?"));
	}
}

function sendSearchPromotionForm() {
	if (!validate()) return false;
	
	var loading = loadForm();
	if (loading) return false;
	
	// 1. url
	var url = getUrl();
	
	var goToHome = true;
	var promotionCategory = getValue(SEARCH_FORM_PROMOTIONS_CATEGORY);
	var fini = getValue(SEARCH_FORM_DATE_FROM_ELEMENT_NAME);
	var fout = getValue(SEARCH_FORM_DATE_TO_ELEMENT_NAME);
	if((fini != null && fini != '') ||  (fout != null && fout != '') 
		|| promotionCategory != 0 || getValue(SEARCH_FORM_COUNTRY_ELEMENT_NAME) != 0 
		|| getValue(SEARCH_FORM_CITY_ELEMENT_NAME) != 0 || getValue(SEARCH_FORM_HOTEL_ELEMENT_NAME) != 0) 
		goToHome = false;
		
	if (goToHome) { 
		if(url.lastIndexOf("?") == url.length -1) 
			url = url.substring(0, url.length -1); 
		go(url.replace(/\?&/,"?"));
		return;
	}
	
	// 2.1 bookig params
	var params = '';
	
	params += getAction(url);
	params += getBookingParams();
	
	// 3. Promotions Search Engine
	if(promotionCategory != 0)
		params+= "&promotionCategory="+ promotionCategory;
	
	go((url + params).replace(/\?&/,"?"));
}

function clearDatesAndSubmit() {
	get(SEARCH_FORM_DATE_FROM_ELEMENT_NAME).value = null;
	get(SEARCH_FORM_DATE_TO_ELEMENT_NAME).value = null;
	sendSearchPromotionForm();
}

function loadForm(filtersActive) {
	var searchButton = get(SEARCH_FORM_BUTTON_ID);
	if (searchButton == null) return;
	searchButtonTxt = searchButton.value;
	searchButtonClass = searchButton.className;
	// odd extra hiding process 
		var extra = get("extraSearchButton");
		if (extra != null) extra.style.display = "none";	
	if (filtersActive) return loadingProcess('searchFilterButton', 'btn-buscando', FILTERING_TXT);
	return loadingProcess(SEARCH_FORM_BUTTON_ID, 'btn-buscando', SEARCHING_TXT);
}

function getUrl(searchType) {
	var countryId = getValue(SEARCH_FORM_COUNTRY_ELEMENT_NAME);
	var cityId = getValue(SEARCH_FORM_CITY_ELEMENT_NAME);
	var hotelId = "0";
	if((searchType != null) && (searchType != SEARCH_TYPE_GEO_SEARCH)){
		hotelId = getValue(SEARCH_FORM_HOTEL_ELEMENT_NAME);
	}
	var url = generateURL(countryId, cityId, hotelId);
	return url;
}

function getAction(url) {
	if (url.indexOf('?') == -1) return "?action=search"; 
	return "&action=search"; 
}

function getCPTPParams(alreadySelected) {
	var cptpParams = "";
	var partyId = (alreadySelected == true)?selectedPartyId:getValue(PARTY_ID_ELEMENT_NAME, mapParentDocument);
	var branchId = (alreadySelected == true)?selectedBranchId:getValue(BRANCH_ID_ELEMENT_NAME, mapParentDocument);
	var clientId = (alreadySelected == true)?selectedClientId:getValue(CLIENT_ID_ELEMENT_NAME, mapParentDocument);
	var quickSearch = getValue(SEARCH_FORM_QUICK_SEARCH_ELEMENT_NAME, mapParentDocument);
	if (!isEmpty(partyId) && partyId != NO_VALUE) cptpParams+= "&party=" + partyId;
	if (!isEmpty(branchId) && partyId != NO_VALUE) cptpParams+= "&branch=" + branchId;
	if (!isEmpty(clientId) && partyId != NO_VALUE) cptpParams+= "&client=" + clientId;
	if (!isEmpty(quickSearch)) cptpParams+= "&quick=" + quickSearch;
	return cptpParams;
}

function getBookingParams(roomElementIdParam) {
	var bookingParams = "";
	// dates
	/* Si estamos en el step6 de OBE no existen los elementos 
	 * SEARCH_FORM_DATE_FROM_ELEMENT_NAME y SEARCH_FORM_DATE_TO_ELEMENT_NAME
	 * pero si estan definidas las variables fini y fout.
	 */
	var ffini = "";
	var ffout = ""
	
	if (get(SEARCH_FORM_DATE_FROM_ELEMENT_NAME, mapParentDocument) == null){
		ffini = fini;
		ffout = fout;
	}else{
		ffini = get(SEARCH_FORM_DATE_FROM_ELEMENT_NAME, mapParentDocument).value;
		ffout = get(SEARCH_FORM_DATE_TO_ELEMENT_NAME, mapParentDocument).value; 
	}
		
	bookingParams += "&fini=" + ffini;
	bookingParams += "&fout=" + ffout;

	// rooming
	
	if(isSearchMini){ bookingParams += getRoomingMini(); }
	else{
		var roomElementId = (roomElementIdParam != null)?roomElementIdParam:DEFAULT_ROOM_ELEMENT_ID;
		if (get(roomElementId, mapParentDocument) != null) {
			var userRoomingData = getRoomingUserInfo(roomElementId);
			for (var i = 1; i < userRoomingData.length; i++) {
				bookingParams += "&nadults" + i + "=" + userRoomingData[i].nAdults;
				bookingParams += "&nchilds" + i + "=" + userRoomingData[i].nChilds;
			}
		}else if(selectedUserRoomingData != null){ //Si estamos en el step6 de OBE...
			var userRoomingData = selectedUserRoomingData; 
			for (var i = 1; i < userRoomingData.length; i++) {
				bookingParams += "&nadults" + i + "=" + userRoomingData[i].nAdults;
				bookingParams += "&nchilds" + i + "=" + userRoomingData[i].nChilds;
			}
		}
	}
	return bookingParams;
}

function areDatesSelected() {
	var from = get(SEARCH_FORM_DATE_FROM_ELEMENT_NAME, mapParentDocument).value;
	var to = get(SEARCH_FORM_DATE_TO_ELEMENT_NAME, mapParentDocument).value;
	return (!isEmpty(from) && !isEmpty(to));
}

function validate() {
	if (!mandatoryFieldCheck) return true;
	// place in here any validation needed for search form sending (in standard conditions, there is no condition to evaluate)
	var fromDate = get(SEARCH_FORM_DATE_FROM_ELEMENT_NAME);
	if (fromDate != null && fromDate.value == '') {
		tagScriptForFormErrors(MISSING_DATA_ERROR);
		alert(MANDATORY_DATES); return false;
	}
	
	if (campaignsMode) {
		var promotionalCodeSelector = get(SEARCH_FORM_PROMOTIONAL_CODE_SELECTOR_ELEMENT_ID);
		var promotionalCode = selectedPromotionalCode;
		if (get(SEARCH_FORM_PROMOTIONAL_CODE_ELEMENT_ID) != null)
			promotionalCode = get(SEARCH_FORM_PROMOTIONAL_CODE_ELEMENT_ID).value;
			
		if ((promotionalCodeSelector != null) && promotionalCodeSelector.checked 
				&& isEmpty(promotionalCode)) {
			tagScriptForFormErrors(MISSING_DATA_ERROR);
			alert(MANDATORY_PROMOTIONAL_CODE); return false;
		}
	}
	else if (cptpMode) {
		var partyId = get(PARTY_ID_ELEMENT_NAME);			
		if (partyId != null && partyId.value == NO_VALUE) {
			alert(MANDATORY_COMPANY); return false;
		}
		var branchId = get(BRANCH_ID_ELEMENT_NAME);
		if (branchId != null && branchId.value == NO_VALUE) {
			alert(MANDATORY_BRANCH); return false;
		}
		if(cptpMode && (isSelectedCodeNoValue(getValue(SEARCH_FORM_CITY_ELEMENT_NAME)))){
			alert(MANDATORY_CITY);
			return false;
		}
	} 
	return true;
}

function isSearchReady() {
	return (typeof(searchValuesReady) !== "undefined" && searchValuesReady == true);
}

function setGeoSearchType() {
	// disable hotel combo
	var hotelSelect = get(SEARCH_FORM_HOTEL_ELEMENT_NAME);
	hotelSelect.disabled = true;
	// enable location input
	var location = get(SEARCH_FORM_LOCATION_ELEMENT_NAME);
	location.disabled = false;
} 

function checkPOIState() {
	var citySelect = get(SEARCH_FORM_CITY_ELEMENT_NAME);
	var location = get(SEARCH_FORM_LOCATION_ELEMENT_NAME);
	var cityCode = null;
	
	if((citySelect == null) || (location == null)) return;
	
	cityCode = citySelect.options[citySelect.selectedIndex].value;
	
	if (isSelectedCodeNoValue(cityCode) || (getSearchType() == SEARCH_TYPE_DEFAULT)) {
		markComboAsDisabled(location);
		location.value = '';
	} else{ // solo queda una opcion posible: busqueda por location...
		markComboAsEnabled(location);
	}
}

function changeSearchType(searchTypePreSelected, locationTextPreSelected) {
	var searchType = (!isEmpty(searchTypePreSelected))?searchTypePreSelected:getSearchType();
	var searchTypeSelector = get(SEARCH_TYPE_SELECTOR_ELEMENT_PREFIX + searchType);
	if (searchTypeSelector == null) return;
	searchTypeSelector.checked = true;

	var hotelSelect = get(SEARCH_FORM_HOTEL_ELEMENT_NAME);
	var location = get(SEARCH_FORM_LOCATION_ELEMENT_NAME);
	
	var citySelect = get(SEARCH_FORM_CITY_ELEMENT_NAME);
	selectedCityCode = citySelect.options[citySelect.selectedIndex].value;
	
	if (searchType == SEARCH_TYPE_DEFAULT) {
		if(!isSelectedCodeNoValue(selectedCityCode)){
			markComboAsEnabled(hotelSelect);
			//repaintHotels(selectedCityCode, selectedHotelId);
		}
		location.value = '';
		location.disabled = true;
	} else {
		markComboAsDisabled(hotelSelect);
		location.disabled = false;
		if (isDefined(locationTextPreSelected)) location.value = locationTextPreSelected;
	}
	checkPOIState();
}


function getSearchType() {
	var SEARCH_TYPE_SELECTOR_GEO_ELEMENT_ID = SEARCH_TYPE_SELECTOR_ELEMENT_PREFIX + SEARCH_TYPE_GEO_SEARCH;
	var searchTypeSelector = get(SEARCH_TYPE_SELECTOR_GEO_ELEMENT_ID);
	return (searchTypeSelector != null && searchTypeSelector.checked)?SEARCH_TYPE_GEO_SEARCH:SEARCH_TYPE_DEFAULT;
}

function setSearchLauncher(launcher){
	searchLauncher = launcher;
}

// out function
function reserveWithSelectedDates(hotelId, offLine, urlOffLine) {
	if (!isSearchReady()) return;
	var selectedFromDate = get(SEARCH_FORM_DATE_FROM_ELEMENT_NAME);
	var selectedToDate = get(SEARCH_FORM_DATE_TO_ELEMENT_NAME);
	if (selectedFromDate == null || selectedFromDate == '') return;
	mandatoryFieldCheck = true;
	if (!validate()) return;
	// consider selected dates as preselected dates 
	fini = selectedFromDate;
	fout = selectedToDate;
	reserve(hotelId, offLine, urlOffLine);
}

//out function
function reserve(hotelId, offLine, urlOffLine, promoId) {
	// TODO: selectedPromotionId
	if (!isSearchReady()) return; 
	var url = "";
	var hotelParam = "hotelId=" + hotelId;
	if (offLine && !areDatesSelected()) {
		url = addParams(PRE_BOOKING_PAGE_PREFIX_URL, new Array("?action=search", hotelParam));
		go(url);
		return;
	}else if(offLine){
		if (urlOffLine != '') url = urlOffLine;
		else url = addParams(BOOKING_BY_MAIL_URL, new Array("?action=search", getBookingParams()));
		go(url);
		return;
	}
	if (areDatesSelected())	{
		url = addParams(BOOKING_URL, new Array(hotelParam, getBookingParams()));
	} else url = addParams(PRE_BOOKING_PAGE_PREFIX_URL, new Array("?action=search", hotelParam));
	// include selected promotioanl code, if available
	if (!isEmpty(selectedPromotionalCode)) url = addParam(url, "pcode=" + selectedPromotionalCode);
	if (!isEmpty(weekcode)) url = addParam(url, "weekcode=" + weekcode);
	// for specific promotion selection
	if (promoId != null) url = addParam(url, "idpromo=" + promoId);
	else if (!isEmpty(selectedPromotionId)) url = addParam(url, "idpromo=" + selectedPromotionId);
	if (!isEmpty(selectedRate)) url = addParam(url, "rate=" + selectedRate);
	if (!isEmpty(selectedWebRate)) url = addParam(url, "webrate=" + selectedWebRate);
	if (cptpMode) url += getCPTPParams(true);
	go(url, mapParentDocument);
}

function goToSearch(url, cptpMode) {
	// TODO faltan promotional-codes?, rate?
	url += getAction(url);
	url += getBookingParams();	
	if (cptpMode) url += getCPTPParams(true);
	if(!isSearchMini)
		go(url);
	else
		go(url, 'top');
}

function launchHelp() {
	var element = get(HELP_ID);
	if (element == null) return;
	if (!helpBox)
		var helpBox = new MultiBox('smb', {descClassName: false, useOverlay: true});
	helpBox.open(element);
}

/*************************************************
			  START URLS GENERATOR
*************************************************/
function generateURL (countryId, cityId, hotelId){
	var url = "";
	if (objectLength(comboConditions)>0)
		url += generateConditionsURL(countryId, cityId, hotelId);
	
	if (url == "")
		url += generateSemanticPath(countryId, cityId, hotelId);
	return url;
}

function generateConditionsURL (countryId, cityId, hotelId){
	for (oneCondition in comboConditions){
		var condition = comboConditions[oneCondition];
		if (condition.apply == true){
			if (condition.url!=null){
				var url = condition.url;
				if (url.indexOf('?') == -1) url+='?';
				if (hotelId!=0){
					if (condition.respectHotelDetail==true) return "";
					url += '&hotel=' + hotelId;
				}
				if (cityId!=0) url += '&city=' + cityId;
				if (countryId!=0) url += '&country=' + countryId;
				
				if (url != "?") return url;
			}
		}
	}
	return "";
}

function generateSemanticPath(countryId, cityId, hotelId) {
	var hotel = jsHotels[getMapKey(hotelId)];
	if (hotel != null) return hotel.getUrl();
	
	var city = jsCities[getMapKey(cityId)];

	if (city != null) return city.getUrl();
	
	var country = jsCountries[getMapKey(countryId)]
	if (country != null) return country.getUrl();
	
	return WORLD_RESULTS_URL; 
}

/*************************************************
			  END URLS GENERATOR
*************************************************/


/*************************************************
			  START MATCH CONDITIONS
*************************************************/
// Para incluir un condition ï¿½nicamente hay que crear una instancia de 
// MatchConditions(hotelArray, citiesArray, countriesArray, apply, name, url)
// donde hotelArray, citiesArray y countriesArray identifican ï¿½nicamente
// los identificadores de cada uno de ellos y dos de ellos pueden ser nulos.
// Es decir, si la condiciï¿½n es que sï¿½lo se quieren ver los hoteles de una categorï¿½a
// bastarï¿½a con incluir el array de hoteles y los demï¿½s dejarlos nulos, y si se 
// quiere categorizar por las ciudades en las que se puede fumar, se podrï¿½an dejar los
// hoteles y los paï¿½ses nulos, y rellenar el array de ciudades.
// APPLY indica si se aplica o no se aplica en ese momento, NAME indica el identificador de la categorï¿½a. 
// y URL indica la URL de destino en caso de filtrar (puede ser nula y mantener la URL por defecto).
// Ademï¿½s, existe la funciï¿½n applyCondition(nameCondition, apply) con la que se podrï¿½
// cambiar el estado de la condiciï¿½n (activando/desactivando).
// *************
var comboConditions = new Object();

function MatchConditions(hotelsArray, citiesArray, countriesArray, apply, name, url, respectHotelDetail) {
	this.hotels = new Object(); 
	this.cities = new Object();
	this.countries = new Object();
	this.apply = (apply==null)?true:apply;
	this.name = name;
	this.url = url;
	this.respectHotelDetail = respectHotelDetail;
		
	this.fillCity = function fillCity(hotels) {
		for (id in hotels) {
			this.cities[jsHotels[getMapKey(id)].cityCode] = true;
		}	
	}
	
	this.fillCountry = function fillCountry(cities) {
		for (id in cities) {
			this.countries[jsCities[getMapKey(id)].countryCode] = true;
		}
	}
	
	// There are data
	comboConditions[this.name] = this;
	
	// Assign data
	if (hotelsArray != null) {
		this.hotels = arrayToObject(hotelsArray);
		this.fillCity(this.hotels);
		this.fillCountry(this.cities);
	} else if (citiesArray != null) {
		this.cities = arrayToObject(citiesArray);
		this.fillCountry(this.cities);
	} else if (countriesArray != null){
		this.countries = arrayToObject(countriesArray);
	} 
}

function applyCondition(nameCondition, apply){
	comboConditions[nameCondition].apply = apply;
	var countrySelect = get(SEARCH_FORM_COUNTRY_ELEMENT_NAME);
	resetCombo(countrySelect, false);
	initSearch();
}

function countryMatchConditions (idCountry){
	for (oneCondition in comboConditions){
		var condition = comboConditions[oneCondition];
		if (objectLength(condition.countries) > 0){
			if (condition.apply == true){
				if (condition.countries[idCountry]!=true){
					return false;
				}
			}
		}
	}
	return true;
} 

function cityMatchConditions(idCity){
	for (oneCondition in comboConditions){
		var condition = comboConditions[oneCondition];
		if (objectLength(condition.cities) > 0){
			if (condition.apply == true) {
				if (objectLength(condition.cities)>0) {
					if (condition.cities[idCity]!=true) {
						return false;
					}
				}
			}
		}
	}
	return true;
}

function hotelMatchConditions(idHotel){
	for (oneCondition in comboConditions){
		var condition = comboConditions[oneCondition];
		if (objectLength(condition.countries) > 0) {
			if (condition.apply == true) {
				if (objectLength(condition.hotels)) {
					if (condition.hotels[idHotel]!=true){
						return false;
					}
				}
			}
		}
	}
	return true;
}
/*************************************************
			  END MATCH CONDITIONS
*************************************************/


function isSelectedCodeNoValue(code) {
	return ((code == "") || (code == NO_VALUE));
}

function showHideFilter(cityCode){
	if(get(DIV_FILTER) != null){
		isSelectedCodeNoValue(cityCode)? hide(get(DIV_FILTER)): show(get(DIV_FILTER));
	}
}

function getMapKey(key){
	if(key.indexOf(CHARACTER_MAP_KEY) != 0) return CHARACTER_MAP_KEY + key;
	else return key;
}