
function IsError(html)
{
	/// <summary>Determines whether the given string is a JSON object containing error messages. Performs regular expression match</summary>
	/// <param name="html" type="string">The potential json object in string form</param>

	// Test for Json array using regex
	var match = /^\[\{.*\}\]$/.test(html)
	return match;
}

function IsJsonError(json)
{
	/// <summary>Determines whether the given json object is an array of error messages</summary>
	/// <param name="json" type="object">The potential array of error messages</param>

	//we expect a collection of error messages, so the root object will be an array
	if (json != undefined && json.length > 0 && json[0].ErrorMessage != undefined)
	{
		return true;
	}
	
	return false;
}

function ShowError(errorsJson, customAction)
{
	/// <summary>
	/// Shows specified error in a message box by default, or pass optional customAction(errors) delegate.
	/// Handles a json object in string form
	/// </summary>
	/// <param name="errorsJson" type="string">A JSON object in string form</param>
	/// <param name="customAction" type="function" optional="true">A custom action to perform on the error collection</param>
	
	var errors = eval(errorsJson);

	ShowJsonError(errors, customAction);
}

function ShowJsonError(errors, customAction)
{
	/// <summary>
	/// Shows specified error in a message box by default, or pass optional customAction(errors) delegate.
	/// Handles a json object which is expected to be an array of error messages
	/// </summary>
	/// <param name="errors" type="object">A JSON object - collection of error messages</param>
	/// <param name="customAction" type="function" optional="true">A custom action to perform on the error collection</param>
	
	if (customAction === undefined)
	{
		// Default action: show in message box
		var msg = "";
		for (var i = 0; i < errors.length; i++)
		{
			if (i > 0) msg += "\n";
			msg += errors[i].ErrorMessage;
		}
		alert(msg);
	}
	else
	{
		// Custom action specified
		customAction(errors);
	}
}

function RemoveBad(strTemp) {
    if (strTemp != null)
        strTemp = strTemp.replace(/\<|\>|\"|\'|\%|\;|\(|\)|\&|\+|\-/g, "");
    return strTemp;
} 

/// <reference path="jquery.vsdoc.1.2.6.js" />

function WebTracker()
{
	/// <summary>
	/// Class for tracking website events. Currently uses Web Trends for tracking.
	/// Allows for adding meta tags and doing inline dynamic tracking for button clicks and the like.
	/// Note: depends on WebTrends.8.0d.js
	/// </summary>
}

WebTracker.AddMetaTag = function(name, value)
{
	/// <summary>Adds a new meta tag with the given name and value to the page</summary>
	/// <param name="name" type="string">The name of the meta tag</param>
	/// <param name="value" type="string">The value of the meta tag</param>
	
	$("head").append('<meta name="' + name + '" content="' + value + '" />');
}

WebTracker.AppendToMetaTag = function(name, value)
{
	/// <summary>Adds or appends the given value to a meta tag with the given name</summary>
	/// <param name="name" type="string">The name of the meta tag</param>
	/// <param name="value" type="string">The value of the meta tag</param>

	var content = "";

	if ($("meta[name='" + name + "']").length)
	{
		content = $("meta[name='" + name + "']").attr("content") + ";" + value;
		$("meta[name='" + name + "']").remove();
	}
	else
	{
		content = value;
	}

	WebTracker.AddMetaTag(name, content);
}

WebTracker.TrackEvent = function(eventUrl, eventName, stepNumber, pathName)
{
	/// <summary>
	/// Static method. Tracks a particular website event - used for dynamic actions like button clicks, not page loads.
	/// Will do nothing if webtrends tracking is disabled.
	/// </summary>
	/// <param name="eventUrl" type="string">The URL to log against the action - does not need to be a real URL</param>
	/// <param name="eventName" type="string">The descriptive name of the action</param>
	/// <param name="stepNumber" type="number" integer="true" optional="true">The web trends step number. If present, also include pathName</param>
	/// <param name="pathName" type="string" optional="true">The name of the web trends path/funnel/journey/whatever we are on. Eg Booking Funnel 2009</param>

	// ensure that the webtrends js file has been loaded - if webtrends tagging is disabled then the js file will not load
	if (typeof (dcsMultiTrack) === "function")
	{
		if (stepNumber != undefined)
		{
			dcsMultiTrack('DCS.dcsuri', '/' + lang + '/' + eventUrl, 'WT.ti', eventName, 'WT.si_n', pathName, 'WT.si_x', stepNumber);
		}
		else
		{
			dcsMultiTrack('DCS.dcsuri', '/' + lang + '/' + eventUrl, 'WT.ti', eventName);
		}
	}
}

WebTracker.TrackTaggedLink = function(tag)
{
	if (typeof (dcsMultiTrack) === "function")
	{
	    dcsMultiTrack('DCS.dcsuri', '/redirect.asp?t=' + tag + '&l=' + lang, 'DCS.dcsqry', '?t=' + tag + '&l=' + lang, 'WT.ti', 'Redirecting to target page', 'DCSext.site_version', '2', 'DCSext.display_language', lang, 'DCSext.partnerlink', tag);
    }
}

function AjaxDataBuilder(includeBasketState) {

    this.names = new Array();
    this.values = new Array();

    ///
    /// Guards a method by throwing an exception if a parameter is null when it should not be passed
    /// in null.
    ///
    this.Guard = function(parameterName, value)
    {
    	if (value == undefined || value == null)
    	{
    		throw ("parameter " + parameterName + " can not be null");
    	}
    }


    this.Add = function(name, value) {
        /// <summary>
        /// Adds data to the builder
        /// </summary>
        /// <param name="name">The name of the posted field.</param>
        /// <param name="value">The value of the posted field.</param>

        this.Guard("name", name);
        this.Guard("value", value);

        this.names.push(name);
        this.values.push(value);

        return this;
    }

    this.Build = function() {
        /// <summary>
        /// Builds the data string for post or get
        /// </summary>

        //  jquery causes a 411 in firefox if you do not set post data to something so we
        //  must default the post data to a blank array.
        var data = "{}";

        // Basket state should be added by default
        if (includeBasketState || includeBasketState == undefined) {
            // Add the basket state by default
            this.names.push("__BasketState");
            this.values.push($('#__BasketState').val());
        }

        var index = 0;
        var count = this.names.length;

        for (index = 0; index < count; index++) {

            var name = this.names[index];
            var value = escape(this.values[index]);

            var assignment = name + "=" + value;

            if (index == 0) {
                data = assignment;
            }
            else {
                data = data + "&" + assignment;
            }
        }


        return data;

    }

    return this;

}





/* Queue.js - a function for creating an efficient queue in JavaScript
*
* The author of this program, Safalra (Stephen Morley), irrevocably releases
* all rights to this program, with the intention of it becoming part of the
* public domain. Because this program is released into the public domain, it
* comes with no warranty either expressed or implied, to the extent permitted
* by law.
*
* For more public domain JavaScript code by the same author, visit:
*
* http://www.safalra.com/web-design/javascript/
*/


/* Creates a new Queue. A Queue is a first-in-first-out (FIFO) data structure.
* Functions of the Queue object allow elements to be enqueued and dequeued, the
* first element to be obtained without dequeuing, and for the current size of
* the Queue and empty/non-empty status to be obtained.
*/
function Queue() {

    // the list of elements, initialised to the empty array
    var queue = [];

    // the amount of space at the front of the queue, initialised to zero
    var queueSpace = 0;

    /* Returns the size of this Queue. The size of a Queue is equal to the number
    * of elements that have been enqueued minus the number of elements that have
    * been dequeued.
    */
    this.getSize = function() {

        // return the number of elements in the queue
        return queue.length - queueSpace;

    }

    /* Returns true if this Queue is empty, and false otherwise. A Queue is empty
    * if the number of elements that have been enqueued equals the number of
    * elements that have been dequeued.
    */
    this.isEmpty = function() {

        // return true if the queue is empty, and false otherwise
        return (queue.length == 0);

    }

    /* Enqueues the specified element in this Queue. The parameter is:
    *
    * element - the element to enqueue
    */
    this.enqueue = function(element) {
        queue.push(element);
    }

    /* Dequeues an element from this Queue. The oldest element in this Queue is
    * removed and returned. If this Queue is empty then undefined is returned.
    */
    this.dequeue = function() {

        // initialise the element to return to be undefined
        var element = undefined;

        // check whether the queue is empty
        if (queue.length) {

            // fetch the oldest element in the queue
            element = queue[queueSpace];

            // update the amount of space and check whether a shift should occur
            if (++queueSpace * 2 >= queue.length) {

                // set the queue equal to the non-empty portion of the queue
                queue = queue.slice(queueSpace);

                // reset the amount of space at the front of the queue
                queueSpace = 0;

            }

        }

        // return the removed element
        return element;

    }

    /* Returns the oldest element in this Queue. If this Queue is empty then
    * undefined is returned. This function returns the same value as the dequeue
    * function, but does not remove the returned element from this Queue.
    */
    this.getOldestElement = function() {

        // initialise the element to return to be undefined
        var element = undefined;

        // if the queue is not element then fetch the oldest element in the queue
        if (queue.length) element = queue[queueSpace];

        // return the oldest element
        return element;

    }

}

///
/// Encapsulates an AJAX request in a command that has the ability to retry on failure
///
function AjaxPostCommand(url, dataBuilder, successCallback, errorCallback, timeoutInMilliseconds, retries, dataType) {
	/// <summary>Encapsulates an AJAX request in a command that has the ability to retry on failure</summary>
	/// <field name="dataType" type="string" optional="true">The data type we expect back from the request. See JQuery AJAX documentation</field>

    var dataBuilder = dataBuilder;
    var postData = {};
    var url = url;

    if (retries == undefined) {
        retries = 3;
    }

    if (timeoutInMilliseconds == undefined) {
    	timeoutInMilliseconds = AjaxPostCommand.DefaultTimeout;
    }
          
    var type = "POST";
        
    // Records the number of execution attempts
    var attemptCount = 0;

    // Records if the command is executing
    var executing = false;
    
    // Executes the ajax call and sets the attempt count
    function executeAjax () {
        attemptCount = attemptCount + 1;
        $.ajax(
                {
                    url: url,
                    cache: false,
                    data: postData,
                    type: type,
                    timeout: timeoutInMilliseconds,
                    success: successHandler,
                    error: errorHandler,
                    dataType: dataType
                }
            )
    }

    // Invokes the success callback
    function successHandler(data)
    {
    	// Only invoke the callback if its defined
    	if (successCallback != undefined)
    	{
    		try
    		{
    			successCallback(data);
    		}
    		catch (e)
    		{
    			if (typeof(console) != "undefined")
    			{
    				console.log('Error in AJAX success callback: ' + e);
    			}
    			// Do nothing because the callback should have handled the error
    		}

    	}

    	executing = false;
    }

    // Handles any errors and invokes the error callback when the number of retries have been exceeded
    function errorHandler(XMLHttpRequest, textStatus, errorThrown) {

        if (attemptCount < retries) {
            // Try again
            executeAjax()
        }
        else {
        
            // Only invoke the callback if its defined
            if (errorCallback != undefined) {

                try {

                    errorCallback(XMLHttpRequest, textStatus, errorThrown);
                    
                }
                catch (e) {
                    // Do nothing because the callback should have handled the error
                }

            }

            executing = false;
            
        }
    }

    ///
    /// Executes the command
    ///
    this.Execute = function()
    {
    	// Build the post data using the builder
    	postData = dataBuilder.Build();

    	// let it be know that we are executing
    	executing = true;

    	// Execute the ajax call
    	executeAjax();
    }

    ///
    /// Determines if the command has finished executing
    //
    this.HasExecutionCompleted = function() {
        return !executing;
    }

    return this;
        
}

/// Static fields

AjaxPostCommand.DefaultTimeout = 30000;
/// <reference path="../Content/Scripts/jquery.vsdoc.js" />

function AjaxGetCommand(url, dataBuilder, successCallback, errorCallback, timeoutInMilliseconds)
{
	/// <summary>Encapsulates an AJAX GET request in a command</summary>
	/// <param name="url" type="string">The URL to request</param>
    /// <param name="dataBuilder" type="string">Builds the querystring parameters to send with the request</param>
	/// <param name="successCallback" type="function">The callback function to execute on a successful response</param>
	/// <param name="errorCallback" type="function">The callback function to execute if an error occurs</param>
	/// <param name="timeoutInMilliseconds" type="Number" integer="true">The timeout to place on the request, in milliseconds</param>

    var dataBuilder = dataBuilder;
    var requestData = {};
	var url = url;

	if (timeoutInMilliseconds == undefined)
	{
		timeoutInMilliseconds = AjaxGetCommand.DefaultTimeout;
	}

	var type = "GET";

	// Records if the command is executing
	var executing = false;

	function executeAjax()
	{
		/// <summary>Executes the ajax call</summary>
		
		$.ajax(
                {
                	url: url,
                	cache: false,
                	data: requestData,
                	type: type,
                	timeout: timeoutInMilliseconds,
                	success: successHandler,
                	error: errorHandler
                }
            );
	}

	function successHandler(data)
	{
		/// <summary>Invokes the success callback</summary>

		// Only invoke the callback if its defined
		if (successCallback != undefined)
		{
			try
			{
				successCallback(data);
			}
			catch (e)
			{
				// Do nothing because the callback should have handled the error
			}


        }

        executing = false;

	}

	function errorHandler(XMLHttpRequest, textStatus, errorThrown)
	{
		/// <summary>Handles any errors and invokes the error callback</summary>
		
		// Only invoke the callback if its defined
		if (errorCallback != undefined)
		{
			try
			{
				errorCallback(XMLHttpRequest, textStatus, errorThrown);
			}
			catch (e)
			{
				// Do nothing because the callback should have handled the error
			}

        }

        executing = false;
		
	}

	this.Execute = function() {
	    /// <summary>Executes the command</summary>

	    // Build the request data using the builder
	    requestData = dataBuilder.Build();

	    // let it be know that we are executing
	    executing = true;

	    // Execute the ajax call
	    executeAjax();
    	
	}


	///
	/// Determines if the command has finished executing
	//
	this.HasExecutionCompleted = function() {
	    return !executing;
	}
	

	return this;

}

/// Static fields

AjaxGetCommand.DefaultTimeout = 30000;
/// <reference path="Queue.js" />

///
/// Throttles command execution by executing each command sequentialy off a queue (FIFO)
/// this class is implemented as singleton and can be used like this - 
/// CommandInvoker.getInstance().QueueCommand(myCommand)
///
var CommandInvoker = (function() {

    var instance = null;

    function PrivateConstructor() {

        //----------------------------------------------------------
        // Private fields
        //----------------------------------------------------------

        var throttlePeriod = 250; // Is in milliseconds
        var queue = new Queue()
        var initialized = false;
        var currentCommand = undefined;

        //----------------------------------------------------------
        // Private functions
        //----------------------------------------------------------

        //
        // Checks if the invoker is busy executing a command
        //
        function IsExecutingCommand() {

            if (currentCommand == undefined) {
                return false;
            }
            else {
                
                // We must still be executing if the command has not completed execution
                return !currentCommand.HasExecutionCompleted()
            }

        }

        ///
        /// Recursively retrieves commands off a queue and executes them. The commands are throttled by
        /// a timeout
        ///
        function executeCommands() {


            if (!IsExecutingCommand()) {

                //console.log("Get command off queue");

                // Get the next command from the queue
                currentCommand = queue.dequeue();

                // check if we got a command off the queue
                if (currentCommand != undefined) {
                    currentCommand.Execute();
                }

            }



            // Stop execution for a while so that the UI can queue some commands
            setTimeout(executeCommands, throttlePeriod);
        }

        //----------------------------------------------------------
        // Public functions
        //----------------------------------------------------------

        ///
        /// Adds a command to the internal queue
        ///
        this.QueueCommand = function(command) {

            // add the command to the internal queue
            queue.enqueue(command);

            // Initialize the invoker if not already initialized by executing the commands
            if (!initialized) {
                initialized = true;
                executeCommands();
            }

        }

    }

    ///
    /// Returns the singleton instance
    ///
    return new function() {
        this.getInstance = function() {
            if (instance == null) {
                instance = new PrivateConstructor();
                instance.constructor = null;
            }
            return instance;
        }
    }
})();

/// <reference path="../../scripts/jquery.vsdoc.1.2.6.js" />
/// <reference path="../../Scripts/AjaxDataBuilder.js" />
/// <reference path="../../Scripts/CommandInvoker.js" />
/// <reference path="../../Scripts/AjaxGetCommand.js" />

var ShowTimetableUrl;
var monthChangeLink;
var vMonth, vYear, vFrom, vTo;
var selectedCheapestFlight;

$(document).ready(function(){InitHandlers()});


function InitHandlers() {   
   
    $(".tabBody").hover(
        function() { $(this).css('cursor', 'pointer'); },
        function() { $(this).css('cursor', ''); }
     );

    $("#NextMonth").unbind("click").click(
    function() {
    ShowMonth(1);
    return false;
    }).hover(
    function() 
    { $(this).css('cursor', 'pointer'); }, function() { $(this).css('cursor', ''); });



    $("a.cheapestOutboundFlightPrice").unbind("click").click(
    function() {
        selectedCheapestFlight = $(this);
        ShowSpecificMonth();
    });

    EnablePreviousMonth();

    $("td.available").unbind("click").click(function() {       
        var idSplit = $(this).children("a").attr("id").split("|")
        SetCalendarDates(idSplit[0], idSplit[1]);
        ShowTimesPopup($(this));
        return false;
    });

    $("td.available").unbind("hover").hover(function() { }, function() { HideTimesPopup($(this)); });

}



function ShowTimesPopup(sender) {
    $(".timetablePopup").hide();
    $("td.available").removeClass("selected");
    sender.addClass("selected");

    var pos = sender.offset();
    var wrapperPos = $("#pageWrap").offset();

    var timesDiv = sender.children(".timetablePopup");

    var senderWidth = sender.outerWidth();
    var senderHeight = sender.outerHeight();
    var timesDivWidth = timesDiv.outerWidth();

    var left = (pos.left - wrapperPos.left - 20) + "px";
    var top = (pos.top - wrapperPos.top + senderHeight - 5) + "px";

    timesDiv.css({
        position: 'absolute',
        zIndex: 5000,
        left: left,
        top: top
    });
    timesDiv.show();
}

function HideTimesPopup(sender) {
    sender.children(".timetablePopup").hide();
}


function EnablePreviousMonth() {

    $("#PrevMonth").unbind("click").show().click(
         function() {
            ShowMonth(-1);
            return false;
         }).hover(
         function() { $(this).css('cursor', 'pointer'); },
         function() {
             $(this).css('cursor', '');
         });
         
}
function SetCalendarDates(day, monyear){
    // get day month for out bound from pod.
    $("#oMonYear").val(monyear);
    $("#oDay").val(day);
}

function BuildStandardRequestData(month, year, from, to)
{
	var requestDataBuilder = new AjaxDataBuilder(false);
	requestDataBuilder.Add("month", month);
	requestDataBuilder.Add("year", year);
	requestDataBuilder.Add("fromCode", from);
	requestDataBuilder.Add("toCode", to);

	return requestDataBuilder;
}

function ShowMonth(increment) {
    ShowUpdatingCalendar();
    var url = monthChangeLink.replace("ShowNothing", "ShowMonthIncrement")

    var builder = BuildStandardRequestData(vMonth, vYear, vFrom, vTo);
    builder.Add("increment", increment);

    DoTimetableRefresh(url, builder);
}

function ShowSpecificMonth() {

    var month, year;
    year = selectedCheapestFlight.children("#flightDate").val().split("-")[0];   
    month = selectedCheapestFlight.children("#flightDate").val().split("-")[1];
    var url = monthChangeLink.replace("ShowNothing", "ShowMonthSpecific")

    var builder = BuildStandardRequestData(month, year, vFrom, vTo);
    
    DoTimetableRefresh(url, builder);
    vMonth = month;
    vYear = year;

}

function DoTimetableRefresh(url, requestDataBuilder)
{
	var successCallback = function(html)
	{
		if (IsError(html))
		{
			ShowError(html, function(errors)
			{
				alert("is error " + html);
			});
		}
		else
		{
			updatePanel(html, "TimetableContainer");
		}
	};

	var errorCallback = function(XMLHttpRequest, textStatus, errorThrown)
	{
		alert("Error viewing timetable");
		//alert(XMLHttpRequest.responseText);
	};

	var command = new AjaxGetCommand(url, requestDataBuilder, successCallback, errorCallback, AjaxPostCommand.DefaultTimeout);

	CommandInvoker.getInstance().QueueCommand(command);
}



function updatePanel(html, panelName) {
    $("#" + panelName).html(html);
    InitHandlers();
}





function HandleAjaxError(XMLHttpRequest, textStatus, errorThrown) {
    alert("Error in Publishing Timetable");
    //alert(XMLHttpRequest.responseText);
}

function ShowUpdatingCalendar() {
   
    var html = '<div class="fareUpdate"><div class="content"><p>';
    html += '<img src="' + AjaxLoadingImageUrl + '" alt="loading" width="24" height="24" /></p>';
    html += '<p>' + updatingFlightsMessage + '&#8230;</p></div></div>';
    html += '<div class="tab-content-foot"></div>'

    $(".publishing-tab-content").html(html);
}


/// <reference path="Calendar.js" />
/// <reference path="../../scripts/jquery.vsdoc.1.2.6.js" />
/// <reference path="../../Scripts/Date.1.0.js" />

var isFromPreviousSearch = false;
//var previousSearchTripLength = 0;
var isOneWay;

function CheckUrls() {
    if (typeof GetLinkedAirportsUrl == 'undefined')
        alert("GetLinkedAirportsUrl is not specified");

    if (typeof SearchForFlightsUrl == 'undefined')
        alert("SearchForFlightsUrl is not specified");
}

function SearchPodOnLoad() {
    CheckUrls();

    $("#originAirport").unbind("change").change(function() {
        var url = GetLinkedAirportsUrl.replace('P_FROM', $(this).val());
        $.getJSON(url, $("#originAirport").value,
        function(jsonResponse) {
            updateDestinationAirports(jsonResponse);
        });
    });

    addOneWayEntryToReturnDate();

    $("#oDate").attachDatePicker('#oDay', '#oMonYear', LatestMonthEndDate, selectionChangedHandler);
    attachSelectorEvents("#oDay", "#oMonYear", selectionChangedHandler);

    $("#rDate").attachDatePicker('#rDay', '#rMonYear', LatestMonthEndDate, selectionChangedHandler);
    attachSelectorEvents("#rDay", "#rMonYear", selectionChangedHandler);

    $("#searchPodSubmitButton").unbind("click").click(function() {
        if (searchParamsAreValid()) {
            if (handleSameDayItinerary() &&  handleDepartTodayDisclaimer()) {
                if (handleChildDisclaimer() && handleInfantDisclaimer()) {
                    submitSearch();
                }
            }
        }
    });
 

    $("#btnManageBookingLogin").unbind("click").click(function() {
        submitLogin();
    }
        );

    $("#btn_Login").unbind("click").click(function() {
        submitCheckin();
    }
        );

    $(".textInput").unbind("focus").focus(function() {
        if (this.value == this.defaultValue) {
            this.value = '';
            }
    }
    );

    $("#strPassword").unbind("focus").focus(function() {
        changeInputToPasswordType(this);
    }
    );
}

function updateDestinationAirports(jsonObj) {
    var select = $("select#destinationAirport")[0];
    select.options.length = 0;
    for (var i=0; i<jsonObj.length; i++) {
        var option = document.createElement('option');
        option.value = jsonObj[i].Code;
        option.text = jsonObj[i].NameWithCode;
        select.options.add(option);
    }
}

function selectionChangedHandler() {
    constrainDateRange("#oDay", "#oMonYear", "#rDay", "#rMonYear");
}

function addOneWayEntryToReturnDate() {

    var SelDay = "00";
    var SelMonYear = "00";

    if (isFromPreviousSearch == true && isOneWay == false) { //previousSearchTripLength != -1) {
        SelDay = $("#rDay option[selected]").val();
        SelMonYear = $("#rMonYear option[selected]").val();
    }
    
    $("#rDay option[selected]").removeAttr("selected");
    var list = $('#rDay').html();
    $('#rDay').empty().html('<option value="00">' + DayNotSelected + '</option>' + list);
    $("#rDay option[value='" + SelDay + "']").attr("selected", "selected");
    
    $("#rMonYear option[selected]").removeAttr("selected");
    var list = $('#rMonYear').html();
    $('#rMonYear').empty().html('<option value="00">' + MonthYearNotSelected + '</option>' + list);
    $("#rMonYear option[value='" + SelMonYear + "']").attr("selected", "selected");

}

function searchParamsAreValid() {
    if ($("#originAirport").val() == '') {
        alert(NoOriginErrorMessage);
        return false;
    }

    if ($("#destinationAirport").val() == '') {
        alert(NoDestinationErrorMessage);
        return false;
    }

    var valid = true;

    if(($("#rDay").val() != '00' && $("#rMonYear").val() == '00') ||
       ($("#rMonYear").val() != '00' && $("#rDay").val() == '00')) {
        alert(IncompleteReturnDateErrorMessage);
        return false;
    }

    var numberOfAdults = parseInt($("#numberOfAdults").val());
    var numberOfFullFareTravelers = numberOfAdults + parseInt($("#numberOfChildren").val());
    if(numberOfFullFareTravelers == 0) {
        alert(ZeroTravelersErrorMessage);
        valid = false;
    }

    if (numberOfFullFareTravelers > 40) {
        alert(MaximumNumberOfTravelersErrorMessage);
        valid = false;
    }
    
    var numberOfInfants = parseInt($("#numberOfInfants").val());
    if(numberOfAdults < numberOfInfants) {
        alert(MoreInfantsThanAdultsErrorMessage);
        valid = false;
    }

    var outboundDateString = getDateString($("#oDay"), $("#oMonYear"));
    var outboundDate = new Date(outboundDateString);
    var today = getToday();
    if (outboundDate < today) {
        var day = dayValue.toString();
        var monthYear = monthValue.toString() + "" + yearValue.toString();
        $("#oDay").val(day);
        $("#oMonYear").val(monthYear);
        alert(OutboundDateBeforeTodayErrorMessage);
        valid = false;
    } 

    return valid;
}

function handleSameDayItinerary() {
    var cont = true;
    
    if ($("#oDay").val() + $("#oMonYear").val() == $("#rDay").val() + $("#rMonYear").val()) {
        cont = confirm(SameDayItineraryWarningMessage);
    }

    return cont;
}


function handleDepartTodayDisclaimer() {
    var cont = true;

    var dateString = getDateString($("#oDay"), $("#oMonYear"));
    var departureDate = new Date(dateString);

    if (departureDate.toDateString() == getToday().toDateString())
        cont = confirm(DepartTodayDisclaimer);

    return cont;
}

function getDateString(day, monthYear) {
    var monthYearString = monthYear.val();
    var to = monthYearString.length;
    var from = to - 4;
    var dayString = day.val();
    var monthString = monthYearString.substring(0, 2);
    var yearString = monthYearString.substring(from, to);
    return yearString + "/" + monthString + "/" + dayString;
}

function getToday() {
    return new Date(yearValue, monthValue, dayValue);
}

function handleChildDisclaimer() {
    var cont = true;

    var numberOfAdults = parseInt($("#numberOfAdults").val());
    var numberOfChildren = parseInt($("#numberOfChildren").val());
    if (numberOfAdults == 0 && numberOfChildren > 0)
        cont = confirm(ChildDisclaimer);

    return cont;
}

function handleInfantDisclaimer() {
    var cont = true;
    
    var numberOfInfants = parseInt($("#numberOfInfants").val());
    if (numberOfInfants > 0)
        cont = confirm(InfantDisclaimer);

    return cont;
}

function submitSearch() {
    var params = "?origAirportCode=" + $("#originAirport").val()
        + "&destAirportCode=" + $("#destinationAirport").val()
        + "&departureDay=" + $("#oDay").val()
        + "&departureMonthYear=" + $("#oMonYear").val()
        + "&returnDay=" + $("#rDay").val()
        + "&returnMonthYear=" + $("#rMonYear").val()
        + "&numberOfAdults=" + $("#numberOfAdults").val()
        + "&numberOfChildren=" + $("#numberOfChildren").val()
        + "&numberOfInfants=" + $("#numberOfInfants").val()
        + "&flexibleOnDates=" + $('#flexibleOnDates').attr('checked')
        +"&email=" + '';

    SearchForFlightsUrl = SearchForFlightsUrl + "/SearchForFlights" + params;

    window.location = SearchForFlightsUrl;
}

function submitLogin() {
    if (ej1SignIn()) {
        document.signin.submit();
    }
}

function submitCheckin() {
    if (ej1CheckInLogin()) {
        document.onlinecheckin.submit();
    }
}

// copied from ej1 for quick implementation 
function ej1CheckInLogin(){
 var frmLogin =  document.onlinecheckin;
 var intErrs = 0;
 var strErrMSG = '';

 var strSurname = frmLogin.strSurname.value;

 while (strSurname.indexOf(' ') != -1){
 strSurname = strSurname.replace(' ','');
 }
 if (strSurname == ''){
 intErrs++;
 strErrMSG += '\n- ' + checkInPassengersLastNameErrorMessage;
 }

 var strBookingReference = frmLogin.strBookingReference.value;

 while (strBookingReference.indexOf(' ') != -1){
 strBookingReference = strBookingReference.replace(' ','');
 }

 if(strBookingReference == ''){
 intErrs++;
 strErrMSG += '\n- ' + checkInBookingReferenceErrorMessage;
 }

 if (intErrs) {
 strErrMSG = clientSideValidationErrorMessage + strErrMSG;
 }

 if (!frmLogin.chkAuthorised.checked) {
 intErrs++;
 strErrMSG += (strErrMSG == '' ? '' : '\n\n');
 strErrMSG += checkInAuthorisationErrorMessage;
 }

 if (intErrs){
 alert(strErrMSG);
 return false;
 } else {
 return true;
 }
}

// copied from ej1 for quick implementation 
function ej1SignIn() {
    var intErrs = 0;
    var strErrMSG = clientSideValidationErrorMessage;
    var emailVal = document.forms["signin"].strEmail.value;
    if ((emailVal.length < 5) || (emailVal.indexOf('@') < 0)) {
        intErrs++;
        strErrMSG += '\n- ' + invalidEmailErrorMessage;
    }

    var strPWord = document.forms["signin"].strPassword.value;
    while (strPWord.indexOf(' ') != -1) {
        strPWord = strPWord.replace(' ', '');
    }

    if (strPWord == '') {
        intErrs++;
        strErrMSG += '\n- ' + invalidPasswordErrorMessage;
    }

    if (intErrs) {
        alert(strErrMSG);
        return false;
    } else {
        return true;
    }
}

function changeInputToPasswordType(inputElm) {
    var iType = 'password';

    if (!inputElm || !inputElm.parentNode || inputElm.type == 'password')
        return;

    var isMSIE = /*@cc_on!@*/false;

    if (!isMSIE) {
        var newElm = document.createElement('input');
        newElm.type = iType;
    }
    else {
        var newElm = document.createElement('span');
        newElm.innerHTML = '<input type="' + iType + '" name="' + inputElm.name + '">';
        newElm = newElm.firstChild;
    }

    //replicate existing element's properties
    var props = ['name', 'id', 'className', 'size', 'tabIndex', 'accessKey'];
    for (var i = 0, l = props.length; i < l; i++) {
        if (inputElm[props[i]]) newElm[props[i]] = inputElm[props[i]];
    }

    //replace control with new passowrd input
    inputElm.parentNode.replaceChild(newElm, inputElm);

    //give the control focus
    window.tempElm = newElm;
    setTimeout("tempElm.hasFocus=true;tempElm.focus();", 1);
}

function DeletePreviousSearch(searchID) {
    var url = DeleteSearchFromCookieUrl.replace('P_SEARCH_ID', searchID);
    $.getJSON(url, searchID,
        function(jsonResponse) {
            if ((jsonResponse) == true) {
                $("#PreviousSearchLine_" + searchID).hide();
            }
            else { alert("error: failed to delete search"); }
        });
    }

function SetSearchPodFromPreviousSearch(searchID, oneway) {

    var builder = new AjaxDataBuilder(false);
    var url = PopulateSearchFromPreviousUrl.replace('P_SEARCH_ID', searchID);
    var successCallback = function(html) {
        isFromPreviousSearch = true;
        //        if (oneway == "true") {
        //            isOneWay = true;
        //        } else {
        //            isOneWay = false;
        //        }
        isOneWay = oneway;
        $("#SearchPodShell").html(html);
    };

    var errorCallback = function(XMLHttpRequest, textStatus, errorThrown) {
        //alert("Error updating Search pod");
        alert(XMLHttpRequest.responseText); 
    };

    var command = new AjaxPostCommand(url, builder, successCallback, errorCallback);
    CommandInvoker.getInstance().QueueCommand(command);


}

function expandSearches(theDiv) {

    $("#" + theDiv).slideToggle("slow", function() {
        if ($("#" + theDiv).is(":visible")) {
            $("#" + theDiv).css("display", "block");
        }
        else {
            $("#" + theDiv).css("display", "none");
        }
        return false;
    });
}

/// <reference path="../../jquery.vsdoc.1.2.6.js" />

/*fullfat header*/

var OffMenuIdFullFat = "#HeaderRibbonMenuSectionInnerOff_";
var OnMenuIdFullFat = "#HeaderRibbonMenuSectionInnerOn_";
var MenuSectionContainer = "#HeaderMenu_";

function InitialiseFullFatMenu(){
    $(MenuSectionContainer + 1).unbind("hover").hover(function() { OpenFullFatMenu(1); }, function() { CloseFullFatMenu(1); });
    $(MenuSectionContainer + 2).unbind("hover").hover(function() { OpenFullFatMenu(2); }, function() { CloseFullFatMenu(2); });
    $(MenuSectionContainer + 3).unbind("hover").hover(function() { OpenFullFatMenu(3); }, function() { CloseFullFatMenu(3); });
    $(MenuSectionContainer + 4).unbind("hover").hover(function() { OpenFullFatMenu(4); }, function() { CloseFullFatMenu(4); });
    $(MenuSectionContainer + 5).unbind("hover").hover(function() { OpenFullFatMenu(5); }, function() { CloseFullFatMenu(5); });
}

function OpenFullFatMenu(menuid) {
    $(OffMenuIdFullFat + menuid).hide();
    $(OnMenuIdFullFat + menuid).show();
    SetElementHeight($(OnMenuIdFullFat + menuid).children(".menuSectionMiddle"));
    return false;
}

function CloseFullFatMenu(menuid) {
    $(OnMenuIdFullFat + menuid).hide();
    $(OffMenuIdFullFat + menuid).show();
    return false;
}

/*semi skimmed header*/

var OffMenuIdSkimmed = "HeaderRibbonMenuSectionInnerOff_";
var OnMenuIdSkimmed = "HeaderRibbonMenuSectionInnerOn_";

function InitialiseSemiSkimmedHeader() {

    $("#HeaderRibbonMenuSectionInnerOff_1").hover(function() { HighlightMenu(1) }, function() { UnHighlightMenu(1) });
    $("#HeaderRibbonMenuSectionInnerOff_2").hover(function() { HighlightMenu(2) }, function() { UnHighlightMenu(2) });
    $("#HeaderRibbonMenuSectionInnerOff_3").hover(function() { HighlightMenu(3) }, function() { UnHighlightMenu(3) });
    $("#HeaderRibbonMenuSectionInnerOff_4").hover(function() { HighlightMenu(4) }, function() { UnHighlightMenu(4) });
    $("#HeaderRibbonMenuSectionInnerOff_5").hover(function() { HighlightMenu(5) }, function() { UnHighlightMenu(5) });

    $("#HeaderRibbonMenuSectionInnerOff_1").unbind("click").bind("click", function() { OpenSkimmedMenu(1) });
    $("#HeaderRibbonMenuSectionInnerOff_2").unbind("click").bind("click", function() { OpenSkimmedMenu(2) });
    $("#HeaderRibbonMenuSectionInnerOff_3").unbind("click").bind("click", function() { OpenSkimmedMenu(3) });
    $("#HeaderRibbonMenuSectionInnerOff_4").unbind("click").bind("click", function() { OpenSkimmedMenu(4) });
    $("#HeaderRibbonMenuSectionInnerOff_5").unbind("click").bind("click", function() { OpenSkimmedMenu(5) });

    $("#HeaderMenuOff_1").unbind("mouseleave").bind("mouseleave", function() { CloseSkimmedMenu(1) });
    $("#HeaderMenuOff_2").unbind("mouseleave").bind("mouseleave", function() { CloseSkimmedMenu(2) });
    $("#HeaderMenuOff_3").unbind("mouseleave").bind("mouseleave", function() { CloseSkimmedMenu(3) });
    $("#HeaderMenuOff_4").unbind("mouseleave").bind("mouseleave", function() { CloseSkimmedMenu(4) });
    $("#HeaderMenuOff_5").unbind("mouseleave").bind("mouseleave", function() { CloseSkimmedMenu(5) });
}


function SwapImages(menuid) {

    var currentImgArrow = $("#ImageArrow_" + menuid).attr('src');
    $("#ImageArrow_" + menuid).attr('src', $("#ImageArrow_" + menuid).attr('hoverimage'));
    $("#ImageArrow_" + menuid).attr('hoverimage', currentImgArrow);

    var currentImgSection = $("#ImageSection_" + menuid).attr('src');
    $("#ImageSection_" + menuid).attr('src', $("#ImageSection_" + menuid).attr('hoverimage'));
    $("#ImageSection_" + menuid).attr('hoverimage', currentImgSection);
}

function HighlightMenu(menuid) {
    $("#TitleText_" + menuid).css("color", "White");
    SwapImages(menuid);
}

function UnHighlightMenu(menuid) {
    $("#TitleText_" + menuid).css("color", "rgb(255, 210, 190)");
    SwapImages(menuid);
}

function OpenSkimmedMenu(menuid) {
    $("#" + OnMenuIdSkimmed + menuid).show();
    SetElementHeight($("#" + OnMenuIdSkimmed + menuid).children(".menuSectionMiddle"));
    for (i = 1; i < 6; i++) {
        if (i != menuid) {
            CloseSkimmedMenu(i);
        }
    }
    return false;
}

function CloseSkimmedMenu(menuid) {
    if ($("#" + OnMenuIdSkimmed + menuid).css("display") != "none") {
        $("#" + OnMenuIdSkimmed + menuid).hide();
    }
    return false;
}

function SetElementHeight(element) {
    //need to set css height otherwise absolute positioned element has abnormal behaviour in IE
    element.css("height", element.height() + "px");
}
