	// *****************************************************************************************************************
	// General AJAX functions
	// *****************************************************************************************************************

	var AJAX_PAGE_TARGETED_PROMOTION = '/presentation/modules/general/genAjaxTargetedPromotion.jsp';
	var AJAX_PAGE_HTL_ADDITIONAL_VALUES = '/presentation/modules/hotel/htlAjaxAvailGetRoomInfo.jsp';
	var AJAX_PAGE_GEN_GET_DESTINATIONS_FROM_INPUT = '/presentation/modules/general/genAjaxDestinationsFromInput.jsp';
	var AJAX_PAGE_BKN_PAYMENT_PGO_REFRESH = '/presentation/modules/booking/bknPaymentAjaxPGORefresh.jsp';


	var REQUEST_OBJECT;

	function createRequestObject(mimeType){
		// NOTE! IE don't need to override the mime type, it will understand the XML anyway
		if (window.XMLHttpRequest) { /* Mozilla and others... */
			try {
				reqObj = new XMLHttpRequest();
				if (reqObj.overrideMimeType) { // not for everyone...
                    if (mimeType)
                        reqObj.overrideMimeType(mimeType);
                    else
    					reqObj.overrideMimeType("text/xml");
                }
			} catch(e) {
				reqObj = false;
			}
		} else if (window.ActiveXObject) { /* Internet Explorer */
			try {
				reqObj = new ActiveXObject("Microsoft.XMLHTTP");
			} catch(e) {
				try {
					reqObj = new ActiveXObject("Microsoft.XMLHTTP");
				} catch(e) {
					reqObj = false;
				}
			}

		} else { /* Unsupported AJAX browser, ignore me later... */
			reqObj = false;
		}

		return reqObj;
	}

	function ajaxRequest(url, responseHandler){
		// do call if browser supports it
		if (REQUEST_OBJECT) {
			eval('REQUEST_OBJECT.onreadystatechange = ' + responseHandler);
			REQUEST_OBJECT.open('GET', url, true);
			REQUEST_OBJECT.send(null);
		}
	}

	function abortRequest() {
		REQUEST_OBJECT.abort();
	}

	function getXMLNodeText(node){
		if (node && node.childNodes[0])
			return node.childNodes[0].nodeValue;
		else
			return '';
	}




	// *****************************************************************************************************************
	// Targeted promotions
	// *****************************************************************************************************************

	function ajaxTargetPromotion(type, product, destination, destinationText) {
		REQUEST_OBJECT = createRequestObject();
		if (REQUEST_OBJECT) {
			ajaxRequest(AJAX_PAGE_TARGETED_PROMOTION+'?type='+type+'&product='+product+'&destination='+destination+"&destinationText="+escape(destinationText), 'handleResponseForTargetedPromotion');
		}
	}

	function handleResponseForTargetedPromotion() {
		if (REQUEST_OBJECT && REQUEST_OBJECT.readyState == 4) {
			if (REQUEST_OBJECT.status == 200 && REQUEST_OBJECT.responseXML) {
				imagePathObj = REQUEST_OBJECT.responseXML.getElementsByTagName('imagePath');
				promotionTextObj = REQUEST_OBJECT.responseXML.getElementsByTagName('promotionText');
				promotionCodeObj = REQUEST_OBJECT.responseXML.getElementsByTagName('promotionCode');
				if (imagePathObj || promotionTextObj) {
					wmDivObj = getDiv('waitMessage-banner');
					if (wmDivObj) {
						var imagePath, promotionText, promotionCode;
						if (imagePathObj)
							imagePath = getXMLNodeText(REQUEST_OBJECT.responseXML.getElementsByTagName('imagePath')[0]);
						if (promotionTextObj)
							promotionText = getXMLNodeText(REQUEST_OBJECT.responseXML.getElementsByTagName('promotionText')[0]);
						if (promotionCodeObj)
							promotionCode = getXMLNodeText(REQUEST_OBJECT.responseXML.getElementsByTagName('promotionCode')[0]);

						var promotionDiv = '';
						if (imagePath || promotionText) {
							if (imagePath)
								promotionDiv += '<img src="' + imagePath + '" border="0" alt="">' + (promotionText ? '<br/><br/>' : '');
							if (promotionText)
								promotionDiv += '<p class="waitMessage-H3">' + promotionText + '</p>';
							// Omniture part (log as event 17)
							if (typeof s != "undefined") {
								s.eVar45 = promotionCode;
								s.events = 'event17';
								try{var s_code=s.t();}catch(err){}
								try{if(s_code)promotionDiv+=(s_code)}catch(err){}
								if(navigator.appVersion.indexOf('MSIE')>=0)promotionDiv+=(unescape('%3C')+'\!-'+'-')
							}
							wmDivObj.innerHTML += promotionDiv;
						} else {
                            /*
                            window.Fusion.mediaZone = 'travellink.se.leisure.waitmessage';
                            window.Fusion.layout = 'banner_waitmess';
                            window.Fusion.loadAds();
                            return false;
                            */
                        }
					}
				}
			}
		}
	}




	// *****************************************************************************************************************
	// Hotel additional values (avail)
	// *****************************************************************************************************************

	var HTL_IDX = 0;
	var MAX_IDX = 10;
	var HTL_ADD_VALUE_SPLASH_MESSAGE = '';
	var HTL_ADD_VALUE_ROOM_WITH_BREAKFAST_MESSAGE = '';
	var HTL_ADD_VALUE_SUFFIX = '';
	var HTL_ADD_VALUE_ROOMS_LEFT = '';

	function handleResponseForHtlAdditionalValues() {
		if (REQUEST_OBJECT && REQUEST_OBJECT.readyState == 4) {
			if (REQUEST_OBJECT.status == 200) {
				// alert(REQUEST_OBJECT.responseText);
				var hotelBaseNode = REQUEST_OBJECT.responseXML.getElementsByTagName('hotels');
				if (hotelBaseNode && hotelBaseNode[0] && hotelBaseNode[0].hasChildNodes()) {
					hotelList = hotelBaseNode[0].getElementsByTagName('hotel');
					if (hotelList && hotelList.length > 0) {
						for (i=0; i < hotelList.length; i++) {
							addValueDivValue = '';
							hotelId = getXMLNodeText(hotelList[i].getElementsByTagName('hotelId')[0]);

							// break if we can't find add value div...
							addValueDiv = getDiv('roomAdditionalValues'+hotelId);
							if (!addValueDiv)
								break;

							// populate rooms left
							roomsLeft = getXMLNodeText(hotelList[i].getElementsByTagName('roomsLeft')[0]);
							if (roomsLeft && roomsLeft != -1 && HTL_ADD_VALUE_ROOMS_LEFT) {
								addValueDivValue += HTL_ADD_VALUE_ROOMS_LEFT.replace('${roomsLeft}', roomsLeft);
								display('roomAdditionalValues'+hotelId, true);
							}

							// populate room with breakfast availabel at additional cost
							roomWithBreakfastAdditionalCost = getXMLNodeText(hotelList[i].getElementsByTagName('roomWithBreakfastAdditionalCost')[0]);
							if (roomWithBreakfastAdditionalCost && HTL_ADD_VALUE_ROOM_WITH_BREAKFAST_MESSAGE) {
								addValueDivValue += (addValueDivValue ? '<br/>' : '') + HTL_ADD_VALUE_ROOM_WITH_BREAKFAST_MESSAGE.replace('${priceWithCurrency}', roomWithBreakfastAdditionalCost);
								display('roomAdditionalValues'+hotelId, true);
							}

							// populate rooms additional values
							roomList = hotelList[i].getElementsByTagName('rooms');
							for (j=0; j < roomList.length; j++) {
								addValueList = roomList[j].getElementsByTagName('additionalValue');
								for (k=0; k < addValueList.length; k++) {
									addValueDivValue += (addValueDivValue ? '<br/>' : '') + getXMLNodeText(addValueList[k]) + ' ' + HTL_ADD_VALUE_SUFFIX;
									display('roomAdditionalValues'+hotelId, true);
								}
							}

							addValueDiv.innerHTML = addValueDivValue;
						}
					}
				}
				HTL_IDX = HTL_IDX+5;
				ajaxHtlAdditionalValues();
			}
		}
	}

	/*
	* NOTE! splashMessage and roomWithBreakfastMessage are only set when calling this message from the JSP page
	*/
	function ajaxHtlAdditionalValues(splashMessage, roomWithBreakfastMessage, addValueSuffix, roomsLeftMessage) {
		REQUEST_OBJECT = createRequestObject();
		if (REQUEST_OBJECT && HTL_IDX < MAX_IDX) {
			if (splashMessage) {
				HTL_ADD_VALUE_SPLASH_MESSAGE = splashMessage;
				showSplashMessage(HTL_ADD_VALUE_SPLASH_MESSAGE, true, 8);
			}
			if (roomWithBreakfastMessage)
				HTL_ADD_VALUE_ROOM_WITH_BREAKFAST_MESSAGE = roomWithBreakfastMessage;
			if (addValueSuffix)
				HTL_ADD_VALUE_SUFFIX = addValueSuffix;
			if (roomsLeftMessage)
				HTL_ADD_VALUE_ROOMS_LEFT = roomsLeftMessage;

			ajaxRequest(AJAX_PAGE_HTL_ADDITIONAL_VALUES + '?startIdx='+HTL_IDX, 'handleResponseForHtlAdditionalValues');
		} else {
			showSplashMessage('', false);
		}
	}


	// *****************************************************************************************************************
	// Destination input
	// *****************************************************************************************************************

	var DESTINATION_INPUT_OBJECT;
	function handleResponseForDestinationInput() {
		if (REQUEST_OBJECT && REQUEST_OBJECT.readyState == 4) {
			if (REQUEST_OBJECT.status == 200) {
				var possibleDestinations = new Array();

				// make sure a session timeout haven't occured (if so, redirect user to session timeout)
				responseText = REQUEST_OBJECT.responseText;
				if (responseText.indexOf('@@@SESSION_TIMEOUT_PAGE@@@') > -1) {
					document.location.href = '/main?type=General&name=GenSessionTimeout';
					return;
				} else if (responseText.indexOf('@@@GENERAL_ERROR_PAGE@@@') > -1) {
					// if we got a general error in the ajax call we do not want the customer to get a javascript error
					// so break here in that case
					return;
				} else if (responseText.indexOf('@@@CACHES_NOT_BUILT@@@') > -1) {
					// caches are not built after restart, don't give any response to the user...
					return;
				}

				var jsonObj = eval('(' + responseText + ')');
				if (jsonObj && jsonObj.destinations.length > 0) {
					for (i=0; i < jsonObj.destinations.length; i++) {
						destObj = new Object();
						destObj.KEY = jsonObj.destinations[i].key;
						destObj.TYPE = jsonObj.destinations[i].type;
						destObj.NAME = jsonObj.destinations[i].name;
						destObj.COMPLETE_NAME = jsonObj.destinations[i].completeName;
						possibleDestinations[possibleDestinations.length] = destObj;
					}
				} else {
					destObj = new Object();
					destObj.KEY = 'NO_DESTINATION_FOUND';
					destObj.NAME = 'NO_DESTINATION_FOUND';
					destObj.COMPLETE_NAME = 'NO_DESTINATION_FOUND';
					possibleDestinations[possibleDestinations.length] = destObj;
				}

				DESTINATION_INPUT_OBJECT.possibleDestinationsArray = possibleDestinations;
				DESTINATION_INPUT_OBJECT.findDestinationsClosure();
			}
		}
	}

	function ajaxDestinationsFromInput(inputObj) {
		DESTINATION_INPUT_OBJECT = inputObj;
		REQUEST_OBJECT = createRequestObject('application/json');
		ajaxRequest(AJAX_PAGE_GEN_GET_DESTINATIONS_FROM_INPUT + '?inputStr='+escape(inputObj.inputText)+'&product='+inputObj.product, 'handleResponseForDestinationInput');
	}

	function ajaxDestinationsByParent(inputObj, parentCode, parentName) {
		DESTINATION_INPUT_OBJECT = inputObj;
		REQUEST_OBJECT = createRequestObject('application/json');
		ajaxRequest(AJAX_PAGE_GEN_GET_DESTINATIONS_FROM_INPUT + '?parentCode='+escape(parentCode)+'&parentName='+escape(parentName)+'&product='+inputObj.product, 'handleResponseForDestinationInput');
	}

	// *****************************************************************************************************************
	// PGO override at payment...
	// *****************************************************************************************************************

	function handlePaymentOverride() {
		if (REQUEST_OBJECT && REQUEST_OBJECT.readyState == 4) {
			if (REQUEST_OBJECT.status == 200) {
				/*
				// we do nothing here, if it doesn't work it it is not much we can do...
				responseText = REQUEST_OBJECT.responseText;
				var jsonObj = eval('(' + responseText + ')');
				if (jsonObj && jsonObj.result.length > 0) {
					alert(jsonObj.result);
				}
				*/
			}
		}
	}

	function ajaxPaymentPGOSessionRefresh() {
		REQUEST_OBJECT = createRequestObject();
		ajaxRequest(AJAX_PAGE_BKN_PAYMENT_PGO_REFRESH, 'handlePaymentOverride');
	}
