/**
 * Copyright 2005 Darren L. Spurgeon
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * -----
 *
 * liveUpdater function and other portions copyright by:
 * Copyright 2004 Leslie A. Hensley (hensleyl@papermountain.org)
 *   you have a license to do what ever you like with this code
 *   orginally from Avai Bryant
 *   http://www.cincomsmalltalk.com/userblogs/avi/blogView?entry=3268075684
 */

//
// GLOBAL OPTIONS
//
/**
	$Revision: 1.3.2.48 $
*/
var isSafari = false;
var isMoz = false;
var isIE = false;

if (navigator.userAgent.indexOf("Safari") > 0) {
  isSafari = true;
  isMoz = false;
  isIE = false;
}
else if (navigator.product == "Gecko") {
  isSafari = false;
  isMoz = true;
  isIE = false;
} else {
  isSafari = false;
  isMoz = false;
  isIE = true;
}

var ie = (document.all && !window.opera) ? 1 : 0; // MS Internet Explorer
var ie7 = false;
/*@cc_on
   /*@if (@_jscript_version >= 5.7)
	   ie7 = true;
    @*/
   /*@end
@*/

//
// GLOBAL FUNCTIONS
//
/* Functions to handle browser incompatibilites */
function eventElement(event) {
  if (isMoz) {
    return event.currentTarget;
  } else {
    return event.srcElement;
  }
}

function addKeyListener(element, listener) {
  if (isSafari)
    element.addEventListener("keydown",listener,false);
  else if (isMoz)
    element.addEventListener("keypress",listener,false);
  else
    element.attachEvent("onkeydown",listener);
}

function addListener(element, type, listener) {
  if (element.addEventListener) {
    element.addEventListener(type, listener, false);
  } else {
    element.attachEvent('on' + type, listener);
  }
}

function removeListener(element, type, listener) {
  if (element.removeEventListener) {
    element.removeEventListener(type, listener, false);
  } else {
    element.detachEvent('on' + type, listener);
  }
}

/* XML Helper functions */
function flatten(node) {
  if (node.nodeType == 1) {
    return '<' + node.nodeName + flattenAttributes(node) + '>' +
    flattenChildren(node.childNodes) + '</' + node.nodeName + '>';
  } else if(node.nodeType == 3) {
    return node.nodeValue;
  }
}

function flattenAttributes(node) {
  var buffer = '';
  for (var i=0;i<node.attributes.length;i++) {
    var attribute = node.attributes[i];
    buffer += ' '+ attribute.name + '="' + attribute.value + '"';
  }
  return buffer;
}

function flattenChildren(nodes) {
  var buffer = '';
  if (nodes.length > 0) {
    for (var i=0;i<nodes.length;i++) {
      buffer += flatten(nodes[i]);
    }
  }
  return buffer;
}

function copyAttributes(source, destination) {
  for (var i=0;i<source.attributes.length;i++) {
    var attribute = source.attributes[i];
    destination.setAttribute(attribute.name, attribute.value);
  }
  destination.className = source.getAttribute('class');
}

function getElementY(element){
  var targetTop = 0;
  if (element.offsetParent) {
    while (element.offsetParent) {
      targetTop += element.offsetTop;
      element = element.offsetParent;
    }
  } else if (element.y) {
    targetTop += element.y;
  }
  return targetTop;
}

function getElementX(element){
  var targetLeft = 0;
  if (element.offsetParent) {
    while (element.offsetParent) {
      targetLeft += element.offsetLeft;
      element = element.offsetParent;
    }
  } else if (element.x) {
    targetLeft += element.yx;
  }
  return targetLeft;
}



/**
 * Returns true if an element has a specified class name
 */
function hasClass(node, className) {
  if (node.className == className) {
    return true;
  }
  var reg = new RegExp('(^| )'+ className +'($| )')
  if (reg.test(node.className)) {
    return true;
  }
  return false;
}

/**
 * Adds a class name to an element
 */
function addClass(node, className) {
  if (hasClass(node, className)) {
    return false;
  }
  node.className += ' '+ className;
  return true;
}

/**
 * Removes a class name from an element
 */
function removeClass(node, className) {
  if (!hasClass(node, className)) {
    return false;
  }
  node.className = eregReplace('(^| )'+ className +'($| )', '', node.className);
  return true;
}

/**
 * Emulate PHP's ereg_replace function in javascript
 */
function eregReplace(search, replace, subject) {
  return subject.replace(new RegExp(search,'g'), replace);
}

//
// LIVE UPDATE CORE
//
/*
  liveUpdater returns the live update function to use
  uriFunc: The function to generate the uri
  postFunc: <optional> Function to run after processing is complete
  preFunc: <optional> Function to run before processing starts
*/
function liveUpdater(uriFunc, handlerFunc, preFunc, emptyFunc, errorFunc) {
  if (!handlerFunc) handlerFunc = function() {};
  if (!preFunc) preFunc = function () {};
  if (!emptyFunc) emptyFunc = function () {};
  if (!errorFunc) errorFunc = function () {};

  return createLiveUpdaterFunction(uriFunc, handlerFunc, preFunc, emptyFunc, errorFunc);
}

function createLiveUpdaterFunction(uriFunc, handlerFunc, preFunc, emptyFunc, errorFunc) {
    var request = false;
    if (window.XMLHttpRequest) {
      request = new XMLHttpRequest();
    }

    function update() {
      if(request && request.readyState < 4)
        request.abort();

      if(!window.XMLHttpRequest)
        request = new ActiveXObject("Microsoft.XMLHTTP");

      preFunc();
      request.onreadystatechange = processRequestChange;
      request.open("GET", uriFunc());
      request.send(null);
      return true;
    }

    function processRequestChange() {
      try {
	      if(request.readyState == 4) {
	      	if (request.status == 200) {
	          var xmlDoc = request.responseXML;
	          if (xmlDoc.documentElement == null
	          		|| !xmlDoc.documentElement.hasChildNodes()
	          		|| xmlDoc.firstChild.nodeName == "parsererror") {
	          	emptyFunc();
	          } else {
	            handlerFunc(xmlDoc);
	          }
	        } else {
	          errorFunc();
	        }
	      }
	   } catch (e) {} //squelch;
    }
    return update;
}


//
// SELECT/DROPDOWN POPULATION
//
function populateSelect(id, targetId, uri, paramName, postFunc, emptyFunc, errorFunc) {
  var inputField = document.getElementById(id);
  var targetField = document.getElementById(targetId);
  if (!postFunc) postFunc = function () {};
  if (!emptyFunc) emptyFunc = function () {};
  if (!errorFunc) errorFunc = function () {};

  function constructUri() {
    var separator = "?";
    if (uri.indexOf("?") >= 0)
        separator = "&";
    return uri
      + separator
      + paramName
      + "="
      + escape(inputField.options[inputField.selectedIndex].value);
  }

  function handleChange(e) {
    var updater = liveUpdater(constructUri, handlerFunc, null, emptyFunc, errorFunc);
    var timeout = window.setTimeout(updater, 0);
  }

  function handlerFunc(xmlDoc) {
    var root = xmlDoc.documentElement;

    // clear existing options
    targetField.options.length = 0;

    if (root != null) {
      targetField.disabled = false;
      var items = root.childNodes;
      for (var i=0; i<items.length; i++) {
        targetField.options[i] = new Option(items[i].firstChild.nodeValue, items[i].getAttribute("value"));
      }

      targetField.focus();
      postFunc();
    }
  }

  addListener(inputField, "change", handleChange);
}

//
// SELECT/DROPDOWN POPULATION of multiple search and book fields
//
function populateSearchBook(id, targetId, uri, paramName, postFunc, emptyFunc, errorFunc) {
  var inputField = document.getElementById(id);
  var targetField = document.getElementById(targetId + "_" + inputField.options[inputField.selectedIndex].value);

  if (!postFunc) postFunc = function () {};
  if (!emptyFunc) emptyFunc = function () {};
  if (!errorFunc) errorFunc = function () {};
  function constructUri() {
    var separator = "?";
    if (uri.indexOf("?") >= 0)
        separator = "&";
    return uri
      + separator
      + paramName
      + "="
      + escape(inputField.options[inputField.selectedIndex].value);
  }
  function handleChange(e) {
  	// disable updates for flights (dom & int), insurance and discount
    var selector = inputField.options[inputField.selectedIndex].value;
	if (selector == "fs_flights" || selector == "fs_idcards" || selector == "fs_insurance" || selector == "fs_flights_int" || selector == "fs_flights_dom" || selector == "fs_tours" || selector == "fs_eurostar") return null;
    var updater = liveUpdater(constructUri, handlerFunc, null, emptyFunc, errorFunc);
    var timeout = window.setTimeout(updater, 0);
  }
  function handlerFunc(xmlDoc) {
    targetField = document.getElementById(targetId + "_" + inputField.options[inputField.selectedIndex].value); 
    var root = xmlDoc.documentElement;
    // clear existing options
    targetField.options.length = 0;
    if (root != null) {
      targetField.disabled = false;
      var items = root.childNodes;
      for (var i=0; i<items.length; i++) {
        targetField.options[i] = new Option(items[i].firstChild.nodeValue, items[i].getAttribute("value"));
      }
      targetField.focus();
      postFunc();
    }
  }
  addListener(inputField, "change", handleChange);
}

//
// HtmlContent
//
function populateHtmlContent(id, targetId, uri, paramName, postFunc, emptyFunc, errorFunc) {
  var inputField = document.getElementById(id);
  var targetContainer = document.getElementById(targetId);
  if (!postFunc) postFunc = function () {};
  if (!emptyFunc) emptyFunc = function () {};
  if (!errorFunc) errorFunc = function () {};

  function constructUri() {
    var separator = "?";
    if (uri.indexOf("?") >= 0)
        separator = "&";
    return uri
      + separator
      + paramName
      + "="
      + escape(inputField.options[inputField.selectedIndex].value);
  }

  function handleChange(e) {
    var updater = liveUpdater(constructUri, handlerFunc, null, emptyFunc, errorFunc);
    var timeout = window.setTimeout(updater, 0);
  }

  function handlerFunc(xmlDoc) {
	targetContainer.innerHTML = "";
    var root = xmlDoc.documentElement;
    targetContainer.innerHTML = root.firstChild.data;
    postFunc();
  }

  addListener(inputField, "change", handleChange);
}

/* ============= fire event ============= */
function fireOnChange(id) {
	var trigger = document.getElementById(id);
	if (trigger.fireEvent) {
		trigger.fireEvent("onchange");
	} else {
		var evt = document.createEvent("HTMLEvents");
		evt.initEvent("change", false, false);
		trigger.dispatchEvent(evt);
	} 
}

/* ============= ajax handler ============= */
function validate() {
  // do nothing yet
}

/* ============= error handling ============= */
function handleHttpException() { // 'err_ajax' should be decl. & set somewhere. If not, a default text will be thrown.
	try{alert(err_ajax);} catch(e){alert("Sorry, an exception occurred.");}
}
function handleEmpty() {
  var li; 
  try{li=err_empty;} catch(e){li="None";}
  if (document.getElementById("i11")) {
	document.getElementById("i11").options.length = 0;
	document.getElementById("i11").options[0] = new Option(li, "");
	document.getElementById("i11").disabled = true;
  }
}
function resetHcty3() {
  document.getElementById("hcty3").options.length = 0;
  document.getElementById("hcty3").options[0] = new Option("None", "");
  document.getElementById("hcty3").disabled = true;
}

//
// AUTOCOMPLETE
//

var activePopupId = null;

function autocomplete(id, popupId, targetId, uri, paramName, postFunc, progressStyle, minimumCharacters) {
  var inputField = document.getElementById(id);
  var popup = document.getElementById(popupId);
  popup.posChecked = false;
  popup.style.visibility = "hidden";
  var targetField = document.getElementById(targetId);
  if (!postFunc) postFunc = function () {};
  if (minimumCharacters == null || minimumCharacters == "null") minimumCharacters = 1;
  var items = new Array();
  var current = 0;
  var originalPopupTop = popup.offsetTop;
  
  function constructUri() {
    var separator = "?";
    if (uri.indexOf("?") >= 0)
        separator = "&";
    return uri + separator + paramName + "=" + escape(inputField.value);
  }

  function hidePopup(e) {
	if (popup.style.visibility == 'hidden') return;
	if (ie && !ie7) {
		if (window.event.type == 'blur' && window.event.srcElement.id == inputField.id) {
  			removeListener(inputField, 'blur', hidePopup);
  		}
  	}
  	popup.style.visibility = 'hidden';
  	activePopupId = null;
  	killPuIframe(popup);
  }

  function handlePopupOver() {removeListener(inputField, 'blur', hidePopup);
  }

  function handlePopupOut() {
    if (popup.style.visibility == 'visible') {
      addListener(inputField, 'blur', hidePopup);
    }
  }

  function handleClick(e) {
    inputField.value = eventElement(e).innerHTML;
    targetField.value = eventElement(e).getAttribute("id");
    popup.style.visibility = 'hidden';
    activePopupId = null;
    killPuIframe(popup);
    inputField.focus();
    if (ie && !ie7) inputField.select();
    postFunc({"inpId":inputField.id,"inpVal":inputField.value,"tarId":targetField.id,"tarVal":targetField.value});
  }

  function handleOver(e) {
  	inputField.focus();
  	if (ie && !ie7) {
  		var range = inputField.createTextRange();
    	range.collapse(true);
    	range.moveStart("character", 0);
    	range.moveEnd("character", inputField.value.length);
   	 	range.select();
  	}
    items[current].className = '';
    current = eventElement(e).index;
    items[current].className = 'selected';
  }

  function handlerFunc(xmlDoc) {
    var root = xmlDoc.documentElement;
    if (root != null) {
      setProgressStyle();

      var items = root.childNodes;

      // Transform item tags to LI tags
      var ul = xmlDoc.createElement("ul");
      for (var i=0; i<items.length; i++) {
        var li = xmlDoc.createElement("li");
        var liIdAttr = xmlDoc.createAttribute("id");
        var liText = xmlDoc.createTextNode(items[i].firstChild.nodeValue);
        li.setAttribute("id", items[i].getAttribute("value"));
        li.appendChild(liText);
        ul.appendChild(li);
      }

      // Remove item tags
      for (var j=items.length-1; j>=0; j--) {
        root.removeChild(root.childNodes[j]);
      }

      // Add UL tag
      root.appendChild(ul);

      // Set innerHTML for popup
      document.getElementById(popupId).innerHTML = flattenChildren(root.childNodes);

      setSelected();
    }
  }

  function setSelected() {
    current = 0;
    items = popup.getElementsByTagName("li");
    if ((items.length > 1)
       || (items.length == 1
           && items[0].innerHTML != inputField.value)) {
      setPopupStyles();
      for (var i = 0; i < items.length; i++) {
        items[i].index = i;
        addOptionHandlers(items[i]);
      }
      items[0].className = 'selected';
    } else {
      popup.style.visibility = 'hidden';
      activePopupId = null;
      killPuIframe(popup);
    }
    resetProgressStyle();
    return null;
  }

  function setProgressStyle() {
    if (progressStyle != null) {
      addClass(inputField, progressStyle);
    }
  }

  function resetProgressStyle() {
    if (progressStyle != null) {
      removeClass(inputField, progressStyle);
    }
  }
  
  function empty() {
    resetProgressStyle();
    popup.style.visibility = 'hidden';
    activePopupId = null;
    killPuIframe(popup);
  }

  function setPopupStyles() {
	if (!popup.posChecked) {
	 	var offX = 0; var offY = 0;
		function getBookDist(obj) {
	    	if(obj.offsetParent.id!="book") {
				offY += obj.offsetParent.offsetTop;
				offX += obj.offsetParent.offsetLeft;
				getBookDist(obj.offsetParent);
			}
		}
		getBookDist(inputField);
		try{
			if (bookID && bookID==3) {
				offX = offX - 106;
				offY = offY + 14;
			}
		} catch (e) {};
		popup.style.left = offX + "px";
		popup.style.top = (offY + inputField.offsetHeight + 3) + "px";
		popup.posChecked = true;
	}
    var maxHeight = 200;
    
    var resultHeight = popup.getElementsByTagName("ul")[0].offsetHeight;
    if (resultHeight < maxHeight) {
	  popup.style.height = resultHeight + 'px';
      popup.style.overflow = 'hidden';
    } else if (isMoz) {
      popup.style.height = maxHeight + 'px';
      popup.style.overflow = '-moz-scrollbars-vertical';
    } else if (isIE && !ie7 && resultHeight < maxHeight) {
      popup.style.height = resultHeight + 'px';
      popup.style.overflowY = 'auto';
    } else {
      popup.style.height = maxHeight + 'px';
      popup.style.overflowY = 'auto';
    }
    popup.scrollTop = 0;
	if (activePopupId != null && activePopupId != popup.id) {
		$(activePopup).visibility = "hidden";
	}
	activePopupId == popup.id;
	popup.style.visibility = 'visible';
	handlePopupOut(); // trigger the blur handler
    showBgIFrame(popup);
  }

  function addOptionHandlers(option) {
    addListener(option, "click", handleClick);
    addListener(option, "mouseover", handleOver);
  }

  var updater = liveUpdater(constructUri, handlerFunc, null, empty);
  var timeout = false;

  function start(e) {
    if (timeout)
      window.clearTimeout(timeout);
    var key = 0;
    if (e.keyCode) { key = e.keyCode; }
    else if (typeof(e.which)!= 'undefined') { key = e.which; }
    var fieldLength = inputField.value.length;
    //up arrow + shift tab
    if (key == 38 || (e.shiftKey && key == 9)) {
      if (current > 0) {
        items[current].className = '';
        current--;
        items[current].className = 'selected';
        items[current].scrollIntoView(false);
      }
      if (key==9 && popup.style.visibility == 'visible') {
      	if(e.stopPropagation) e.stopPropagation(); /** stop event bubbling */
	    if (isIE) {
	      event.returnValue = false;
	    } else {
	      e.preventDefault();
	    }
		e.cancelBubble = true;
      }
    //down arrow + tab
    } else if (key == 40 || (key == 9 && items.length > 1)) {
      if(current < items.length - 1) {
        items[current].className = '';
        current++;
        items[current].className = 'selected';
        items[current].scrollIntoView(false);
      }
      if (key==9 && popup.style.visibility == 'visible') {
        inputField.focus();
      	if(e.stopPropagation) e.stopPropagation(); /** stop event bubbling */
	    if (isIE) {
	      event.returnValue = false;
	    } else {
	      e.preventDefault();
	    }
		e.cancelBubble = true;
      }
    //enter
    } else if (((key == 13) || (key == 9 && items.length == 1)) && popup.style.visibility == 'visible' ) {
      inputField.value = items[current].innerHTML;
      targetField.value = items[current].getAttribute("id");
      popup.style.visibility = 'hidden';
      activePopupId = null;
      killPuIframe(popup);
      inputField.focus();
      if (isIE) {
        event.returnValue = false;
      } else {
        e.preventDefault();
      }
      postFunc({"inpId":inputField.id,"inpVal":inputField.value,"tarId":targetField.id,"tarVal":targetField.value});

    //escape
    } else if (key == 27) {
      hidePopup();
      if (isIE) {
        event.returnValue = false;
      } else {
        e.preventDefault();
      }
    } else {
      // increment/decrement fieldLength for correct count
      if (key == 8 || key == 46) {
        fieldLength -= 1;
      } else { fieldLength += 1; }

      // Check for empty input field or not enough characters
      if (fieldLength < minimumCharacters) {
        // hide popup and return
        hidePopup();
        killPuIframe(popup)
      } else if (key != 9) {
      // CSI change: avoid unecessary ajax calls
     	if (key == 37 || key == 39 || key == 35 || key == 36) return; // left arrow, right arrow, End
     	if ((key == 8 || key == 46) && fieldLength < minimumCharacters) return; // Backspace, Del
        timeout = window.setTimeout(updater, 300);
      }
    }
  }

  addKeyListener(inputField, start);
  addListener(popup, 'mouseover', handlePopupOver);
  addListener(popup, 'mouseout', handlePopupOut);
}

var bgIframe = null;

if(ie && !ie7 ) window.attachEvent("onload", prepareBGIframe); 

function prepareBGIframe() {
	try {
		if ($("book"))
			bgIframe = new BackgroundIframe($("book"));
	} catch(e) {}
}


function showBgIFrame(popup) {
  if (ie && !ie7 && bgIframe) {
 	with (bgIframe.iframe) {
 		style.zIndex = 9000; //popup.style.zIndex - 1;
		style.width = (popup.offsetWidth + 4) + "px";
		style.height = popup.offsetHeight + "px";
		style.display = "block";
		style.left = (popup.offsetLeft - 2) + "px";
		style.top = (popup.offsetTop -1) + "px";
	}
  }
}

function killPuIframe(popup) {
	if (ie && !ie7 && bgIframe) {
		bgIframe.iframe.style.display = "none";
	}
}
