Oasys = {
	
	// public functions //
	callMethod: function(method, params, pleaseWait, onSuccess, onFailure) {
		var ajaxParams = new Object();
		ajaxParams.method = "post";
		ajaxParams.postBody = Object.toJSON(params);
		ajaxParams.onSuccess = Oasys.onAjaxSuccess;
		ajaxParams.onFailure = Oasys.onAjaxFailure;
		Oasys.clientOnAjaxFailure = onFailure;
		Oasys.clientOnAjaxSuccess = onSuccess;
	
		Oasys.clearErrors();
		Oasys.showMask(pleaseWait);
		
		new Ajax.Request( Oasys.root + "PorteVerte/Proxy.php?method=" + method, ajaxParams );
	},
	
	// private functions //
	
	hasItems: function(array) {
		
		//HACKHERE - how to get number of associtive items?
		for(key in array) {
			if(typeof(array[key]) == "string") {
				return true;
			}
		}
		
		return false;
	},

    getSelected: function(selectField)
    {
		if(selectField.options)
		{
	    	return selectField.options[selectField.selectedIndex].value
	    }
	    else
    	{
    		////This is a <radio> object
    		if(typeof(selectField.length) == "undefined")
    			if(selectField.checked)
	    			return selectField.value
	    		else
	    			return ""
    		else
    			for(var i=0; i < selectField.length; i++)
    			{
    				if(selectField[i].checked)
    					return selectField[i].value
    			}

    		return ""
    	}
    },
	
	onAjaxFailure: function(response) {
		window.setTimeout(Oasys.onAjaxFailure2.bind(Oasys, response), 0);
	},

	onAjaxFailure2: function(response) {
		Oasys.hideMask();
		error = Oasys.strings.ajaxError.replace("@error", response.statusText + "' (" + response.status + ") - " + response.responseText);
		Oasys.showErrors({system: error});

		if(Oasys.clientOnAjaxFailure) {
			Oasys.clientOnAjaxFailure();
		}
	},

	onAjaxSuccess: function(response) {
		window.setTimeout(Oasys.onAjaxSuccess2.bind(Oasys, response), 0);
	},
	
	onAjaxSuccess2: function(response) {
		Oasys.hideMask();

		sResponse = response.responseText;
		
		// expected to be json in all cases:
		sResponse = sResponse.replace(/(\n|\r)/g, "");
		
		try {
			jResponse = sResponse.evalJSON();
		} catch(error) {
			Oasys.showErrors({system: Oasys.strings.ajaxError.replace("@error", "Unexpected response format (JSON) - " + sResponse)});
			if(this.clientOnAjaxFailure) {
				Oasys.clientOnAjaxFailure();
			}
			return;
		}
		
		if(jResponse.ValidationFailures.Failures.length > 0) {
			errors = {};
			for(var i=0; i < jResponse.ValidationFailures.Failures.length; i++) {
				errors[jResponse.ValidationFailures.Failures[i].Key] = jResponse.ValidationFailures.Failures[i].Value;
			}
				
			Oasys.showErrors(errors);
			if(Oasys.clientOnAjaxFailure) {
				Oasys.clientOnAjaxFailure();
			}
			return;
		}
		
		if(Oasys.clientOnAjaxSuccess) {
			Oasys.clientOnAjaxSuccess(jResponse);
		}
	},
	
	/// UI functions. override with your own if needed. //
	
	showMask: function(message)
	{
		Oasys.setInnerText(document.getElementById("ProgressMessage"), message)
	
		//document.body.onresize = Oasys.SetLayerPosition;
		//document.body.onscroll = Oasys.SetLayerPosition;
		Oasys.setLayerPosition();
	
		document.getElementById("masker").style.display = "block"; 
		document.getElementById("progress").style.display = "block"; 
	},
	
	hideMask: function()
	{
		window.onresize = function(){ }
		window.onscroll = function(){ }
	
		var masker = document.getElementById("masker");
		var progress = document.getElementById("progress");
	
		masker.style.display = "none"; 
		progress.style.display = "none";
	},
	
	showMessage: function(message) {
		$("Notification").className = "InfoMessage";
		$("Notification").innerHTML = message;
		$("Notification").style.display = "block";
	},
	
	showErrors: function(errors) {
		errorMessage = [];
		for(field in errors) {
			if(typeof(errors[field]) != "string") {
				continue;
			}
			
			errorMessage.push(errors[field]);
		}
		
		$("Notification").className = "ErrorMessage";
	
		if(errorMessage.length == 1) {
			$("Notification").innerHTML = errorMessage[0];
		} else {
			$("Notification").innerHTML = "<ul><li>" + errorMessage.join("</li><li>") + "</li></ul>";
		}

		$("Notification").style.display = "block";

		///Scroll to the top of the page so they can see the new message:
		elem = document.getElementById("Notification");
		window.scrollTo(elem.scrollLeft, elem.scrollTop);
	},
	
	clearErrors: function() {
		$("Notification").innerHTML = "";
		$("Notification").className = "";
	},
	
	// helper methods used for the UI functions
	
	setInnerText: function(obj, newValue)
	{
		if (document.all) // IE;
			obj.innerText = newValue;
		else if (obj.textContent)
			obj.textContent = newValue;
	},
	
	setLayerPosition: function() 
	{
		///Masker should mask all the screen and scrolled areas:
		
		var shadow = document.getElementById("masker");
	
		if(typeof window.pageYOffset != "undefined")
		{
			///FireFox
			scrollTop = window.pageYOffset
			scrollLeft = window.pageXOffset
			
			///But this INCLUDES the scrollbar sizes, causing scrollbars to change/flicker during the 
			///masking
			scrollFudge = -30
		}
		else
		{
			//IE
			scrollTop = window.scrollTop
			scrollLeft = document.scrollLeft
			scrollFudge = 0
		}
		
		if( typeof( window.pageYOffset ) == 'number' ) {
		//Netscape compliant
		scrollTop = window.pageYOffset;
		scrollLeft = window.pageXOffset;
	  } else {
		//DOM compliant
		scrollTop = document.body.scrollTop;
		scrollLeft = document.body.scrollLeft;
	  }
	
		if( typeof( window.innerWidth ) == 'number' ) {
			//Non-IE
			windowWidth = window.innerWidth;
			windowHeight = window.innerHeight;
		} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
			//IE 6+ in 'standards compliant mode'
			windowWidth = document.documentElement.clientWidth;
			windowHeight = document.documentElement.clientHeight;
		} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
			//IE 4 compatible
			windowWidth = document.body.clientWidth;
			windowHeight = document.body.clientHeight;
		}
	  
		///Masker (shadow) should fill the entire scrollable area:
		shadow.style.width = windowWidth+ scrollFudge + "px";
		shadow.style.height = windowHeight + scrollFudge + "px";
		shadow.style.left = scrollLeft + "px"
		shadow.style.top = scrollTop + "px"
	
		///Progress div should be centered but in the current scrolled window area:
		var progress = document.getElementById("progress");
		progress.style.left = parseInt((windowWidth - 200) / 2) + scrollLeft + "px";
		progress.style.top = parseInt((windowHeight - 100) / 2) + scrollTop + "px";
	},
	
	// must set these in page before using any methods //
	root: "/",
	language: "en"
}

//http://www.netlobo.com/url_query_string_javascript.html

urlDecode = function(encodedString) {
  var output = encodedString;
  var binVal, thisString;
  var myregexp = /(%[^%]{2})/;
  while ((match = myregexp.exec(output)) != null
             && match.length > 1
             && match[1] != '') {
    binVal = parseInt(match[1].substr(1),16);
    thisString = String.fromCharCode(binVal);
    output = output.replace(match[1], thisString);
  }
  return output.replace(/\+/g, " ");
}

function getUrlParam( name )
{
  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
  var regexS = "[\\?&]"+name+"=([^&#]*)";
  var regex = new RegExp( regexS );
  var results = regex.exec( window.location.href );
  if( results == null )
    return "";
  else
    return urlDecode(results[1]);
}

function getUrlParamNames( ) // gpn stands for 'get parameter names'
{
	var params = new Array( );
	var regex = /[\?&]([^=]+)=/g;
	while( ( results = regex.exec( window.location.href ) ) != null )
		params.push( results[1] );
	return params;
}

function getUrlQuery() {
	return window.location.href.match(/(\?.*)?$/)[0];
}

Oasys.strings = {"ajaxError":"An error occured connecting to the booking engine. Please try your query again later or contact us by email or telephone indicating the following error details - @error","Error":"An error occured connecting to the booking engine. Please try your query again later or contact us by email or telephone indicating the following error details - @details"}


setCookie = function(sName, sValue)
{
  document.cookie = sName + "=" + escape(sValue) + "; expires=; ; path=/"
}

getCookie = function(sName)
{
  // cookies are separated by semicolons
  var aCookie = document.cookie.split("; ");
  for (var i=0; i < aCookie.length; i++)
  {
    // a name/value pair (a crumb) is separated by an equal sign
    var aCrumb = aCookie[i].split("=");
    if (sName == aCrumb[0]) 
    {
		if(!aCrumb[1])
		{
			//alert("returning nothing");
			return ""
		}
		else
		{
			//alert("returning: " + unescape(aCrumb[1]))
			return urlDecode(aCrumb[1]);
		}
    }
  }

  // a cookie with the requested name does not exist
  return "";
}

deleteCookie = function( name ) 
{
	d = new Date()
	document.cookie = name + "=blah; expires=" + d.toGMTString() + "; ; path=/";
}

urlDecode = function(encodedString) {
  var output = encodedString;
  var binVal, thisString;
  var myregexp = /(%[^%]{2})/;
  while ((match = myregexp.exec(output)) != null
             && match.length > 1
             && match[1] != '') {
    binVal = parseInt(match[1].substr(1),16);
    thisString = String.fromCharCode(binVal);
    output = output.replace(match[1], thisString);
  }
  return output.replace(/\+/g, " ");
}

//http://www.webtoolkit.info/javascript-sprintf.html
sprintfWrapper = {
 
	init : function () {
 
		if (typeof arguments == "undefined") { return null; }
		if (arguments.length < 1) { return null; }
		if (typeof arguments[0] != "string") { return null; }
		if (typeof RegExp == "undefined") { return null; }
 
		var string = arguments[0];
		var exp = new RegExp(/(%([%]|(\-)?(\+|\x20)?(0)?(\d+)?(\.(\d)?)?([bcdfosxX])))/g);
		var matches = new Array();
		var strings = new Array();
		var convCount = 0;
		var stringPosStart = 0;
		var stringPosEnd = 0;
		var matchPosEnd = 0;
		var newString = '';
		var match = null;
 
		while (match = exp.exec(string)) {
			if (match[9]) { convCount += 1; }
 
			stringPosStart = matchPosEnd;
			stringPosEnd = exp.lastIndex - match[0].length;
			strings[strings.length] = string.substring(stringPosStart, stringPosEnd);
 
			matchPosEnd = exp.lastIndex;
			matches[matches.length] = {
				match: match[0],
				left: match[3] ? true : false,
				sign: match[4] || '',
				pad: match[5] || ' ',
				min: match[6] || 0,
				precision: match[8],
				code: match[9] || '%',
				negative: parseInt(arguments[convCount]) < 0 ? true : false,
				argument: String(arguments[convCount])
			};
		}
		strings[strings.length] = string.substring(matchPosEnd);
 
		if (matches.length == 0) { return string; }
		if ((arguments.length - 1) < convCount) { return null; }
 
		var code = null;
		var match = null;
		var i = null;
 
		for (i=0; i<matches.length; i++) {
 
			if (matches[i].code == '%') { substitution = '%' }
			else if (matches[i].code == 'b') {
				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(2));
				substitution = sprintfWrapper.convert(matches[i], true);
			}
			else if (matches[i].code == 'c') {
				matches[i].argument = String(String.fromCharCode(parseInt(Math.abs(parseInt(matches[i].argument)))));
				substitution = sprintfWrapper.convert(matches[i], true);
			}
			else if (matches[i].code == 'd') {
				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)));
				substitution = sprintfWrapper.convert(matches[i]);
			}
			else if (matches[i].code == 'f') {
				matches[i].argument = String(Math.abs(parseFloat(matches[i].argument)).toFixed(matches[i].precision ? matches[i].precision : 6));
				substitution = sprintfWrapper.convert(matches[i]);
			}
			else if (matches[i].code == 'o') {
				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(8));
				substitution = sprintfWrapper.convert(matches[i]);
			}
			else if (matches[i].code == 's') {
				matches[i].argument = matches[i].argument.substring(0, matches[i].precision ? matches[i].precision : matches[i].argument.length)
				substitution = sprintfWrapper.convert(matches[i], true);
			}
			else if (matches[i].code == 'x') {
				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
				substitution = sprintfWrapper.convert(matches[i]);
			}
			else if (matches[i].code == 'X') {
				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
				substitution = sprintfWrapper.convert(matches[i]).toUpperCase();
			}
			else {
				substitution = matches[i].match;
			}
 
			newString += strings[i];
			newString += substitution;
 
		}
		newString += strings[i];
 
		return newString;
 
	},
 
	convert : function(match, nosign){
		if (nosign) {
			match.sign = '';
		} else {
			match.sign = match.negative ? '-' : match.sign;
		}
		var l = match.min - match.argument.length + 1 - match.sign.length;
		var pad = new Array(l < 0 ? 0 : l).join(match.pad);
		if (!match.left) {
			if (match.pad == "0" || nosign) {
				return match.sign + pad + match.argument;
			} else {
				return pad + match.sign + match.argument;
			}
		} else {
			if (match.pad == "0" || nosign) {
				return match.sign + match.argument + pad.replace(/0/g, ' ');
			} else {
				return match.sign + match.argument + pad;
			}
		}
	}
}
 
sprintf = sprintfWrapper.init;