/*!
    This file is part of the Navitaire NewSkies application.
    Copyright (C) Navitaire.  All rights reserved.
*/

/*
    Dependencies:
        This file depends on other JavaScript files to be there at run time.
        
        jquery.js:
            $ is a jquery variable

    Standards:
        JavaScript file names are camelCase, starting with a lower case letter
        Put all code in the appropriate namespace such as all object definitions go in SKYSALES.Class
        Objects take no parameters when they are constructed, but implement an init method for initialization of their data members
        
        Every object definition has some basic methods
            init(jsonObject) - calls the initializing methods
            setSettingsByObject(jsonObject) - initializes the object by matching the jsonObject key name with the public member variable name
            setVars - accesses nodes on the dom
            addEvents - adds dom events to the object, and sets event handlers
            supplant - swaps out the objects member value names in [] with there actual values
            
        Event handler method names end in Handler, for example clickEventHandler, 
        this is to identify that the this variable will be the dom object and not the object instance.
        
        You pass string ids of dom nodes to objects and they handle finding that node on the dom, and wiring up its own events
        
        Do not write HTML in JavaScript, use a template node from the XSLT, and swap out the object values with a supplant method.
            Array brackets [] are used to tell the supplant method to replace the member name with the member value.
            [name] is replaced with this.name, Hello [title] [name], becomes Hello Mr. Anderson
      
        Inheritance
            Note that I have to instantiate an instance of the base class. And keep it around to be able to call base class methods.
                var parent = new GLOBAL.Class.Base();
                
            You must make a copy of the this object, to be used when the this object turns into the window or a dom object.
                var thisChildObject = GLOBAL.extendObject(parent);
                
            To call a parent method, you must use the build in call function
                parent.setSettingsByObject.call(this);
            
            The child class must override event handler methods to set the this variable correctly.
                // The event is added in a addEvents method
                thisChildObject.domButton.click(this.updateHandler);

                // The event is handeled by the correct method, and has thisChildObject available to use via closure
                thisChildObject.updateHandler = function ()
                {
                    thisChildObject.update();
                };
            
            How to know when to use the "this" keyword, or the copied this object (thisChildObject)
            
                You should always use the copied this variable on the left side of an assignment operator.
                    thisChildObject.type = 'childObject';
                    
                Inside of an event handler method where you know the the this variable will be set to the dom object.
                    thisChildObject.updateHandler = function ()
                    {
                        thisChildObject.update();
                    };
                    
                Use the "this" keyword in every other scenario.
                    this.setSettingsByObject(jsonObject);
                    var name = this.name;
                    
        
        Follow all of the JsLint rules that apply when you click good parts.
        
        It is highly recommended that you use a JavaScript code compressor to decrease the size of the JavaScript files in production.
        Be sure to keep the original file around, because making edits to a compressed file is very difficult.
        JavaScript Compressors: 
            YUI Compressor: http://developer.yahoo.com/yui/compressor/
            JsMin: http://crockford.com/javascript/jsmin.html
        We highly recommend turning on gzip compression on your web server.
        

    General Notes:
        The common.js file is where JavaScript that is used in multiple places goes,
        or JavaScript that is commonly used. Such as code for a control that is on many views.
        
        All of the SkySales JavaScript should be behind the SKYSALES object defined in this file.
        You can think of the SKYSALES object as a namespace.
        
    ToDo:
        + Move all of the JavaScript that is dynamically output from the server to external JavaScript files 
        + Put all code behind the SKYSALES namespace, there are currently some global functions that can not be moved yet
        + Make the SkySales class smaller, most objects do not need most of its features.
        + Make the setSettingsByObject the same as in unitMap.js, so all other classes can use it.
        + Call delete after you are finished with json data, such as all of the ResourceInfo Json.
        + Change all of the if (SKYSALES.Class.ClassName === undefined) to just if (!SKYSALES.Class.ClassName) is is shorter
        + Design a way where the object tags do not get searched forunless that control is on the page, or that they are all searched for in a single pass
        + Make all event handler function names end in Handler, such as updateDomHandler. This way you will be able to easily tell what the this variable is set to.
        + Fix all of the code in this file to follow the SkySales JavaScript coding standards
        + Take out the eval calls - eval is evil
        
        
    JsLint Status:
        JsLint Status:
        Pass - JsLint Edition 2008-05-31
        
        + Strict whitespace
        + Assume a browser 
        + Disallow undefined variables
        + Disallow leading _ in identifiers
        + Disallow == and !=
        + Disallow ++ and --
        + Disallow bitwise operators
        + Tolerate eval
        Indentation 4
        
*/

/*extern $ jQuery window */

/*
    Initialize SKYSALES namespace
    All javascript in skysales should be behind the SKYSALES namespace
    This prevents naming collisions
*/
/*global SKYSALES */

SKYSALES = {};

//The JSON parser, and serializer
SKYSALES.Json = window.JSON;

//A pointer to the active resource object instance
SKYSALES.Resource = {};

//A static helper class
SKYSALES.Util = {};

//A namespace for class definitions
SKYSALES.Class = {};

/*
    A namespace for instances, 
    this is used for instances of objects that are auto generated from object tags. 
*/
SKYSALES.Instance = {};
SKYSALES.Instance.index = 0;
SKYSALES.Instance.getNextIndex = function ()
{
    SKYSALES.Instance.index += 1;
    return SKYSALES.Instance.index;
};

/*
    Name: 
        Class LocalCurrency
    Param:
        num
    Return: 
        An instance of LocalCurrency
    Functionality:
        This class is used by Util.convertToLocaleCurrency(num)
    Notes:
        This class provides the ability to convert a number to the local currency format
    Class Hierarchy:
        LocalCurrency
*/
if (!SKYSALES.Class.LocaleCurrency) 
{
    SKYSALES.Class.LocaleCurrency = function ()
    {
        var parent = new SKYSALES.Class.SkySales();
        var thisLocaleCurrency = SKYSALES.Util.extendObject(parent);
        
        thisLocaleCurrency.num = 0;
        
        var resource = SKYSALES.Util.getResource();
        var currencyCultureInfo = resource.currencyCultureInfo;
        var integerPartNum = 0;
        var integerPartString = '';
        var decimalPartString = '';
        var number = '';
        var positive = true;
        
        thisLocaleCurrency.currency = thisLocaleCurrency.num.toString();

        var getCurrencyPattern = function ()
        {
            var pattern = currencyCultureInfo.positivePattern;
            if (!positive)
            {
                pattern =  currencyCultureInfo.negativePattern;
            }
            return pattern;
        };
        
        var getIntegerPart = function (numVal)
        {
            var groupSizes = currencyCultureInfo.groupSizes || [];
            var groupSeparator = currencyCultureInfo.groupSeparator;
            var groupSizesIndex = 0;
            var index = 0;
            var currentGroupSize = 3;
            if (groupSizesIndex > groupSizes.length)
            {
                currentGroupSize = groupSizes[groupSizesIndex];
            }
            var currentGroupEndIndex = currentGroupSize - 1;
            
            integerPartNum = Math.floor(numVal);
            var localString = integerPartNum.toString();
            var array = localString.split('');
            var reverseArray = array.reverse();
            var reverseArrayOutput = [];            

            var getNextGroupSize = function ()
            {
                var nextGroupSize = 3;
                //Increment group sizes index if necessary
                if (groupSizesIndex <= groupSizes.length - 2)
                {
                    groupSizesIndex += 1;
                    nextGroupSize = groupSizes[groupSizesIndex];
                }
                else
                {
                    nextGroupSize = currentGroupSize;
                }
                currentGroupEndIndex += nextGroupSize;
                return nextGroupSize;
            };

            for (index = 0; index < reverseArray.length; index += 1)
            {
                if (index > currentGroupEndIndex)
                {
                    currentGroupSize = getNextGroupSize();
                    reverseArrayOutput.push(groupSeparator);
                }                
                reverseArrayOutput.push(reverseArray[index]);
            }
            
            array = reverseArrayOutput.reverse();
            var outputString = array.join('');
            return outputString;
        };
        
        var getDecimalPart = function (numVal)
        {
            var decimalPart = numVal - integerPartNum;
            var decimalPartTrimmed = decimalPart.toFixed(currencyCultureInfo.decimalDigits);
            var decimalPartString = decimalPartTrimmed.substring(2);
            return decimalPartString;
        };
        
        var applyPattern = function ()
        {
            var pattern = getCurrencyPattern() || '';
            var replaceNumber = pattern.replace('n', number);
            return replaceNumber;
        };
        
        thisLocaleCurrency.init = function (json)
        {
            this.setSettingsByObject(json);
            positive = this.num >= 0;
            // Make the number positive. The applyPattern will reestablish the sign.
            this.num = Math.abs(this.num);            
            integerPartString = getIntegerPart(this.num);
            decimalPartString = getDecimalPart(this.num);
            number = integerPartString + currencyCultureInfo.decimalSeparator + decimalPartString;    
            thisLocaleCurrency.currency = applyPattern();
        };
        return thisLocaleCurrency;
    };
}

/*
    Name: 
        Class Resource
    Param:
        None
    Return: 
        An instance of Resource
    Functionality:
        Used to hold any common data that multiple controls use such as
        CountryInfo, MacInfo, StationInfo, and BookingInfo
    Notes:
        Right now there is one resource object instance.
        It is accessed in the JavaScript by calling SKYSALES.Util.getResource()
        It is created in the common.xslt file, and populated by resource data
        that is written to JSON.
        The resources that come down to the browser are configured at a view level in the naml file.
        To get a list of stations in JSON you add the node of
        <bind link="StationResource" property="ResourceContainer"/>
        as a child node of the view node.
        
        This class also contains a way to access cookie data. 
        Such as the contact info that is stored in a cookie to populate the contact view.
    Class Hierarchy:
        SkySales -> Resource
*/
SKYSALES.Class.Resource = function ()
{
    var parent = new SKYSALES.Class.SkySales();
    var thisResource = SKYSALES.Util.extendObject(parent);
    
    thisResource.locationInfo = {};
    thisResource.countryInfo = {};
    thisResource.stationInfo = {};
    thisResource.macInfo = {};
    thisResource.marketInfo = {};
    thisResource.macHash = {};
    thisResource.stationHash = {};
    thisResource.marketHash = {};
    thisResource.sourceInfo = {};
    thisResource.clientHash = {};
    thisResource.dateCultureInfo = {};
    thisResource.currencyCultureInfo = {};
    
    /*
        Turns the macInfo into a hash for quick lookups.
        Keying into the macHash with the mac code you will get back 
        an object that contains an array of station codes that the mac code is associated with.
        macHash[macCode] = { "code": "stationCode", "stations": [ "stationCode1", "stationCode2" ] };
    */
    thisResource.populateMacHash = function ()
    {
        var i = 0;
        var macArray = [];
        var macHash = {};
        var mac = null;
        if (thisResource.macInfo && thisResource.macInfo.MacList)
        {
            macArray = thisResource.macInfo.MacList;
            for (i = 0; i < macArray.length; i += 1)
            {
                mac = macArray[i];
                macHash[mac.code] = mac;
            }
        }
        thisResource.macHash = macHash;
    };
    
    /*
        Turns the stationInfo into a hash for quick lookups.
        Keying into the stationHash with the station code you will get back a station object
        stationHash[stationCode] = { "macCode": "", "name":"", "code": "" };
    */
    thisResource.populateStationHash = function ()
    {
        var i = 0;
        var stationArray = [];
        var stationHash = {};
        var station = null;
        if (thisResource.stationInfo && thisResource.stationInfo.StationList)
        {
            stationArray = thisResource.stationInfo.StationList;
            for (i = 0; i < stationArray.length; i += 1)
            {
                station = stationArray[i];
                stationHash[station.code] = station;
                }
            }
        thisResource.stationHash = stationHash;
    };
    
    /*
        Turns the marketInfo into a hash for quick lookups.
        Keying into the marketHash with the orgin station code you will get back an array of objects.
        Each object contains a destination station code that can be mapped to a station object using the stationHash.
        marketHash[originStationCode] = [ { "code": "destinationStationCode1", "name": "destinationStationCode2" } ]
    */
    thisResource.populateMarketHash = function ()
    {
        var i = 0;
        var marketHash = {};
        var marketArray = [];
        var market = {};
        
        var destinationIndex = 0;
        var destinationArray = [];
        var destinationCode = '';
        var destination = {};
        var station = {};
        
        if (thisResource.marketInfo && thisResource.marketInfo.MarketList)
        {
            marketArray = thisResource.marketInfo.MarketList;
            for (i = 0; i < marketArray.length; i += 1)
            {
                market = marketArray[i];
                destinationArray = market.Value;
                if (destinationArray)
                {
                    marketHash[market.Key] = destinationArray;
                    for (destinationIndex = 0; destinationIndex < destinationArray.length; destinationIndex += 1)
                    {
                        destination = destinationArray[destinationIndex];
                        destinationCode = destination.code;
                        destination.name = '';
                        station = thisResource.stationHash[destinationCode];
                        if (station)
                        {
                            destination.name = station.name;
                        }
                    }
                }
            }
            thisResource.marketHash = marketHash;
        }
    };
    
    /*
        The clientHash is data that has been stored in a cookie
    */
    thisResource.populateClientHash = function ()
    {
        var cookie = window.document.cookie;
        var nameValueArray = [];
        var i = 0;
        var singleNameValue = '';
        var key = '';
        var value = '';
        var eqIndex = -1;
        if (cookie)
        {
            nameValueArray = document.cookie.split('; ');
            for (i = 0; i < nameValueArray.length; i += 1)
            {
                singleNameValue = nameValueArray[i];
                eqIndex = singleNameValue.indexOf('=');
                if (eqIndex > -1)
                {
                    key = singleNameValue.substring(0, eqIndex);
                    value = singleNameValue.substring(eqIndex + 1, singleNameValue.length);
                    if (key)
                    {
                        value = SKYSALES.Util.decodeUriComponent(value);
                        thisResource.clientHash[key] = value;
                    }
                }
            }
        }
    };
    
    /*
        Populate the object instance.
        This is accomplished by matching the name of the public menber 
        with the name of the key in the key: value pair of the JSON object that is passed in.
        It then turns the data into hash lists for quick lookups.
    */
    thisResource.setSettingsByObject = function (jsonObject)
    {
        parent.setSettingsByObject.call(this, jsonObject);
        thisResource.populateStationHash();
        thisResource.populateMacHash();
        thisResource.populateMarketHash();
        thisResource.populateClientHash();
    };
    return thisResource;
};

/*
    Name: 
        Class Util
    Param:
        None
    Return: 
        None
    Functionality:
        Represents a Static Util object
    Notes:
        Provides common methods.
        Used for inheritance - for example
            var parent = new SKYSALES.Class.SkySales();
            var theObject = SKYSALES.Util.extendObject(parent);
        This class reads in the JSON object tags and instantiates them into running JavaScript
    Class Hierarchy:
        SkySales -> Resource
*/

SKYSALES.Util.createObjectArray = [];
SKYSALES.Util.createObject = function (objNameBase, objType, json)
{
    var createObjectArray = SKYSALES.Util.createObjectArray;
    createObjectArray[createObjectArray.length] = {
        'objNameBase': objNameBase,
        'objType': objType,
        'json': json
    };
};

SKYSALES.Util.initObjects = function ()
{
    var i = 0;
    var createObjectArray = SKYSALES.Util.createObjectArray;
    var objName = '';
    var objectType = '';
    var json = null;
    var createObject = null;
    for (i = 0; i < createObjectArray.length; i += 1)
    {
        createObject = createObjectArray[i];
        objName = createObject.objNameBase + SKYSALES.Instance.getNextIndex();
        objectType = createObject.objType;
        json = createObject.json || {};
        if (SKYSALES.Class[objectType])
        {
            SKYSALES.Instance[objName] = new SKYSALES.Class[objectType]();
            SKYSALES.Instance[objName].init(json);
        }
    }
    SKYSALES.Util.createObjectArray = [];
};

//Replace characters that could not be stored in a cookie
SKYSALES.Util.decodeUriComponent = function (str)
{
    str = str || '';
    if (window.decodeURIComponent)
    {
        str = window.decodeURIComponent(str);
    }
    str = str.replace(/\+/g, ' ');
    return str;
};

//Replace characters for cookie storage
SKYSALES.Util.encodeUriComponent = function (str)
{
    str = str || '';
    if (window.encodeURIComponent)
    {
        str = window.encodeURIComponent(str);
    }
    return str;
};

//Return the main resource instance, this object is instantiated in the common.xslt
SKYSALES.Util.getResource = function ()
{
    return SKYSALES.Resource;
};

//Douglas Crockford's inheritance method
SKYSALES.Util.extendObject = function (o)
{
    var F = function () {};
    F.prototype = o;
    return new F();
};

//Instantiates an object from an html object tag
SKYSALES.Util.initializeNewObject = function (paramObject)
{
    var objName = "";
    
    var defaultSetting = {
        objNameBase: '',
        objType: '',
        selector: ''
    };
    var validateParamObject = function ()
    {
        var retVal = true;
        $().extend(defaultSetting, paramObject);
        var propName = null;
        for (propName in defaultSetting)
        {
            if (defaultSetting.hasOwnProperty(propName))
            {
                if (defaultSetting[propName] === undefined)
                {
                    retVal = false;
                    break;
                }
            }
        }
        return retVal;
    };
    var paramNodeFunction = function (index)
    {
        var paramNodeValue = $(this).val();
        var parsedJsonObject = SKYSALES.Json.parse(paramNodeValue);
        var funRef = null;
        var refName = '';
        var refArray = [];
        var i = 0;
        var refIndex = 0;
        var arrayRegex = /^([a-zA-Z0-9]+)\[(\d+)\]$/;
        var matchArray = [];
        if (parsedJsonObject.method !== undefined)
        {
            funRef = SKYSALES.Instance[objName];
            if (parsedJsonObject.method.name.indexOf('.') > -1)
            {
                refArray = parsedJsonObject.method.name.split('.');
                for (i = 0; i < refArray.length; i += 1)
                {
                    refName = refArray[i];
                    matchArray = refName.match(arrayRegex);
                    if ((matchArray) && (matchArray.length > 0))
                    {
                        refName = matchArray[1];
                        refIndex = matchArray[2];
                        refIndex = parseInt(refIndex, 10);
                        funRef = funRef[refName][refIndex];
                    }
                    else
                    {
                        funRef = funRef[refName];
                    }
                }
            }
            else
            {
                funRef = funRef[parsedJsonObject.method.name];
            }
            
            if (funRef)
            {
                funRef(parsedJsonObject.method.paramJsonObject);
            }
        }
    };
    var objectNodeFunction = function ()
    {
        objName = paramObject.objNameBase + SKYSALES.Instance.getNextIndex();
        if (SKYSALES.Class[paramObject.objType])
        {
            SKYSALES.Instance[objName] = new SKYSALES.Class[paramObject.objType]();
            $("object.jsObject > param", this).each(paramNodeFunction);
        }
        else
        {
            alert("Object Type Not Found: " + paramObject.objType);
        }
    };
    var containerFunction = function ()
    {
        var isValid = validateParamObject();
        if (isValid)
        {
            $(paramObject.selector).each(objectNodeFunction);
        }
        else
        {
            alert("\nthere has been an error");
        }
    };
    containerFunction();
    return false;
};

/*
    Populates a html select box
    An Option object should always be used instead of writing <option> nodes to the dom.
    Writing <option> nodes to the dom has issues in IE6
*/
SKYSALES.Util.populateSelect = function (paramObj)
{
    var selectedItem = paramObj.selectedItem || null;
    var objectArray = paramObj.objectArray || null;
    var selectBox = paramObj.selectBox || null;
    var showCode = paramObj.showCode || false;
    var clearOptions = paramObj.clearOptions || false;
    var text = '';
    var value = '';
    var selectBoxObj = null;
    var obj = null;
    var prop = '';
    
    if (selectBox)
    {
        selectBoxObj = selectBox.get(0);
        if (selectBoxObj && selectBoxObj.options)
        {
            if (clearOptions)
            {
                selectBoxObj.options.length = 0;
            }
            else
            {
                if (!selectBoxObj.originalOptionLength)
                {
                    selectBoxObj.originalOptionLength = selectBoxObj.options.length;
                }
                selectBoxObj.options.length = selectBoxObj.originalOptionLength;
            }
            if (objectArray)
            {
                for (prop in objectArray)
                {
                    if (objectArray.hasOwnProperty(prop))
                    {
                        obj = objectArray[prop];
                        if (showCode)
                        {
                            text = obj.name + ' (' + obj.code + ')';
                        }
                        else
                        {
                            text = obj.name;
                        }
                        value = obj.code;
                        selectBoxObj.options[selectBoxObj.options.length] = new window.Option(text, value, false, false);
                    }
                }
                if (selectedItem !== null)
                {
                    selectBox.val(selectedItem);
                }
            }
        }
    }
};

SKYSALES.Util.cloneArray = function (array)
{
    return array.concat();
};

SKYSALES.Util.convertToLocaleCurrency = function (num)
{
    var json = {
        'num': num
    };
    var localCurrency = new SKYSALES.Class.LocaleCurrency();
    localCurrency.init(json);
    return localCurrency.currency;
};

/*
    Name: 
        Class SkySales
    Param:
        None
    Return: 
        An instance of SkySales
    Functionality:
        This is the SkySales base class that most objects inherit from
    Notes:
        This class provides the ability to show and hide objects based on their container.
    Class Hierarchy:
        SkySales
*/
if (!SKYSALES.Class.SkySales)
{
    SKYSALES.Class.SkySales = function ()
    {   
        var thisSkySales = this;
        
        thisSkySales.containerId = '';
        thisSkySales.container = null;
        
        thisSkySales.init = SKYSALES.Class.SkySales.prototype.init;
        thisSkySales.setSettingsByObject = SKYSALES.Class.SkySales.prototype.setSettingsByObject;
        thisSkySales.addEvents = SKYSALES.Class.SkySales.prototype.addEvents;
        thisSkySales.setVars = SKYSALES.Class.SkySales.prototype.setVars;
        thisSkySales.hide = SKYSALES.Class.SkySales.prototype.hide;
        thisSkySales.show = SKYSALES.Class.SkySales.prototype.show;
        return thisSkySales;
    };
    SKYSALES.Class.SkySales.prototype.init = function (json)
    {
        this.setSettingsByObject(json);
        this.setVars();
    };
    SKYSALES.Class.SkySales.prototype.setSettingsByObject = function (json)
    {
        var propName = '';
        for (propName in json)
        {
            if (json.hasOwnProperty(propName))
            {
                if (this[propName] !== undefined)
                {
                    this[propName] = json[propName];
                }
            }
        }
    };
    SKYSALES.Class.SkySales.prototype.addEvents = function () {};
    SKYSALES.Class.SkySales.prototype.setVars = function () 
    {
        this.container = $('#' + this.containerId);
    };
    SKYSALES.Class.SkySales.prototype.hide = function () 
    {
        this.container.hide('slow');
    };
    SKYSALES.Class.SkySales.prototype.show = function () 
    {
        this.container.show('slow');
    };
}

/*
    Name: 
        Class BaseToggleView
    Param:
        None
    Return: 
        An instance of BaseToggleView
    Functionality:
        This is the Base class for any class that can show or hide itself.
        The containerId is the id of the domelement that you wish to show and hide.
    Notes:
    Class Hierarchy:
        SkySales -> BaseToggleView
*/
if (!SKYSALES.Class.BaseToggleView)
{
    SKYSALES.Class.BaseToggleView = function ()
    {   
        var parent = SKYSALES.Class.SkySales();
        var thisBaseToggleView = SKYSALES.Util.extendObject(parent);
        
        thisBaseToggleView.toggleViewIdArray = [];
        thisBaseToggleView.toggleViewArray = [];
        
        thisBaseToggleView.addToggleView = function (json)
        {
            if (json.toggleViewIdArray)
            {
                json = json.toggleViewIdArray;
            }
            var toggleViewIdArray = json || [];
            var toggleViewIdObj = null;
            var i = 0;
            var toggleView = null;
            if (toggleViewIdArray.length === undefined)
            {
                toggleViewIdArray = [];
                toggleViewIdArray[0] = json;
            }
            for (i = 0; i < toggleViewIdArray.length; i += 1)
            {
                toggleViewIdObj = toggleViewIdArray[i];
                toggleView = new SKYSALES.Class.ToggleView();
                toggleView.init(toggleViewIdObj);
                thisBaseToggleView.toggleViewArray[thisBaseToggleView.toggleViewArray.length] = toggleView;
            }
        };
        return thisBaseToggleView;
    };
}

/*
    Name: 
        Class FlightSearch
    Param:
        None
    Return: 
        An instance of FlightSearch
    Functionality:
        The object that initializes the AvailabilitySearchInput control
    Notes:
        This class contains and creates all of the objects necessary to add functionality to the AvailabilitySearchInput control
    Class Hierarchy:
        SkySales -> FlightSearch
*/
if (!SKYSALES.Class.FlightSearch)
{ 
    SKYSALES.Class.FlightSearch = function ()
    {   
        var parent = new SKYSALES.Class.SkySales();
        var thisFlightSearch = SKYSALES.Util.extendObject(parent);
        
        thisFlightSearch.marketArray = null;
        thisFlightSearch.flightTypeInputIdArray = null;
        thisFlightSearch.countryInputIdArray = null;
        
        var countryInputArray = [];
        var flightTypeInputArray = [];
        
        thisFlightSearch.init = function (paramObject)
        {
            this.setSettingsByObject(paramObject);
            this.setVars();
            this.addEvents();
            this.initFlightTypeInputIdArray();
            this.initCountryInputIdArray();
            this.populateFlightType();
        };
        
        thisFlightSearch.setSettingsByObject = function (json)
        {
            parent.setSettingsByObject.call(this, json);
            
            var i = 0;
            var marketArray = this.marketArray || [];
            var market = null;
            for (i = 0; i < marketArray.length; i += 1)
            {
                market = new SKYSALES.Class.FlightSearchMarket();
                market.flightSearch = this;
                market.index = i;
                market.init(marketArray[i]);
                thisFlightSearch.marketArray[i] = market;
            }
        };

        thisFlightSearch.initCountryInputIdArray = function ()
        {
            var i = 0;
            var countryInputId = null;
            var countryInput = {};
            var countryInputIdArray = this.countryInputIdArray || [];
            for (i = 0; i < countryInputIdArray.length; i += 1)
            {
                countryInputId = countryInputIdArray[i];
                countryInput = new SKYSALES.Class.CountryInput();
                countryInput.init(countryInputId);
                countryInputArray[countryInputArray.length] = countryInput;
            }
        };
        
        thisFlightSearch.initFlightTypeInputIdArray = function ()
        {
            var i = 0;
            var flightTypeInputId = null;
            var flightTypeInput = {};
            var flightTypeInputIdArray = this.flightTypeInputIdArray || [];
            for (i = 0; i < flightTypeInputIdArray.length; i += 1)
            {
                flightTypeInputId = flightTypeInputIdArray[i];
                flightTypeInput = new SKYSALES.Class.FlightTypeInput();
                flightTypeInput.flightSearch = this;
                flightTypeInput.index = i;
                flightTypeInput.init(flightTypeInputId);
                flightTypeInputArray[flightTypeInputArray.length] = flightTypeInput;
            }
        };
        
        thisFlightSearch.populateFlightType = function ()
        {
            var flightTypeIndex = 0;
            var flightType = null;
            for (flightTypeIndex = 0; flightTypeIndex < flightTypeInputArray.length; flightTypeIndex += 1)
            {
                flightType = flightTypeInputArray[flightTypeIndex];
                if (flightType.input.attr('checked'))
                {
                    flightType.input.click();
                    break;
                }
            }
        };
        
        thisFlightSearch.updateFlightType = function (activeflightType)
        {
            var flightTypeIndex = 0;
            var flightType = null;
            
            for (flightTypeIndex = 0; flightTypeIndex < flightTypeInputArray.length; flightTypeIndex += 1)
            {
                flightType = flightTypeInputArray[flightTypeIndex];
                flightType.hideInputArray.show();
            }
            activeflightType.hideInputArray.hide();
        };
        
        
        return thisFlightSearch;
    };
    SKYSALES.Class.FlightSearch.createObject = function (json)
    {
        SKYSALES.Util.createObject('flightSearch', 'FlightSearch', json);
    };
}


/*
    Name: 
        Class FlightSearchMarket
    Param:
        None
    Return: 
        An instance of FlightSearchMarket
    Functionality:
        The object that initializes the market data for the AvailabilitySearchInput control
    Notes:
        
    Class Hierarchy:
        SkySales -> FlightSearchMarket
*/
if (!SKYSALES.Class.FlightSearchMarket)
{ 
    SKYSALES.Class.FlightSearchMarket = function ()
    {   
        var parent = new SKYSALES.Class.SkySales();
        var thisFlightSearchMarket = SKYSALES.Util.extendObject(parent);
        
        thisFlightSearchMarket.flightSearch = null;
        thisFlightSearchMarket.index = -1;
        //thisFlightSearchMarket.validationInputId = '';
        thisFlightSearchMarket.validationMessageObject = {};
        
        thisFlightSearchMarket.validationObjectIdArray = [];
        thisFlightSearchMarket.stationInputIdArray = [];
        thisFlightSearchMarket.stationDropDownIdArray = [];
        thisFlightSearchMarket.marketInputIdArray = [];
        thisFlightSearchMarket.macInputIdArray = [];
        thisFlightSearchMarket.marketDateIdArray = [];
        
        //var validationInput = null;
        var marketInputArray = [];
        var stationInputArray = [];
        var stationDropDownArray = [];
        var macInputArray = [];
        var marketDateArray = [];
        
        thisFlightSearchMarket.init = function (json)
        {
            this.setSettingsByObject(json);
            this.setVars();
            this.addEvents();

            this.initMarketInputIdArray();
            this.initStationInputIdArray();
            this.initStationDropDownIdArray();
            this.initMacInputIdArray();
            this.initMarketDateIdArray();
            this.initValidationObjectRedirect();
        };
        
        thisFlightSearchMarket.initMacInputIdArray = function ()
        {
            var i = 0;
            var macInputId = null;
            var macInput = {};
            var macInputIdArray = this.macInputIdArray || [];
            for (i = 0; i < macInputIdArray.length; i += 1)
            {
                macInputId = macInputIdArray[i];
                macInput = new SKYSALES.Class.MacInput();
                macInput.init(macInputId);
                macInputArray[macInputArray.length] = macInput;
                macInput.showMac.call(macInput.stationInput);
            }
        };
        
        thisFlightSearchMarket.initMarketDateIdArray = function ()
        {
            var i = 0;
            var marketDateId = null;
            var marketDate = {};
            var marketDateIdArray = this.marketDateIdArray || [];
            for (i = 0; i < marketDateIdArray.length; i += 1)
            {
                marketDateId = marketDateIdArray[i];
                marketDate = new SKYSALES.Class.MarketDate();
                marketDate.init(marketDateId);
                marketDateArray[marketDateArray.length] = marketDate;
            }
        };
        
        thisFlightSearchMarket.initMarketInputIdArray = function ()
        {
            var i = 0;
            var marketInputId = null;
            var marketInput = {};
            var marketInputIdArray = this.marketInputIdArray || [];
            for (i = 0; i < marketInputIdArray.length; i += 1)
            {
                marketInputId = marketInputIdArray[i];
                marketInput = new SKYSALES.Class.MarketInput();
                marketInput.init(marketInputId);
                marketInputArray[marketInputArray.length] = marketInput;
            }
        };
        
        thisFlightSearchMarket.initStationInputIdArray = function ()
        {
            var i = 0;
            var stationInputId = null;
            var stationInput = {};
            var stationInputIdArray = this.stationInputIdArray;
            for (i = 0; i < stationInputIdArray.length; i += 1)
            {
                stationInputId = stationInputIdArray[i];
                stationInput = new SKYSALES.Class.StationInput();
                stationInput.init(stationInputId);
                stationInputArray[stationInputArray.length] = stationInput;
            }
        };
        
        thisFlightSearchMarket.initStationDropDownIdArray = function ()
        {
            var i = 0;
            var stationDropDownId = null;
            var stationDropDown = {};
            var stationDropDownIdArray = this.stationDropDownIdArray;
            for (i = 0; i < stationDropDownIdArray.length; i += 1)
            {
                stationDropDownId = stationDropDownIdArray[i];
                stationDropDown = new SKYSALES.Class.StationDropDown();
                stationDropDown.init(stationDropDownId);
                stationDropDownArray[stationDropDownArray.length] = stationDropDown;
            }
        };
        
        //This function will redirect validation to a new object if the view has
        //been configured to use drop down lists but will tolerate a misconfiguration
        //if the dropdownlist mapping is not removed from the view
        thisFlightSearchMarket.initValidationObjectRedirect = function ()
        {
            //find the metaobject used to validate the first item inthe hash
            var validationObjectIdArray = this.validationObjectIdArray || [];
            var i = 0;
            var validationObjectId = '';
            var key = '';
            var value = '';
            var metaObjectParamToModify = null;
            var dropDownListToValidate = null;
            var metaObjectParam = null;
            for (i = 0; i < validationObjectIdArray.length; i += 1)
            {
                validationObjectId = validationObjectIdArray[i];
                key = validationObjectId.key || '';
                value = validationObjectId.value || '';
                metaObjectParamToModify = $("object.metaobject>param[@value*='" + key + "']");
                if (metaObjectParamToModify.length > 0)
                {
                    //before we do the work check to see if the validation target even exists                        
                    dropDownListToValidate = $(":input#" + value);
                    if (dropDownListToValidate.length > 0)
                    {
                        metaObjectParam = metaObjectParamToModify[0];
                        if ('value' in metaObjectParam)
                        {
                            var newStr = metaObjectParam.value;
                            newStr = newStr.replace(key, value);
                            metaObjectParam.value = newStr;
                        }
                    }
                }
            }
        };
        return thisFlightSearchMarket;
    };
}


/*
    Name: 
        Class FlightStatusSearchContainer
    Param:
        None
    Return: 
        An instance of FlightStatusSearchContainer
    Functionality:
        The object that initializes the FlightFollowing control
    Notes:
        A FlightStatusSearchContainer object is created every time a div appears in the dom that has a class of flightStatusSearchContainer
        <div class="flightStatusSearchContainer" ></div>
        There should be one instance of this object for every FlightFollowing control in the view.
    Class Hierarchy:
        SkySales -> FlightSearchContainer -> FlightStatusSearchContainer
*/
//if (!SKYSALES.Class.FlightStatusSearchContainer)
//{ 
//    SKYSALES.Class.FlightStatusSearchContainer = function ()
//    {   
//        var flightStatusSearchContainer = new SKYSALES.Class.FlightSearchContainer();
//        var thisFlightStatusSearchContainer = SKYSALES.Util.extendObject(flightStatusSearchContainer);
//        return thisFlightStatusSearchContainer;
//    };
//    SKYSALES.Class.FlightStatusSearchContainer.initializeFlightStatusSearchContainers = function ()
//    {
//        var paramObject = {
//            objNameBase: 'flightStatusSearchContainer',
//            objType: 'FlightStatusSearchContainer',
//            selector: 'div.flightStatusSearchContainer'
//        };
//        SKYSALES.Util.initializeNewObject(paramObject);
//    };
//}

/*
    Name: 
        Class MacInput
    Param:
        None
    Return: 
        An instance of MacInput
    Functionality:
        Handels the functionality of the macs on the AvailabilitySearchInput control
    Notes:
        This class controls the mac html input controls
    Class Hierarchy:
        SkySales -> MacInput
*/
if (!SKYSALES.Class.MacInput)
{
    SKYSALES.Class.MacInput = function ()
    {
        var macInputBase = new SKYSALES.Class.SkySales();
        var thisMacInput = SKYSALES.Util.extendObject(macInputBase);
        
        thisMacInput.macHash = SKYSALES.Util.getResource().macHash;
        thisMacInput.stationHash = SKYSALES.Util.getResource().stationHash;
        thisMacInput.stationInputId = '';
        thisMacInput.macContainerId = '';
        thisMacInput.macLabelId = '';
        thisMacInput.macInputId = '';
        thisMacInput.macContainer = {};
        thisMacInput.stationInput = {};
        thisMacInput.macInput = {};
        thisMacInput.macLabel = {};
        
        thisMacInput.showMac = function ()
        {
            var stationCode = $(this).val();
            stationCode = stationCode || '';
            stationCode = stationCode.toUpperCase();
            var station = null;
            var macCode = '';
            var macText = '';
            var mac = null;

            thisMacInput.macInput.removeAttr('checked');
            thisMacInput.macContainer.hide();
            station = thisMacInput.stationHash[stationCode];
            if (station)
            {
                macCode = station.macCode;
                mac = thisMacInput.macHash[macCode];
                if ((mac) && (mac.stations.length > 0))
                {
                    macText = mac.stations.join();
                    thisMacInput.macLabel.html(macText);
                    thisMacInput.macContainer.show();
                }
            }
        };
        
        thisMacInput.addEvents = function ()
        {
            thisMacInput.stationInput.change(thisMacInput.showMac);
        };
        
        thisMacInput.setVars = function ()
        {
            thisMacInput.stationInput = $('#' + thisMacInput.stationInputId);
            thisMacInput.macContainer = $('#' + thisMacInput.macContainerId);
            thisMacInput.macLabel = $('#' + thisMacInput.macLabelId);
            thisMacInput.macInput = $('#' + thisMacInput.macInputId);
        };
        
        thisMacInput.init = function (paramObject)
        {
            macInputBase.init.call(this, paramObject);
            thisMacInput.macContainer.hide();
            this.addEvents();
        };
        return thisMacInput;
    };
}

/*
    Name: 
        Class MarketDate
    Param:
        None
    Return: 
        An instance of MarketDate
    Functionality:
         Handels the functionality of the dates on the AvailabilitySearchInput control
    Notes:
        The dates also effect the date selection calendar
    Class Hierarchy:
        SkySales -> MarketDate
*/
if (!SKYSALES.Class.MarketDate)
{
    SKYSALES.Class.MarketDate = function ()
    {
        var marketDateBase = new SKYSALES.Class.SkySales();
        var thisMarketDate = SKYSALES.Util.extendObject(marketDateBase);
        
        thisMarketDate.dateFormat = SKYSALES.datepicker.datePickerFormat;
        thisMarketDate.dateDelimiter = SKYSALES.datepicker.datePickerDelimiter;
        thisMarketDate.marketDateId = '';
        thisMarketDate.marketDate = null;
        thisMarketDate.marketDayId = '';
        thisMarketDate.marketDay = null;
        thisMarketDate.marketMonthYearId = '';
        thisMarketDate.marketMonthYear = null;
        
        thisMarketDate.setSettingsByObject = function (jsonObject)
        {
            marketDateBase.setSettingsByObject.call(this, jsonObject);
            var propName = '';
            for (propName in jsonObject)
            {
                if (thisMarketDate.hasOwnProperty(propName))
                {
                    thisMarketDate[propName] = jsonObject[propName];
                }
            }
        };
        
        thisMarketDate.parseDate = function (dateStr)
        {
            var day = '';
            var month = '';
            var year = '';
            var date = new Date();
            var dateData = '';
            var formatChar = '';
            var datePickerArray = [];
            var i = 0;
            if (dateStr.indexOf(thisMarketDate.dateDelimiter) > -1)
            {
                datePickerArray = dateStr.split(thisMarketDate.dateDelimiter);
                for (i = 0; i < thisMarketDate.dateFormat.length; i += 1)
                {
                    dateData = datePickerArray[i];
                    if (dateData.charAt(0) === '0')
                    {
                        dateData = dateData.substring(1);
                    }
                    formatChar = thisMarketDate.dateFormat.charAt(i);
                    switch (formatChar)
                    {
                    case 'm': 
                        month = dateData; 
                        break;
                    case 'd': 
                        day = dateData; 
                        break;
                    case 'y': 
                        year = dateData; 
                        break;
                    }
                }
                
                date = new Date(year, month - 1, day);
            }
            return date;
        };
        
        thisMarketDate.addEvents = function ()
        {
            var datePickerManager = new SKYSALES.Class.DatePickerManager();
            datePickerManager.isAOS = false;
            datePickerManager.yearMonth = thisMarketDate.marketMonthYear;
            datePickerManager.day = thisMarketDate.marketDay;
            datePickerManager.linkedDate = thisMarketDate.marketDate;
            datePickerManager.init();
        };
        
        thisMarketDate.setVars = function ()
        {
            thisMarketDate.marketDate = $('#' + thisMarketDate.marketDateId);
            thisMarketDate.marketDay = $('#' + thisMarketDate.marketDayId);
            thisMarketDate.marketMonthYear = $('#' + thisMarketDate.marketMonthYearId);
        };
        
        thisMarketDate.init = function (paramObject)
        {
            marketDateBase.init.call(this, paramObject);
            
            this.addEvents();
        };
        
        thisMarketDate.datesInOrder = function (dateArray)
        {       
            var retVal = true;
            var dateA = null;
            var dateB = null;
            
            dateA = this.parseDate(dateArray[0]);                
            dateB = this.parseDate(dateArray[1]);
            
            if (dateA > dateB)
            {
                retVal = false;
            }
            return retVal;
        };
        
        thisMarketDate.datesNotPast = function (dateArray)
        {       
            var retVal = true;
            var dateA = null;
            var dateB = null;
            
            dateA = this.parseDate(dateArray[0]);                
            dateB = this.parseDate(dateArray[1]);
            
            var dateCheckerA = new IDTGV.Class.DateChecker(dateA.getDate(),dateA.getMonth()+1,dateA.getFullYear());
            var dateCheckerB = new IDTGV.Class.DateChecker(dateB.getDate(),dateB.getMonth()+1,dateB.getFullYear());
            
            
            if ( dateCheckerA.isPastDate() || dateCheckerB.isPastDate())
            {
                return false;
            }
            
            return retVal;
        };

        return thisMarketDate;
    };
}

/*
    Name: 
        Class CountryInput
    Param:
        None
    Return: 
        An instance of CountryInput
    Functionality:
         Handels the functionality of the resident country on the AvailabilitySearchInput control
    Notes:
        The list of countries comes from the resource object
    Class Hierarchy:
        SkySales -> CountryInput
*/
if (!SKYSALES.Class.CountryInput)
{
    SKYSALES.Class.CountryInput = function ()
    {
        var countryInputBase = new SKYSALES.Class.SkySales();
        var thisCountryInput = SKYSALES.Util.extendObject(countryInputBase);
        
        thisCountryInput.countryInfo = SKYSALES.Util.getResource().countryInfo;
        thisCountryInput.countryInputId = '';
        thisCountryInput.input = {};
        thisCountryInput.defaultCountry = '';
        thisCountryInput.countryArray = [];
        
        thisCountryInput.populateCountryInput = function ()
        {
            var selectParamObj = {
                'selectBox': thisCountryInput.input,
                'objectArray': thisCountryInput.countryArray,
                'selectedItem': thisCountryInput.defaultCountry,
                'showCode': true
            };
            SKYSALES.Util.populateSelect(selectParamObj);
        };
        
        thisCountryInput.addEvents = function ()
        {
        };
        
        thisCountryInput.setVars = function ()
        {
            thisCountryInput.input = $('#' + thisCountryInput.countryInputId);
            var countryInfo = thisCountryInput.countryInfo;
            if (countryInfo)
            {
                if (countryInfo.CountryList)
                {
                    thisCountryInput.countryArray = countryInfo.CountryList;
                }
                if (countryInfo.DefaultValue)
                {
                    thisCountryInput.defaultCountry = countryInfo.DefaultValue;
                }
            }
        };
        
        thisCountryInput.init = function (paramObject)
        {
            countryInputBase.init.call(this, paramObject);
            thisCountryInput.populateCountryInput();
            this.addEvents();
        };
        return thisCountryInput;
    };
}

/*
    Name: 
        Class FlightTypeInput
    Param:
        None
    Return: 
        An instance of CountryInput
    Functionality:
         Handels the functionality of the flight type on the AvailabilitySearchInput control
    Notes:
        Flight type is the type of flight, as in Round Trip, One Way, or Open Jaw
        When you select a flight type the correct html fields are shown.
    Class Hierarchy:
        SkySales -> FlightTypeInput
*/
if (!SKYSALES.Class.FlightTypeInput)
{
    SKYSALES.Class.FlightTypeInput = function ()
    {
        var parent = new SKYSALES.Class.SkySales();
        var thisFlightTypeInput = SKYSALES.Util.extendObject(parent);
        
        thisFlightTypeInput.flightSearch = null;
        thisFlightTypeInput.index = -1;
        
        thisFlightTypeInput.flightTypeId = '';
        thisFlightTypeInput.hideInputIdArray = [];
        thisFlightTypeInput.hideInputArray = [];
        thisFlightTypeInput.input = {};
        
        thisFlightTypeInput.updateFlightTypeHandler = function ()
        {
            thisFlightTypeInput.flightSearch.updateFlightType(thisFlightTypeInput);
        };
        
        thisFlightTypeInput.addEvents = function ()
        {
            parent.addEvents.call(this);
            this.input.click(this.updateFlightTypeHandler);
        };
        
        thisFlightTypeInput.getById = function (id) 
        {
            var retVal = null;
            if (id)
            {
                retVal = window.document.getElementById(id);
            }
            return retVal;
        };
        
        thisFlightTypeInput.setVars = function ()
        {
            parent.setVars.call(this);
            
            var hideInputIndex = 0;
            var hideInput = null;
            var hideInputArray = [];

            thisFlightTypeInput.input = $('#' + this.flightTypeId);
            for (hideInputIndex = 0; hideInputIndex < this.hideInputIdArray.length; hideInputIndex += 1)
            {
                hideInput = thisFlightTypeInput.getById(this.hideInputIdArray[hideInputIndex]);
                if (hideInput)
                {
                    hideInputArray[hideInputArray.length] = hideInput;
                }
            }
            thisFlightTypeInput.hideInputArray = $(hideInputArray);
        };
        
        thisFlightTypeInput.init = function (json)
        {
            this.setSettingsByObject(json);
            this.setVars();
            this.addEvents();
        };
        return thisFlightTypeInput;
    };
}

/*
    Name: 
        Class MarketInput
    Param:
        None
    Return: 
        An instance of MarketInput
    Functionality:
         Handels the functionality of the markets on the AvailabilitySearchInput control
    Notes:
        Markets are a link between stations. 
        When you select an orgin station only the valid destionation stations should be available for selection.
    Class Hierarchy:
        SkySales -> MarketInput
*/
if (!SKYSALES.Class.MarketInput)
{
    SKYSALES.Class.MarketInput = function ()
    {
        var marketInputBase = new SKYSALES.Class.SkySales();
        var thisMarketInput = SKYSALES.Util.extendObject(marketInputBase);
        
        thisMarketInput.marketHash = SKYSALES.Util.getResource().marketHash;
        thisMarketInput.stationHash = SKYSALES.Util.getResource().stationHash;
        
        thisMarketInput.containerId = '';
        thisMarketInput.container = null;
        thisMarketInput.disableInputId = '';
        thisMarketInput.disableInput = null;
        thisMarketInput.originId = '';
        thisMarketInput.origin = null;
        thisMarketInput.destinationId = '';
        thisMarketInput.destination = null;
        thisMarketInput.toggleMarketCount = 0;
        
        thisMarketInput.toggleMarket = function ()
        {
            if ((thisMarketInput.toggleMarketCount % 2) === 0)
            {
                $(':input', thisMarketInput.container).attr('disabled', 'disabled');
            }
            else
            {
                $(':input', thisMarketInput.container).removeAttr('disabled');
            }
            thisMarketInput.toggleMarketCount += 1;
        };
        
        thisMarketInput.useComboBox = function (input)
        {
            var retVal = true;
            if (input && input.get(0) && input.get(0).options)
            {
                retVal = false;
            }
            return retVal;
        };
        
        thisMarketInput.updateMarketOrigin = function ()
        {
            var origin = $(this).val();
            origin = origin.toUpperCase();
            var destinationArray = thisMarketInput.marketHash[origin];
            destinationArray = destinationArray || [];
			
			//Idtgv modification start
			//enable sorting
            destinationArray.sort(function(a, b) 
                { 
                    if (a.name === b.name)   { return 0;}                  
                    if (a.name < b.name) { return -1;}
                    return 1;
                        
                });
                
            //Idtgv modification end
            
            var selectParamObj = null;
            var useCombo = true;

            useCombo = thisMarketInput.useComboBox(thisMarketInput.destination);
            if (useCombo)
            {
                selectParamObj = {
                    'input': thisMarketInput.destination,
                    'options': destinationArray
                };
                SKYSALES.Class.DropDown.getDropDown(selectParamObj);
            }
            else
            {
                /*iDTGV fix*/
                selectParamObj = {
                    'selectBox': thisMarketInput.destination,
                    'objectArray': destinationArray,
                    'selectedItem':thisMarketInput.destination.val()
                };
                SKYSALES.Util.populateSelect(selectParamObj);
            }
        };
        
        thisMarketInput.addEvents = function ()
        {
            thisMarketInput.origin.change(thisMarketInput.updateMarketOrigin);
            thisMarketInput.disableInput.click(thisMarketInput.toggleMarket);
        };
        
        thisMarketInput.setVars = function ()
        {
            thisMarketInput.container = $('#' + thisMarketInput.containerId);
            thisMarketInput.disableInput = $('#' + thisMarketInput.disableInputId);
            thisMarketInput.origin = $('#' + thisMarketInput.originId);
            thisMarketInput.destination = $('#' + thisMarketInput.destinationId);
        };
        
        thisMarketInput.populateMarketInput = function (input)
        {
            var useCombo = true;
            var selectParamObj = {};
            if ((input) && (input.length > 0))
            {
                useCombo = thisMarketInput.useComboBox(input);
                if (useCombo)
                {
                    selectParamObj = {
                        'input': input,
                        'options': thisMarketInput.stationHash
                    };
                    SKYSALES.Class.DropDown.getDropDown(selectParamObj);
                }
                else
                {
                    /*Idtgv FIX*/                                    
                    selectParamObj = {
                        'selectBox':  input,
                        'objectArray': thisMarketInput.stationHash,
                        'selectedItem': input.val()
                    };
                    SKYSALES.Util.populateSelect(selectParamObj);
                }
            }
        };
        
        thisMarketInput.init = function (paramObject)
        {
            marketInputBase.init.call(this, paramObject);
            this.addEvents();
            
            thisMarketInput.populateMarketInput(thisMarketInput.origin);
            thisMarketInput.populateMarketInput(thisMarketInput.destination);
            
            thisMarketInput.disableInput.click();
            thisMarketInput.disableInput.removeAttr('checked');
        };
        return thisMarketInput;
    };
}


/*
    Name: 
        Class StationInput
    Param:
        None
    Return: 
        An instance of StationInput
    Functionality:
         Handels the functionality of the stations on the AvailabilitySearchInput control
    Notes:
        StationInput is the html form element where you type the orgin or destination station
    Class Hierarchy:
        SkySales -> StationInput
*/
if (!SKYSALES.Class.StationInput)
{
    SKYSALES.Class.StationInput = function ()
    {
        var parent = new SKYSALES.Class.SkySales();
        var thisStationInput = SKYSALES.Util.extendObject(parent);
        
        thisStationInput.stationInputId = '';
        thisStationInput.stationInput = null;
        
        thisStationInput.setVars = function ()
        {
            parent.setVars.call(this);
            thisStationInput.stationInput = $('#' + this.stationInputId);
        };
        
        thisStationInput.init = function (json)
        {
            parent.init.call(this, json);
            this.addEvents();
        };
        return thisStationInput;
    };
}

/*
    Name: 
        Class StationDropDown
    Param:
        None
    Return: 
        An instance of StationDropDown
    Functionality:
         Handels the functionality of the stations on the AvailabilitySearchInput control
    Notes:
        StationDropDown is the html form element where you select the orgin or destination station
    Class Hierarchy:
        SkySales -> StationDropDown
*/
if (!SKYSALES.Class.StationDropDown)
{
    SKYSALES.Class.StationDropDown = function ()
    {
        var stationDropDownBase = new SKYSALES.Class.SkySales();
        var thisStationDropDown = SKYSALES.Util.extendObject(stationDropDownBase);
        
        thisStationDropDown.selectBoxId = '';
        thisStationDropDown.selectBox = null;
        thisStationDropDown.inputId = '';
        thisStationDropDown.input = null;
        
        thisStationDropDown.updateStationDropDown = function ()
        {
            var stationCode = $(this).val();
            thisStationDropDown.selectBox.val(stationCode);
        };
        
        thisStationDropDown.updateStationInput = function ()
        {
            var stationCode = $(this).val();
            thisStationDropDown.input.val(stationCode);
            thisStationDropDown.input.change();
        };
        
        thisStationDropDown.addEvents = function ()
        {
            thisStationDropDown.input.change(thisStationDropDown.updateStationDropDown);
            thisStationDropDown.selectBox.change(thisStationDropDown.updateStationInput);
        };
        
        thisStationDropDown.setVars = function ()
        {
            thisStationDropDown.selectBox = $('#' + thisStationDropDown.selectBoxId);
            thisStationDropDown.input = $('#' + thisStationDropDown.inputId);
        };
        
        thisStationDropDown.init = function (paramObject)
        {
            stationDropDownBase.init.call(this, paramObject);
            this.addEvents();
            thisStationDropDown.input.change();
        };
        return thisStationDropDown;
    };
}

/* 
    Name: 
        Class TravelDocumentInput
    Param:
        None
    Return: 
        An instance of TravelDocumentInput
     Functionality:
        The object that sets the travel document information of the TravelDocumentInput control for registration
    Notes:
        
    Class Hierarchy:
        SkySales -> TravelDocumentInput
*/
if (!SKYSALES.Class.TravelDocumentInput)
{
	SKYSALES.Class.TravelDocumentInput = function ()
	{
	    var parent = new SKYSALES.Class.SkySales();
        var thisTravelDocumentInput = SKYSALES.Util.extendObject(parent);

        thisTravelDocumentInput.travelDocumentInfoId = '';
        thisTravelDocumentInput.travelDocumentInfo = null;
        thisTravelDocumentInput.delimiter = '_';
        thisTravelDocumentInput.documentTypeId = '';
        thisTravelDocumentInput.documentType = null;
        thisTravelDocumentInput.documentNumberId = '';
        thisTravelDocumentInput.documentNumber = null;
        thisTravelDocumentInput.documentIssuingCountryId = '';
        thisTravelDocumentInput.documentIssuingCountry = null;
        thisTravelDocumentInput.documentCountryOfBirthId = '';
        thisTravelDocumentInput.documentCountryOfBirth = null;
        
        thisTravelDocumentInput.travelDocumentKey = '';
        
        thisTravelDocumentInput.init = function (json)
        {
            this.setSettingsByObject(json);
            this.setVars();
            this.addEvents();
        };

        thisTravelDocumentInput.setVars = function ()
        {
            parent.setVars.call(this);
            thisTravelDocumentInput.travelDocumentInfo = $('#' + this.travelDocumentInfoId);
            thisTravelDocumentInput.documentType = $('#' + this.documentTypeId);
            thisTravelDocumentInput.documentNumber = $('#' + this.documentNumberId);
            thisTravelDocumentInput.documentIssuingCountry = $('#' + this.documentIssuingCountryId);
            thisTravelDocumentInput.documentCountryOfBirth = $('#' + this.documentCountryOfBirthId);
        };
        
        thisTravelDocumentInput.setTravelDocumentInfo = function ()
        {
            var travelDocumentKey = '';
            var documentType = this.documentType.val();
            var documentNumber = this.documentNumber.val();
            var documentIssuingCountry = this.documentIssuingCountry.val();
            var documentCountryOfBirth = this.documentCountryOfBirth.val();
            
            if (documentType && documentNumber && documentIssuingCountry && documentCountryOfBirth)
            {
                travelDocumentKey = documentType + this.delimiter + documentNumber + this.delimiter + documentIssuingCountry + this.delimiter + documentCountryOfBirth;
                this.travelDocumentInfo.val(travelDocumentKey);
            }
            return true;
        };
	    return thisTravelDocumentInput;
    };
}

/*
    Name: 
        Class ControlGroup
    Param:
        None
    Return: 
        An instance of ControlGroup
    Functionality:
        Handels a ControlGroup validation
    Notes:
        
    Class Hierarchy:
        SkySales -> ControlGroup
*/
if (!SKYSALES.Class.ControlGroup)
{
    SKYSALES.Class.ControlGroup = function ()
    {   
        var parent = new SKYSALES.Class.SkySales();
        var thisControlGroup = SKYSALES.Util.extendObject(parent);
        
        thisControlGroup.actionId = 'SkySales';
        thisControlGroup.action = null;
        
        thisControlGroup.init = function (json)
        {
            this.setSettingsByObject(json);
            this.setVars();
            this.addEvents();
        };
        thisControlGroup.setVars = function ()
        {
            parent.setVars.call(this);
            thisControlGroup.action = $('#' + this.actionId);
        };
        thisControlGroup.addEvents = function ()
        {
            parent.addEvents.call(this);
            this.action.click(this.validateHandler);
        };
        thisControlGroup.validateHandler = function ()
        {
            var retVal = thisControlGroup.validate();
            return retVal;
        };
        thisControlGroup.validate = function ()
        {
            var actionDom = this.action.get(0);
            var retVal = window.validate(actionDom);
            return retVal;
        };
        return thisControlGroup;
    };
    SKYSALES.Class.ControlGroup.createObject = function (json)
    {
        SKYSALES.Util.createObject('controlGroup', 'ControlGroup', json);
    };
}

/*
    Name: 
        Class ControlGroup
    Param:
        None
    Return: 
        An instance of ControlGroup
    Functionality:
        Handels a ControlGroup validation
    Notes:
        
    Class Hierarchy:
        SkySales -> ControlGroup
*/
if (!SKYSALES.Class.ControlGroupRegister)
{
    SKYSALES.Class.ControlGroupRegister = function ()
    {   
        var parent = new SKYSALES.Class.ControlGroup();
        var thisControlGroupRegister = SKYSALES.Util.extendObject(parent);
        
        thisControlGroupRegister.travelDocumentInput = null;
        
        thisControlGroupRegister.setSettingsByObject = function (json)
        {
            parent.setSettingsByObject.call(this, json);
            var travelDocumentInput = new SKYSALES.Class.TravelDocumentInput();
            travelDocumentInput.init(this.travelDocumentInput);
            thisControlGroupRegister.travelDocumentInput = travelDocumentInput;
        };
        thisControlGroupRegister.validateHandler = function ()
        {
            var retVal = thisControlGroupRegister.validate();
            return retVal;
        };
        thisControlGroupRegister.validate = function ()
        {
            var retVal = false;
            retVal = this.travelDocumentInput.setTravelDocumentInfo();
            if (retVal)
            {
                retVal = parent.validate.call(this);
            }
            return retVal;
        };
        return thisControlGroupRegister;
    };
    SKYSALES.Class.ControlGroupRegister.createObject = function (json)
    {
        SKYSALES.Util.createObject('controlGroupRegister', 'ControlGroupRegister', json);
    };
}


/*
    Name: 
        Class ContactInput
    Param:
        None
    Return: 
        An instance of ContactInput
    Functionality:
        Handels the ContactInput control
    Notes:
        Auto populates from the clientHash cookie
        when you enter in a name that matches the one on the cookie.
    Class Hierarchy:
        SkySales -> ContactInput
*/
if (!SKYSALES.Class.ContactInput)
{
    SKYSALES.Class.ContactInput = function ()
    {   
        var contactInput = new SKYSALES.Class.SkySales();
        var thisContactInput = SKYSALES.Util.extendObject(contactInput);
        
        thisContactInput.clientId = '';
        thisContactInput.keyIdArray = [];
        thisContactInput.keyArray = [];
        thisContactInput.clientStoreIdHash = null;
        thisContactInput.countryInputId = '';
        thisContactInput.countryInput = null;
        thisContactInput.stateInputId = '';
        thisContactInput.stateInput = null;
        thisContactInput.countryStateHash = null;
        thisContactInput.imContactId = '';
        thisContactInput.imContact = null;
        thisContactInput.currentContactData = {};
        thisContactInput.logOutButton = null;
        
        thisContactInput.clientHash = SKYSALES.Util.getResource().clientHash;
        
         thisContactInput.setSettingsByObject = function (jsonObject)
        {
            contactInput.setSettingsByObject.call(this, jsonObject);
            var propName = '';
            for (propName in jsonObject)
            {
                if (thisContactInput.hasOwnProperty(propName))
                {
                    thisContactInput[propName] = jsonObject[propName];
                }
            }
        };
        
        thisContactInput.clearCurrentContact = function()
        {
             $("#" + thisContactInput.clientId + "_DropDownListTitle").val("");
                    $("#" + thisContactInput.clientId + "_TextBoxFirstName").val("");
                    $("#" + thisContactInput.clientId + "_TextBoxMiddleName").val("");
                    $("#" + thisContactInput.clientId + "_TextBoxLastName").val("");
                    $("#" + thisContactInput.clientId + "_TextBoxAddressLine1").val("");
                    $("#" + thisContactInput.clientId + "_TextBoxAddressLine2").val("");
                    $("#" + thisContactInput.clientId + "_TextBoxAddressLine3").val("");
                    $("#" + thisContactInput.clientId + "_TextBoxCity").val("");
                    $("#" + thisContactInput.clientId + "_DropDownListStateProvince").val("");
                    $("#" + thisContactInput.clientId + "_DropDownListCountry").val("");
                    $("#" + thisContactInput.clientId + "_TextBoxPostalCode").val("");
                    $("#" + thisContactInput.clientId + "_TextBoxHomePhone").val("");
                    $("#" + thisContactInput.clientId + "_TextBoxWorkPhone").val("");
                    $("#" + thisContactInput.clientId + "_TextBoxOtherPhone").val("");
                    $("#" + thisContactInput.clientId + "_TextBoxFax").val("");
                    $("#" + thisContactInput.clientId + "_TextBoxEmailAddress").val("");
        };
        
        thisContactInput.populateCurrentContact = function()
        {
            if (thisContactInput.currentContactData)
            {
                if (thisContactInput.imContact.attr("checked") === true)
                {
                    $("#" + thisContactInput.clientId + "_DropDownListTitle").val(thisContactInput.currentContactData.title);
                    $("#" + thisContactInput.clientId + "_TextBoxFirstName").val(thisContactInput.currentContactData.firstName);
                    $("#" + thisContactInput.clientId + "_TextBoxMiddleName").val(thisContactInput.currentContactData.middleName);
                    $("#" + thisContactInput.clientId + "_TextBoxLastName").val(thisContactInput.currentContactData.lastName);
                    $("#" + thisContactInput.clientId + "_TextBoxAddressLine1").val(thisContactInput.currentContactData.streetAddressOne);
                    $("#" + thisContactInput.clientId + "_TextBoxAddressLine2").val(thisContactInput.currentContactData.streetAddressTwo);
                    $("#" + thisContactInput.clientId + "_TextBoxAddressLine3").val(thisContactInput.currentContactData.streetAddressThree);
                    $("#" + thisContactInput.clientId + "_TextBoxCity").val(thisContactInput.currentContactData.city);
                    $("#" + thisContactInput.clientId + "_DropDownListStateProvince").val(thisContactInput.currentContactData.stateProvince);
                    $("#" + thisContactInput.clientId + "_DropDownListCountry").val(thisContactInput.currentContactData.country);
                    $("#" + thisContactInput.clientId + "_TextBoxPostalCode").val(thisContactInput.currentContactData.postalCode);
                    $("#" + thisContactInput.clientId + "_TextBoxHomePhone").val(thisContactInput.currentContactData.eveningPhone);
                    $("#" + thisContactInput.clientId + "_TextBoxWorkPhone").val(thisContactInput.currentContactData.dayPhone);
                    $("#" + thisContactInput.clientId + "_TextBoxOtherPhone").val(thisContactInput.currentContactData.mobilePhone);
                    $("#" + thisContactInput.clientId + "_TextBoxFax").val(thisContactInput.currentContactData.faxPhone);
                    $("#" + thisContactInput.clientId + "_TextBoxEmailAddress").val(thisContactInput.currentContactData.email);
                }
                else
                {
                    thisContactInput.clearCurrentContact();
                }
            }
        };
        
        thisContactInput.populateCountryStateHash = function ()
        {
            var i = 0;
            var selectBox = thisContactInput.stateInput.get(0);
            var country = '';
            var stateArray = [];
            var countryStateArray = [];
            var option = null;
            var state = '';
            var stateName = '';
            var stateObject = {};
            var countryStateHash = {};
            if (selectBox && selectBox.options)
            {
                thisContactInput.countryStateHash = {};
                countryStateHash.customStates = [];
                countryStateHash.allStates = [];
                for (i = 0; i < selectBox.options.length; i += 1)
                {
                    option = selectBox.options[i];
                    state = option.value;
                    stateName = option.text;
                    stateObject = { 
                        'name': stateName,
                        'code': state
                    };
                    countryStateArray = option.value.split('|');
                    if (countryStateArray.length === 2)
                    {
                        country = countryStateArray[0];
                        stateArray = countryStateHash[country];
                        stateArray = stateArray || [];
                        stateArray[stateArray.length] = stateObject;
                        countryStateHash[country] = stateArray;
                        
                        countryStateHash.allStates[countryStateHash.allStates.length] = stateObject;
                    }
                    else
                    {
                        countryStateHash.customStates[countryStateHash.customStates.length] = stateObject;
                    }
                }
                thisContactInput.countryStateHash = countryStateHash;
            }
        };
        
        thisContactInput.updateCountry = function ()
        {
            var countryState = thisContactInput.stateInput.val();
            var countryStateArray = countryState.split('|');
            var country = '';
            if (countryStateArray.length === 2)
            {
                country = countryStateArray[0];
                thisContactInput.countryInput.val(country);
            }
        };
        
        thisContactInput.updateState = function ()
        {
            var country = thisContactInput.countryInput.val();
            var stateArray = [];
            var stateObject = {};
            var stateObjectArray = [];
            var i = 0;
            if (!thisContactInput.countryStateHash)
            {
                thisContactInput.populateCountryStateHash();
            }
            stateArray = thisContactInput.countryStateHash[country];
            stateArray = stateArray || [];
            if (stateArray.length === 0)
            {
                stateArray = thisContactInput.countryStateHash.allStates;
            }
            for (i = 0; i < thisContactInput.countryStateHash.customStates.length; i += 1)
            {
                stateObject = thisContactInput.countryStateHash.customStates[i];
                stateObjectArray[stateObjectArray.length] = stateObject;
            }
            for (i = 0; i < stateArray.length; i += 1)
            {
                stateObject = stateArray[i];
                stateObjectArray[stateObjectArray.length] = stateObject;
            }
            var paramObject = {
                    'objectArray': stateObjectArray,
                    'selectBox': thisContactInput.stateInput,
                    'showCode': false,
                    'clearOptions': true
                };
            SKYSALES.Util.populateSelect(paramObject);
        };
        
        thisContactInput.getKey = function ()
        {
            var i = 0;
            var keyArray = thisContactInput.keyArray;
            var keyObject = null;
            var key = '';
            for (i = 0; i < keyArray.length; i += 1)
            {
                keyObject = keyArray[i];
                key += keyObject.val();
            }
            key = thisContactInput.clientId + '_' + key;
            return key;
        };
        
        thisContactInput.populateClientStoreIdHash = function ()
        {
            var clientHash = thisContactInput.clientHash;
            var i = 0;
            var keyValueStr = '';
            var keyValueArray = [];
            var singleKeyValueStr = '';
            var eqIndex = -1;
            var key = thisContactInput.getKey();
            var value = null;
            thisContactInput.clientStoreIdHash = {};
            if (key && clientHash && clientHash[key])
            {
                thisContactInput.clientStoreIdHash = thisContactInput.clientStoreIdHash || {};
                keyValueStr = clientHash[key];
                keyValueArray = keyValueStr.split('&');
                for (i = 0; i < keyValueArray.length; i += 1)
                {
                    singleKeyValueStr = keyValueArray[i];
                    eqIndex = singleKeyValueStr.indexOf('=');
                    if (eqIndex > -1)
                    {
                        key = singleKeyValueStr.substring(0, eqIndex);
                        value = singleKeyValueStr.substring(eqIndex + 1, singleKeyValueStr.length);
                        if (key)
                        {
                            thisContactInput.clientStoreIdHash[key] = value;
                        }
                    }
                }
            }
        };
        
        thisContactInput.autoPopulateForm = function ()
        {
            thisContactInput.populateClientStoreIdHash();
            var clientStoreIdHash = thisContactInput.clientStoreIdHash;
            var key = '';
            var value = '';
            for (key in clientStoreIdHash)
            {
                if (clientStoreIdHash.hasOwnProperty(key))
                {
                    value = clientStoreIdHash[key];
                    $('#' + key).val(value);
                }
            }
        };
        
        thisContactInput.addEvents = function ()
        {
            contactInput.addEvents.call(this);
            var i = 0;
            var keyArray = thisContactInput.keyArray;
            var key = null;
            for (i = 0; i < keyArray.length; i += 1)
            {
                key = keyArray[i];
                key.change(thisContactInput.autoPopulateForm);
            }
            thisContactInput.countryInput.change(thisContactInput.updateState);
            thisContactInput.stateInput.change(thisContactInput.updateCountry);
        };
        
        thisContactInput.setVars = function ()
        {
            contactInput.setVars.call(this);
            var i = 0;
            var keyIdArray = thisContactInput.keyIdArray;
            var keyArray = thisContactInput.keyArray;
            var keyId = '';
            for (i = 0; i < keyIdArray.length; i += 1)
            {
                keyId = keyIdArray[i];
                keyArray[keyArray.length] = $('#' + keyId);
            }
            thisContactInput.countryInput = $('#' + thisContactInput.countryInputId);
            thisContactInput.stateInput = $('#' + thisContactInput.stateInputId);
            thisContactInput.imContact = $('#' + thisContactInput.imContactId);
            thisContactInput.logOutButton = $('#MemberLoginContactView_ButtonLogOut');

        };
        
        thisContactInput.init = function (paramObj)
        {
            this.setSettingsByObject(paramObj);
            this.setVars();
            this.addEvents();
        };
        return thisContactInput;
    };
    SKYSALES.Class.ContactInput.createObject = function (json)
    {
        SKYSALES.Util.createObject('contactInput', 'ContactInput', json);
    };
}

/*
    Name: 
        Class ToggleView
    Param:
        None
    Return: 
        An instance of ToggleView
    Functionality:
        The ToggleView class is used to show and hide dom elements.
    Notes:
        It is set up so that you can click different elements to show and hide the dom object.
        You can have a link that you click to show the element, and anothe that you click to hide it.
        showId is the id of the html element that you click to show the element
        hideId is the id of the html element that you click to hide the element
        elementId is the id of the element you are showing and hiding
    Class Hierarchy:
        SkySales -> ToggleView
*/
if (!SKYSALES.Class.ToggleView)
{
    SKYSALES.Class.ToggleView = function ()
    {
        var toggleView = new SKYSALES.Class.SkySales();
        var thisToggleView = SKYSALES.Util.extendObject(toggleView);
        
        thisToggleView.showId = '';
        thisToggleView.hideId = '';
        thisToggleView.elementId = '';
        
        thisToggleView.show = null;
        thisToggleView.hide = null;
        thisToggleView.element = null;
        
        thisToggleView.setVars = function ()
        {
            toggleView.setVars.call(this);
            thisToggleView.show = $('#' + thisToggleView.showId);
            thisToggleView.hide = $('#' + thisToggleView.hideId);
            thisToggleView.element = $('#' + thisToggleView.elementId);
        };
        
        thisToggleView.init = function (paramObj)
        {
            this.setSettingsByObject(paramObj);
            this.setVars();
            this.addEvents();
        };
        
        thisToggleView.updateShowHandler = function ()
        {
            thisToggleView.element.show('slow');
        };
        
        thisToggleView.updateHideHandler = function ()
        {
            thisToggleView.element.hide();
        };
        
        thisToggleView.addEvents = function ()
        {
            toggleView.addEvents.call(this);
            thisToggleView.show.click(thisToggleView.updateShowHandler);
            thisToggleView.hide.click(thisToggleView.updateHideHandler);
        };
        return thisToggleView;
    };
}

/*
    Name: 
        Class PriceDisplay
    Param:
        None
    Return: 
        An instance of PriceDisplay
    Functionality:
        Handels the PriceDisplay control
    Notes:
        All functionality is inherited from the SkySales Class
    Class Hierarchy:
        SkySales -> PriceDisplay
*/
if (!SKYSALES.Class.PriceDisplay)
{
    SKYSALES.Class.PriceDisplay = function ()
    {   
        var parent = new SKYSALES.Class.SkySales();
        var thisPriceDisplay = SKYSALES.Util.extendObject(parent);
        
        thisPriceDisplay.toggleViewIdArray = null;
        
        thisPriceDisplay.init = function (json)
        {
            this.setSettingsByObject(json);
            
            var toggleViewIdArray = this.toggleViewIdArray || [];
            var i = 0;
            var toggleView = null;
            for (i = 0; i < toggleViewIdArray.length; i += 1)
            {
                toggleView = new SKYSALES.Class.ToggleView();
                toggleView.init(toggleViewIdArray[i]);
                thisPriceDisplay.toggleViewIdArray[i] = toggleView;
            }
        };
        return thisPriceDisplay;
    };
    SKYSALES.Class.PriceDisplay.createObject = function (json)
    {
        SKYSALES.Util.createObject('priceDisplay', 'PriceDisplay', json);
    };
}

/*
    Name: 
        Class FlightDisplay
    Param:
        None
    Return: 
        An instance of FlightDisplay
    Functionality:
        Handels the FlightDisplay control
    Notes:
        All functionality is inherited from the SkySales Class
    Class Hierarchy:
        SkySales -> FlightDisplay
*/
if (!SKYSALES.Class.FlightDisplay)
{
    SKYSALES.Class.FlightDisplay = function ()
    {   
        var parent = new SKYSALES.Class.SkySales();
        var thisFlightDisplay = SKYSALES.Util.extendObject(parent);
        
        thisFlightDisplay.toggleViewIdArray = null;
        
        thisFlightDisplay.init = function (json)
        {
            this.setSettingsByObject(json);
            
            var toggleViewIdArray = this.toggleViewIdArray || [];
            var i = 0;
            var toggleView = null;
            for (i = 0; i < toggleViewIdArray.length; i += 1)
            {
                toggleView = new SKYSALES.Class.ToggleView();
                toggleView.init(toggleViewIdArray[i]);
                thisFlightDisplay.toggleViewIdArray[i] = toggleView;
            }
        };
        return thisFlightDisplay;
    };
    SKYSALES.Class.FlightDisplay.createObject = function (json)
    {
        SKYSALES.Util.createObject('flightDisplay', 'FlightDisplay', json);
    };
}

/*
    Name: 
        Class RandomImage
    Param:
        None
    Return: 
        An instance of RandomImage
    Functionality:
        Handels the RandomImage on the search view
    Notes:
        This class can be used to display a random image,
        provided it has a list of uri that point to images,
        and a dom node to place the image.
    Class Hierarchy:
        SkySales -> RandomImage
*/
if (!SKYSALES.Class.RandomImage)
{
    SKYSALES.Class.RandomImage = function ()
    {   
        var parent = new SKYSALES.Class.SkySales();
        var thisRandomImage = SKYSALES.Util.extendObject(parent);
        
        thisRandomImage.imageUriArray = [];
        
        thisRandomImage.init = function (json)
        {
            this.setSettingsByObject(json);
            this.setVars();
            this.setAsBackground();
        };
        
        thisRandomImage.getRandomNumber = function ()
        {
            var randomNumberMax = this.imageUriArray.length;
            var randomNumber = Math.floor(Math.random() * randomNumberMax);
            return randomNumber;
        };
        
        thisRandomImage.setAsBackground = function ()
        {
            var randomNumber = this.getRandomNumber();
            var uri = 'url(' + this.imageUriArray[randomNumber] + ')';
            this.container.css('background-image', uri);
        };
        return thisRandomImage;
    };
    SKYSALES.Class.RandomImage.createObject = function (json)
    {
        SKYSALES.Util.createObject('randomImage', 'RandomImage', json);
    };
}

/*
    Name: 
        Class DropDown
    Param:
        None
    Return: 
        An instance of DropDown
    Functionality:
        The DropDown class is a combo box.
    Notes:
        Provided with an input box, and an array of objects that have a code and name property
        it will turn the text box into a combo box that attemps to help you auto complete what you are typing
        given the data provided.
        The way to turn an input box into a combo box is
        var selectParamObj = {
                    'input': $(inputBox),
                    'options': [ { "code": "", "name": name } ]
         };
         SKYSALES.Class.DropDown.getDropDown(selectParamObj);
    Class Hierarchy:
        DropDown
*/
SKYSALES.Class.DropDown = function (paramObject)
{
    paramObject = paramObject || {};
    var thisDrop = this;
    
    thisDrop.container = {};
    thisDrop.name = '';
    thisDrop.options = [];
    thisDrop.dropDownContainer = null;
    thisDrop.dropDownContainerInput = null;
    thisDrop.document = null;
    thisDrop.optionList = null;
    thisDrop.optionActiveClass = 'optionActive';
    thisDrop.timeOutObj = null;
    thisDrop.timeOut = 225;
    thisDrop.minCharLength = 2;
    thisDrop.optionMax = 100;
    thisDrop.html = '<div></div><div class="dropDownContainer"></div>';
    thisDrop.autoComplete = true;
    
    thisDrop.setSettingsByObject = function (jsonObject)
    {
        var prop = null;
        for (prop in jsonObject)
        {
            if (thisDrop.hasOwnProperty(prop))
            {
                thisDrop[prop] = jsonObject[prop];
            }
        }
    };
    
    thisDrop.getOptionHtml = function (search)
    {
        search = search || '';
        var option = {};
        var prop = '';
        var optionHtml = '';
        var optionCount = 0;
        var optionHash = thisDrop.options;
        var re = new RegExp('^' + search, 'i');
        if (search.length < thisDrop.minCharLength)
        {
            optionHtml = '';
        }
        else
        {
            for (prop in optionHash)
            {
                if (optionHash.hasOwnProperty(prop))
                {
                    option = optionHash[prop];
                    option.name = option.name || '';
                    option.code = option.code || '';
                    if (option.name.match(re) || option.code.match(re))
                    {
                        optionHtml += '<div><span>' + option.code + '</span>' + option.name + ' (' + option.code + ')' + '</div>';
                        optionCount += 1;
                    }
                    if (optionCount >= thisDrop.optionMax)
                    {
                        break;
                    }
                }
            }
        }
        return optionHtml;
    };
    
    thisDrop.close = function ()
    {
        if (thisDrop.timeOutObj)
        {
            window.clearTimeout(thisDrop.timeOutObj);
        }
        thisDrop.document.unbind('click', thisDrop.close);
        if (thisDrop.optionList)
        {
            thisDrop.optionList.unbind('hover');
            thisDrop.optionList.unbind('click');
        }
        thisDrop.optionList = null;
        thisDrop.dropDownContainer.html('');
    };
    
    
    thisDrop.getActiveOptionIndex = function ()
    {
        var activeOptionIndex = -1;
        var activeOption = $('.' + thisDrop.optionActiveClass, thisDrop.dropDownContainer);
        if (thisDrop.optionList && (activeOption.length > 0))
        {
            activeOptionIndex = thisDrop.optionList.index(activeOption[0]);
        }
        return activeOptionIndex;
    };
    
    thisDrop.arrowDown = function ()
    {
        var activeOptionIndex = thisDrop.getActiveOptionIndex();
        if (thisDrop.optionList)
        {
            if ((activeOptionIndex === -1) && (thisDrop.optionList.length > 0))
            {
                thisDrop.optionActive.call(thisDrop.optionList[0]);
            }
            else if (thisDrop.optionList.length > activeOptionIndex + 1)
            {
                thisDrop.optionInActive.call(thisDrop.optionList[activeOptionIndex]);
                thisDrop.optionActive.call(thisDrop.optionList[activeOptionIndex + 1]);
            }
            else
            {
                thisDrop.arrowDownOpen();
            }
        }
        else
        {
            thisDrop.arrowDownOpen();
        }
    };
    
    thisDrop.arrowDownOpen = function ()
    {
        var oldMinCharLength = thisDrop.minCharLength;
        thisDrop.minCharLength = 0;
        thisDrop.open();
        thisDrop.minCharLength = oldMinCharLength;
    };
    
    thisDrop.arrowUp = function ()
    {
        var activeOptionIndex = thisDrop.getActiveOptionIndex();
        if (thisDrop.optionList)
        {
            if ((activeOptionIndex === -1) && (thisDrop.optionList.length > 0))
            {
                thisDrop.optionActive.call(thisDrop.optionList[0]);
            }
            else if ((activeOptionIndex > 0) && (thisDrop.optionList.length > 0))
            {
                thisDrop.optionInActive.call(thisDrop.optionList[activeOptionIndex]);
                thisDrop.optionActive.call(thisDrop.optionList[activeOptionIndex - 1]);       
            }
        }
    };
    
    thisDrop.selectButton = function ()
    {
        var activeOptionIndex = thisDrop.getActiveOptionIndex();
        var oldOptionMax = thisDrop.optionMax;
        if (activeOptionIndex > -1)
        {
            thisDrop.selectOption.call(thisDrop.optionList[activeOptionIndex]);
        }
        else if (thisDrop.autoComplete === true)
        {
            thisDrop.optionMax = 1;
            thisDrop.open();
            if (thisDrop.optionList && (thisDrop.optionList.length > 0))
            {
                thisDrop.selectOption.call(thisDrop.optionList[0]);
            }
            thisDrop.optionMax = oldOptionMax;
        }
    };
    
    /*
        40: down arrow
        38: up arrow
        32: space
        9: tab
        13: enter
    */
    
    thisDrop.keyEvent = function (key)
    {
        var retVal = true;
        var keyNum = key.which;
        if (keyNum === 40)
        {
            thisDrop.arrowDown();
            thisDrop.autoComplete = true;
            retVal = false;
        }
        else if (keyNum === 38)
        {
            thisDrop.arrowUp();
            thisDrop.autoComplete = true;
            retVal = false;
        }
        else if (keyNum === 9)
        {
            thisDrop.selectButton();
            thisDrop.inputBlur();
        }
        else if (keyNum === 13)
        {
            thisDrop.selectButton();
            thisDrop.autoComplete = false;
            retVal = false;
        }
        else
        {
            thisDrop.autoComplete = true;
        }
        return retVal;
    };
    
    thisDrop.inputKeyEvent = function (key)
    {
        var retVal = true;
        var keyNum = key.which;
        if ((keyNum !== 40) && (keyNum !== 38) && (keyNum !== 9) && (keyNum !== 13))
        {
            if (thisDrop.timeOutObj)
            {
                window.clearTimeout(thisDrop.timeOutObj);
            }
            thisDrop.timeOutObj = window.setTimeout(thisDrop.open, thisDrop.timeOut);
            retVal = false;
        }
        return retVal;
    };
    
    thisDrop.catchEvent = function ()
    {
        return false;
    };
    
    thisDrop.open = function ()
    {
        var iframeHtml = '';
        var iframe = null;
        var search = thisDrop.dropDownContainerInput.val();
        var optionHtml = thisDrop.getOptionHtml(search);
        var height = 0;
        var containerWidth = 0;
        thisDrop.dropDownContainer.html(optionHtml);
        thisDrop.addOptionEvents();
        thisDrop.dropDownContainer.click(thisDrop.catchEvent);
        thisDrop.document.click(thisDrop.close);
        
        thisDrop.dropDownContainer.show();
        if (thisDrop.optionList && (thisDrop.optionList.length > 0) && thisDrop.optionActive)
        {
            thisDrop.optionActive.call(thisDrop.optionList[0]);
        }
        containerWidth = thisDrop.dropDownContainer.width();
        
        if ($.browser.msie)
        {
            height = thisDrop.dropDownContainer.height();
            iframeHtml = '<iframe src="#"></iframe>';
            thisDrop.dropDownContainer.prepend(iframeHtml);
            iframe = $('iframe', thisDrop.dropDownContainer);
            iframe.width(containerWidth);
            iframe.height(height);
        }
    };
    
    thisDrop.optionActive = function ()
    {
        var option = $(this);
        thisDrop.optionList.removeClass(thisDrop.optionActiveClass);
        option.addClass(thisDrop.optionActiveClass);
    };
    
    thisDrop.optionInActive = function ()
    {
        var option = $(this);
        option.removeClass(thisDrop.optionActiveClass);
    };
    
    thisDrop.selectOption = function ()
    {
        var text = $('span', this).text();
        thisDrop.dropDownContainerInput.val(text);
        thisDrop.close();
        thisDrop.dropDownContainerInput.change();
    };
    
    thisDrop.addOptionEvents = function ()
    {
        thisDrop.optionList = $('div', thisDrop.dropDownContainer);
        thisDrop.optionList.hover(thisDrop.optionActive, thisDrop.optionInActive);
        thisDrop.optionList.click(thisDrop.selectOption);
    };
    
    thisDrop.inputBlur = function ()
    {
        thisDrop.close();
    };
    
    thisDrop.addEvents = function (paramObject)
    {
        thisDrop.dropDownContainerInput = paramObject.input;
        thisDrop.dropDownContainer = $('div.dropDownContainer', thisDrop.container);
        thisDrop.document = $(document);
        thisDrop.dropDownContainerInput.keyup(thisDrop.inputKeyEvent);
        thisDrop.dropDownContainerInput.keydown(thisDrop.keyEvent);
    };
    
    thisDrop.init = function (paramObject)
    {
        thisDrop.setSettingsByObject(paramObject);
        var html = thisDrop.html;
        paramObject.input.attr('autocomplete', 'off');
        paramObject.input.wrap('<span class="dropDownOuterContainer"></span>');
        paramObject.input.after(html);
        thisDrop.container = paramObject.input.parent('span.dropDownOuterContainer');
        thisDrop.addEvents(paramObject);
        SKYSALES.Class.DropDown.dropDownArray[SKYSALES.Class.DropDown.dropDownArray.length] = thisDrop;
    };
    thisDrop.init(paramObject);
    return thisDrop;
};

SKYSALES.Class.DropDown.dropDownArray = [];

SKYSALES.Class.DropDown.getDropDown = function (selectParamObj)
{
    var retVal = null;
    var i = 0;
    var dropDown = null;
    var dropDownArray = SKYSALES.Class.DropDown.dropDownArray;
    var input = null;
    var inputCompare = selectParamObj.input.get(0);
    for (i = 0; i < dropDownArray.length; i += 1)
    {
        dropDown = dropDownArray[i];
        input = dropDown.dropDownContainerInput.get(0);
        if ((input) && (inputCompare) && (input === inputCompare))
        {
            retVal = dropDownArray[i];
            if (selectParamObj.options)
            {
                retVal.options = selectParamObj.options;
            }
        }
    }
    if (!retVal)
    {
        retVal = new SKYSALES.Class.DropDown(selectParamObj);
    }
    return retVal;
};

if (SKYSALES.Class.DatePickerManager === undefined)
{
	SKYSALES.Class.DatePickerManager = function ()
    {
        var thisDatePickerManager = this;
        thisDatePickerManager.isAOS = false;
        thisDatePickerManager.yearMonth = null;
        thisDatePickerManager.day = null;
        thisDatePickerManager.linkedDate = null;
        
        var allDayOptionArray = [];
        var yearMonthDelimiter = '-';
        var yearMonthFormatString = 'yy-mm';
        var firstDateOption = 'first';
        var fullDateFormatString = 'mm/dd/yy';
        
        var validateYearMonthRegExp = new RegExp('\\d{4}-\\d{2}');
        
        var getDaysInMonth = function (dateParam)
        {
            var daysNotInMonthDate = new Date(dateParam.getFullYear(), dateParam.getMonth(), 32);
            var daysNotInMonth = daysNotInMonthDate.getDate();
            return 32 - daysNotInMonth;
        };
        
        var validateDay = function (dayParam)
        {
            return dayParam.match(/\d{2}/);
        };
        
        var validateYearMonth = function (yearMonthParam)
        {
            yearMonthParam = yearMonthParam || '';
            return yearMonthParam.match(validateYearMonthRegExp);
        };
        
        var getDate = function (yearMonthParam, dayParam)
        {
            var retDate = new Date();
            var yearMonthArray = yearMonthParam.split(yearMonthDelimiter);
            var yearIndex = 0;
            var monthIndex = 1;
            if (true === thisDatePickerManager.isAOS)
            {
                yearIndex = 1;
                monthIndex = 0;
            }
            var yearVal = yearMonthArray[yearIndex];
            var monthVal = yearMonthArray[monthIndex] - 1;
            retDate = new Date(yearVal, monthVal, dayParam);
            return retDate;
        };
        
        var parseDate = function (yearMonthParam, dayParam)
        {
            var retDate = new Date();
            var validateDayVal = validateDay(dayParam);
            var validateYearMonthVal = validateYearMonth(yearMonthParam);

            if (validateDayVal && validateYearMonthVal)
            {
                var date = getDate(yearMonthParam, dayParam);
                var daysInMonth = getDaysInMonth(date);
                
                var dayVal = dayParam;
                if (dayParam > daysInMonth)
                {
                    dayVal = daysInMonth;
                }
                retDate = new Date(date.getFullYear(), date.getMonth(), dayVal);
            }
            else
            {
                retDate = new Date();
            }
            return retDate;
        };
        
        var readLinked = function ()
        {
            var date = parseDate(thisDatePickerManager.yearMonth.val(), thisDatePickerManager.day.val());            
            var dateString = $.datepicker.formatDate(fullDateFormatString, date);
            thisDatePickerManager.linkedDate.val(dateString);            
            return {};
        };
        
        var dayResizeAndSet = function (dateParam)
        {
            var todayDate = new Date();
            var todayDay = todayDate.getDate();
            var todayYearMonth = todayDate.getYear() + todayDate.getMonth();
            var dateParamYearMonth = dateParam.getYear() + dateParam.getMonth();
            var monthYearIsCurrent = (todayYearMonth === dateParamYearMonth);
            var todayIsPastSecond = (2 < todayDay);
            var trimInvalidDays = todayIsPastSecond && monthYearIsCurrent;
            var day = dateParam.getDate();
            var daysInMonth = getDaysInMonth(dateParam);
            var daysInMonthDifference = 31 - daysInMonth;
            var dayOptionArray = SKYSALES.Util.cloneArray(allDayOptionArray);
            var removeDaysAfterThisIndex = 31;
            if (daysInMonthDifference > 0)
            {
                removeDaysAfterThisIndex = 31 - daysInMonthDifference;
                dayOptionArray.splice(removeDaysAfterThisIndex, daysInMonthDifference);
            }
            if (trimInvalidDays) 
            {
                dayOptionArray.splice(0, todayDay - 1);
            }
            var daySelectParams = {
                'selectedItem': day,
                'objectArray': dayOptionArray,
                'selectBox': thisDatePickerManager.day,
                'clearOptions': true
            };            
            SKYSALES.Util.populateSelect(daySelectParams);
        };
        
        // Prevent selection of invalid dates through the select controls
        var yearMonthUpdate = function ()
        {
            var dayVal = thisDatePickerManager.day.val();
            var date = getDate(thisDatePickerManager.yearMonth.val(), 1);
            var daysInMonth = getDaysInMonth(date);
            if (dayVal > daysInMonth)
            {
                dayVal = daysInMonth;
            }
            date = new Date(date.getFullYear(), date.getMonth(), dayVal);
            dayResizeAndSet(date);
            thisDatePickerManager.linkedDate.val($.datepicker.formatDate(fullDateFormatString, date));
        };
        
        var dateUpdate = function ()
        {
            var yearMonthVal = thisDatePickerManager.yearMonth.val();
            var dayVal = thisDatePickerManager.day.val();
            var date = parseDate(yearMonthVal, dayVal);
            var dateVal = $.datepicker.formatDate(fullDateFormatString, date);
            thisDatePickerManager.linkedDate.val(dateVal);
        };
        
        var createAllDayOptionArray = function ()
        {
            var retArray = [];
            var optionIterator = 1;
            var option = {};
            for (optionIterator = 1; optionIterator <= 31; optionIterator += 1)
            {
                option = {};
                option.name = optionIterator;
                if (optionIterator <= 9)
                {
                    option.code = '0' + optionIterator;
                }
                else
                {
                    option.code = optionIterator;
                }
                retArray[optionIterator - 1] = option;
            }
            return retArray;
        };
        
        // Update select controls to match the date picker selection
        var updateLinked = function (dateString)
        {
            var match = dateString.match(/\d{2}\/\d{2}\/\d{4}/);
            var date = new Date();
            var yearMonthString = '';
            if (match)
            {
                date = new Date(dateString);
                yearMonthString = $.datepicker.formatDate(yearMonthFormatString, date);
                thisDatePickerManager.yearMonth.val(yearMonthString);                
                dayResizeAndSet(date);
            }
        };
        
        thisDatePickerManager.setSettingsByObject = function (paramObject)
        {
            var propName = '';
            for (propName in paramObject)
            {
                if (thisDatePickerManager.hasOwnProperty(propName))
                {
                    thisDatePickerManager[propName] = paramObject[propName];
                }
            }
        };
        
        thisDatePickerManager.setVars = function ()
        {
            if (true === thisDatePickerManager.isAOS)
            {
                yearMonthDelimiter = '/';
                yearMonthFormatString = 'm/yy';
                validateYearMonthRegExp = new RegExp('\\d{1,2}\\/\\d{4}');
                firstDateOption = 'eq(1)';
            }
        };
        
        var initFlight = function ()
        {
            if (!thisDatePickerManager.isAOS)
            {
                dateUpdate();
            }
        };        
        
        thisDatePickerManager.addEvents = function ()
        {
            thisDatePickerManager.yearMonth.change(yearMonthUpdate);
            thisDatePickerManager.day.change(dateUpdate);
            
            var minDate = new Date();
            var maxDate = new Date();
            var setDayDate = new Date();
            maxDate.setFullYear(maxDate.getFullYear() + 1);
            
            var yearMonthFirst = $('option:' + firstDateOption, thisDatePickerManager.yearMonth).val();
            var yearMonthLast = $('option:last', thisDatePickerManager.yearMonth).val();
            allDayOptionArray = createAllDayOptionArray();
            
            var linkedDate = thisDatePickerManager.linkedDate;
            
            if (validateYearMonth(yearMonthFirst))
            {
                minDate.setDate(minDate.getDate() - 1);
                if (thisDatePickerManager.isAOS)
                {
                    setDayDate = new Date(thisDatePickerManager.linkedDate.val());
                }
                else
                {
                    setDayDate = getDate(thisDatePickerManager.yearMonth.val(), thisDatePickerManager.day.val());
                }
                dayResizeAndSet(setDayDate);
            }
            
            if (validateYearMonth(yearMonthLast))
            {
                maxDate = getDate(yearMonthLast, 1);
                var daysInMonth = getDaysInMonth(maxDate);
                maxDate = new Date(maxDate.getFullYear(), maxDate.getMonth(), daysInMonth);
            }
            
            var resource = SKYSALES.Util.getResource();
            var dateCultureInfo = resource.dateCultureInfo;
            var datePickerSettings = SKYSALES.datepicker;
            
            initFlight();
            
            var datePickerParams = {
                'beforeShow': readLinked,
                'onSelect': updateLinked,
                'minDate': minDate,
                'maxDate': maxDate,
                'showOn': 'both',
                'buttonImageOnly': true,
                'buttonImage': 'images/Idtgv/calendar-up.gif',
                'buttonText': 'Calendrier',
                'numberOfMonths': 1,
                'mandatory': true,
                'monthNames': dateCultureInfo.monthNames,
                'monthNamesShort': dateCultureInfo.monthNamesShort,
                'dayNames': dateCultureInfo.dayNames,
                'dayNamesShort': dateCultureInfo.dayNamesShort,
                'dayNamesMin': dateCultureInfo.dayNamesMin,
                'closeText': datePickerSettings.closeText,
                'prevText': datePickerSettings.prevText,
                'nextText': datePickerSettings.nextText,
                'currentText': datePickerSettings.currentText
            };            
            linkedDate.datepicker(datePickerParams);
        };
        
        thisDatePickerManager.init = function (paramObject)
        {
            this.setSettingsByObject(paramObject);
            this.setVars();
            this.addEvents();
        };
    };
}
//Code to deal with the old way of getting the form on the page
SKYSALES.initializeSkySalesForm = function ()
{
    document.SkySales = document.forms.SkySales;
};

//Returns the skysales html form
SKYSALES.getSkySalesForm = function ()
{
    var skySalesForm = $('SkySales').get(0);
    return skySalesForm;
};

/*
    Name: 
        Class Common
    Param:
        None
    Return: 
        An instance of Common
    Functionality:
        Provide common functionality and events on every view.
    Notes:
        This should be put in the SKYSALES.Class namespace.
    Class Hierarchy:
        Common
*/
SKYSALES.Common = function ()
{
    var thisCommon = this;
    var countryInfo = null;
    
    thisCommon.allInputObjects = null;
    
    thisCommon.initializeCommon = function ()
    {
        var hint = new SKYSALES.Hint();
        var inputLabel = new SKYSALES.InputLabel();
        thisCommon.addKeyDownEvents();
        thisCommon.addSetAndEraseEvents();
        thisCommon.setValues();
        hint.addHintEvents();
        inputLabel.formatInputLabel();
        thisCommon.stripeTables();
    };
    
    thisCommon.setValues = function ()
    {
        var setValue = function (index)
        {
            if ((this.jsvalue !== null) && (this.jsvalue !== undefined))
            {
                this.value = this.jsvalue;
            }
        };
        thisCommon.getAllInputObjects().each(setValue);
    };
    
    thisCommon.stopSubmit = function ()
    {
        // Remove the submit event so that you can click the submit button
        $('form').unbind('submit', thisCommon.stopSubmit);
        return false;
    };
    
    thisCommon.addKeyDownEvents = function ()
    {
        var keyFunction = function (e)
        {
            if (e.keyCode === 13)
            {
                // Stop the enter key in opera
                $('form').submit(thisCommon.stopSubmit);
                return false;
            }
            return true;
        };
        $(':input').keydown(keyFunction);
    };
    
    thisCommon.getAllInputObjects = function ()
    {
        if (thisCommon.allInputObjects === null)
        {
            thisCommon.allInputObjects = $(':input');
        }
        return thisCommon.allInputObjects;
    };
    
    thisCommon.addSetAndEraseEvents = function ()
    {
        var focusFunction = function ()
        {
            thisCommon.eraseElement(this, this.requiredempty);
        };
        var blurFunction = function ()
        {
            thisCommon.setElement(this, this.requiredempty);
            $(this).change();
        };
        var eventFunction = function (index)
        {   
            if ((this.requiredempty !== null) && (this.requiredempty !== undefined))
            {
                //hack prevent focus on hidden elements in IE (which will throw an exception)
                if ($(this).is(':hidden') === false)
                {
                    $(this).focus(focusFunction);
                    $(this).blur(blurFunction);
                }
            }
        };
        thisCommon.getAllInputObjects().each(eventFunction);
    };
    
    thisCommon.eraseElement = function (element, defaultValue)
    {
        if (element.value === defaultValue)
        {
            element.value = "";
        }
    };
    
    thisCommon.setElement = function (element, defaultValue)
    {
        if (element.value === "")
        {
            element.value = defaultValue;
        }
    };
    
    thisCommon.getCountryInfo = function ()
    {
        if (countryInfo === null)
        {
            countryInfo = window.countryInfo;
        }
        return countryInfo;
    };
    thisCommon.setCountryInfo = function (arg)
    {
        countryInfo = arg;
        return thisCommon;
    };
    
    thisCommon.isEmpty = function (element, defaultValue)
    {
        var val = null;
        var retVal = false;
        
        if ((element) && (defaultValue === undefined))
        {
            if (element.requiredempty)
            {
                defaultValue = element.requiredempty;
            }
            else
            {
                defaultValue = '';
            }
        }
        
        val = SKYSALES.Common.getValue(element);
        if ((val === null) || (val === undefined) || (val.length === 0) || (val === defaultValue))
        {
            retVal = true;
        }
        return retVal;
    };
    
    thisCommon.stripeTables = function ()
    {
        $(".stripeMe tr:even").addClass("alt");
        return thisCommon;
    };
};

//Adds an event to the dom, and sets a function handler
SKYSALES.Common.addEvent = function (obj, eventString, functionRef)
{
    $(obj).bind(eventString, functionRef);
};

//Returns the value of an html form element
SKYSALES.Common.getValue = function (e)
{
    var val = null;
    if (e)
    {
        val = $(e).val();
        return val;
    }
    return null;
};

/*
    Name: 
        Class InputLabel
    Param:
        None
    Return: 
        An instance of InputLabel
    Functionality:
        Adds the * to required fields, and : to the end of labels for input boxes
    Notes:
        This should be put in the SKYSALES.Class namespace.
    Class Hierarchy:
        InputLabel
*/
SKYSALES.InputLabel = function ()
{
    var thisInputLabel = this;
    thisInputLabel.getInputLabelRequiredFlag = function ()
    {
        return '*';
    };
    
    thisInputLabel.getInputLabelSuffix = function ()
    {
        return ':';
    };
    
    thisInputLabel.formatInputLabel = function ()
    {
        var requiredFlag = thisInputLabel.getInputLabelRequiredFlag();
        var suffix = thisInputLabel.getInputLabelSuffix();
        var eventFunction = function (index)
        {
        	//Idtgv - adding if to prevent javascript error when id is null
			 if (this.id !== '')
					 {
            var label = $("label[@for=" + this.id + "]").eq(0);
            var labelText = $(label).text();
            var inputType = '';
            var required = null;
            if (labelText !== '')
            {
                inputType = $(this).attr("type");
                if ((inputType !== 'checkbox') && (inputType !== 'radio'))
                {
                    labelText = labelText + suffix;
                }
                required = this.required;
                if (required === undefined)
                {
                    required = null;
                }
                if (required === null)
                {
                    required = this.getAttribute('required');
                }
                if (required !== null)
                {
                    required = required.toString().toLowerCase();
                    if (required === 'true')
                    {
                        labelText = requiredFlag + labelText;
                    }
                }
                $(label).text(labelText);
            }
		 }
        };
        SKYSALES.common.getAllInputObjects().each(eventFunction);
    };
};

/*
    Name: 
        Class Dhtml
    Param:
        None
    Return: 
        An instance of Dhtml
    Functionality:
        Provides methods that return the x and y position of an element on the dom
    Notes:
        This should be put in the SKYSALES.Class namespace.
    Class Hierarchy:
        Dhtml
*/
SKYSALES.Dhtml = function ()
{
    var thisDhtml = this;
    thisDhtml.getX = function (obj)
    {
        var pos = 0;
        if (obj.x)
        {
            pos += obj.x;
        }
        else if (obj.offsetParent)
        {
            while (obj.offsetParent)
            {
                pos += obj.offsetLeft;
                obj    = obj.offsetParent;
            }
        }
        return pos;
    };
    
    thisDhtml.getY = function (obj)
    {
        var pos = 0;
        if (obj.y)
        {
            pos += obj.y;
        }
        else if (obj)
        {
            while (obj)
            {       
                pos += obj.offsetTop;
                obj = obj.offsetParent;
            }
        }
        return pos;
    };
    return thisDhtml;
};

/*
    Name: 
        Class Hint
    Param:
        None
    Return: 
        An instance of Hint
    Functionality:
        A hint is shown as a helpful tip to the user about a html form field.
        Such as showing the user what the valid characters are for their password, 
        when they are registering as a new user
    Notes:
        This should be put in the SKYSALES.Class namespace.
    Class Hierarchy:
        Hint
*/
SKYSALES.Hint = function ()
{
    var thisHint = this;
    thisHint.addHintEvents = function ()
    {
        var eventFunction = function (index)
        {
            if ((this.hint !== null) && (this.hint !== undefined))
            {
                if (this.tagName && (this.tagName.toString().toLowerCase() === 'input'))
                {
                    thisHint.addHintFocusEvents(this);
                }
                else
                {
                    thisHint.addHintHoverEvents(this);
                }
            }
        };
        SKYSALES.common.getAllInputObjects().each(eventFunction);
    };

    thisHint.addHintFocusEvents = function (obj, hintText)
    {
        var focusFunction = function ()
        {
            thisHint.showHint(obj, hintText);
        };
        var blurFunction = function ()
        {
            thisHint.hideHint(obj, hintText);
        };
        if ($(obj).is(':hidden') === false)
        {
            $(obj).focus(focusFunction);
            $(obj).blur(blurFunction);
        }
    };

    thisHint.addHintHoverEvents = function (obj, hintText)
    {
        var showFunction = function ()
        {
            thisHint.showHint(obj, hintText);
        };
        var hideFunction = function ()
        {
            thisHint.hideHint(obj, hintText);
        };
        $(obj).hover(showFunction, hideFunction);
    };

    thisHint.getHintDivId = function ()
    {
        return "cssHint";
    };

    thisHint.showHint = function (obj, hintHtml, xOffset, yOffset, referenceId)
    {
        var hintDivId = thisHint.getHintDivId();
        var jQueryHintDiv = $('#' + hintDivId);
        var x = 0;
        var y = 0;
        var defaultXOffset = 0;
        var defaultYOffset = 0;
        
        if (xOffset === undefined)
        {
            xOffset = obj.hintxoffset;
        }
        if (yOffset === undefined)
        {
            yOffset = obj.hintyoffset;
        }
        
        if (referenceId === undefined)
        {
            referenceId = obj.hintReferenceid;
        }
        var referenceObject = $('#' + referenceId).get(0);
        
        var dhtml = new SKYSALES.Dhtml();
        if (!referenceObject)
        {
            x = dhtml.getX(obj);
            y = dhtml.getY(obj);
            if (xOffset === undefined)
            {
                x += obj.offsetWidth + 5;
            }
        }
        else
        {
            x = dhtml.getX(referenceObject);
            y = dhtml.getY(referenceObject);
            if (xOffset === undefined)
            {
                x += referenceObject.offsetWidth + 5;
            }
        }
        
        if (hintHtml === undefined)
        {
            if (obj.hint !== undefined)
            {
                hintHtml = obj.hint;
            }
        }
        jQueryHintDiv.html(hintHtml);
        jQueryHintDiv.show();
        xOffset    = (xOffset !== undefined) ? xOffset : defaultXOffset;
        yOffset    = (yOffset !== undefined) ? yOffset : defaultYOffset;
        var leftX = parseInt(xOffset, 10) + parseInt(x, 10);
        var leftY = parseInt(yOffset, 10) + parseInt(y, 10);
        jQueryHintDiv.css('left', leftX + 'px');
        jQueryHintDiv.css('top', leftY + 'px');
    };

    thisHint.hideHint = function (obj)
    {
        var hintDivId = thisHint.getHintDivId();
        $('#' + hintDivId).hide();
    };
};

/*
    Name: 
        Class ValidationErrorReadAlong
    Param:
        None
    Return: 
        An instance of ValidationErrorReadAlong
    Functionality:
        To provide a way of showing the user validation error messages so that they can fix them in a user friendly way 
    Notes:
        This should be put in the SKYSALES.Class namespace.
    Class Hierarchy:
        ValidationErrorReadAlong
*/
SKYSALES.ValidationErrorReadAlong = function ()
{
    var thisReadAlong = this;
    thisReadAlong.objId = '';
    thisReadAlong.obj = null;
    thisReadAlong.errorMessage = '';
    thisReadAlong.isError = false;
    thisReadAlong.hasBeenFixed = false;
    thisReadAlong.hasValidationEvents = false;
    
    thisReadAlong.getValidationErrorHtml = function ()
    {
        var validatonErrorHtml = '<iframe id="validationErrorContainerReadAlongIFrame" class="hidden" ><\/iframe> <div id="validationErrorContainerReadAlong" > <div class="close"> <input id="validationErrorContainerReadAlongCloseButton" type="button" class="closeBtn" value="X" \/> <\/div> <div id="validationErrorContainerReadAlongContent" ><div id="validationErrorContainerReadAlongList" > <\/div> <\/div> <\/div>';
        return validatonErrorHtml;
    };
    thisReadAlong.getValidationErrorCloseId = function ()
    {
        return 'validationErrorContainerReadAlongCloseButton';
    };
    thisReadAlong.getValidationErrorListId = function ()
    {
        return 'validationErrorContainerReadAlongList';
    };
    thisReadAlong.getValidationErrorIFrameId = function ()
    {
        return 'validationErrorContainerReadAlongIFrame';
    };
    thisReadAlong.getValidationErrorDivId = function ()
    {
        return 'validationErrorContainerReadAlong';
    };
    thisReadAlong.getFixedClass = function ()
    {
        return 'fixedValidationError';
    };
    thisReadAlong.addCloseEvent = function ()
    {
        var closeId = thisReadAlong.getValidationErrorCloseId();
        var closeFunction = function ()
        {
            thisReadAlong.hide();
        };
        $('#' + closeId).click(closeFunction);  
    };
    thisReadAlong.addValidationErrorDiv = function ()
    {
        $('#mainContent').append(thisReadAlong.getValidationErrorHtml());
    };
    thisReadAlong.hide = function ()
    {
        var iFrameId = thisReadAlong.getValidationErrorIFrameId();
        var divId =  thisReadAlong.getValidationErrorDivId();
        $('#' + iFrameId).hide();
        $('#' + divId).hide();
    };
    thisReadAlong.addFocusEvent = function (index)
    {
        var data = {obj: this};
        var eventFunction = function (event)
        {
            var obj = event.data.obj;
            var hint = null;
            var readAlongDivObj = null;
            var readAlongDivWidth = 0;
            var readAlongDivHeight = 0;
            var x = 0;
            var y = 0;
            var dhtml = null;
            var iFrameObj = null;
            if (obj.isError === true)
            {
                hint = new SKYSALES.Hint();
                hint.hideHint();
                readAlongDivObj = $('#' + thisReadAlong.getValidationErrorDivId());
                readAlongDivWidth = parseInt(readAlongDivObj.width(), 10) + 5;
                readAlongDivHeight = parseInt(readAlongDivObj.height(), 10) + 5;
                dhtml = new SKYSALES.Dhtml();
                x = dhtml.getX(obj.obj);
                y = dhtml.getY(obj.obj);
                x = x + this.offsetWidth + 5;
                y = y - 45;
                /* Start IE 6 Hack */
                if ($.browser.msie)
                {
                    iFrameObj = $('#' + thisReadAlong.getValidationErrorIFrameId());
                    iFrameObj.css('position', 'absolute');
                    iFrameObj.show();
                    iFrameObj.width(readAlongDivWidth - 25);
                    iFrameObj.height(readAlongDivHeight - 5);
                    iFrameObj.css('left', x + 16);
                    iFrameObj.css('top', y);
                }
                /* End IE 6 Hack */
                readAlongDivObj.css('left', x);
                readAlongDivObj.css('top', y);
                readAlongDivObj.css('position', 'absolute');
                readAlongDivObj.show('slow');
                return false;
            }
        };
        
        if ($(this.obj).is(':hidden') === false)
        {
            $(this.obj).bind("focus", data, eventFunction);
        }
        
    };
    
    thisReadAlong.addBlurEvent = function (index)
    {
        var data = {obj: this};
        var eventFunction = function (event)
        {
            var obj = event.data.obj;
            var validateObj = new SKYSALES.Validate(null, '', '', null);
            validateObj.validateSingleElement(this);
            var errorMessage = validateObj.errors;
            var isFixed = false;
            var allFixed = true;
            if (validateObj.validationErrorArray.length > 0)
            {
                if (validateObj.validationErrorArray[0].isError === false)
                {
                    isFixed = true;
                }
            }
            var listId = obj.getValidationErrorListId();
            var listObj = $('#' + listId).find('li').eq(index);
            var fixedClass = obj.getFixedClass();
            var fixedFunction = function ()
            {
                if (
                        (allFixed === true) && 
                        ($(this).attr("class").indexOf('hidden') === -1) && 
                        ($(this).attr("class").indexOf(fixedClass) === -1)
                        )
                {
                    allFixed = false;
                }
            };
            if (isFixed === true)
            {
                /*iDTGV modif*/
                obj.isError = false;
                obj.hasBeenFixed = true;
                listObj.addClass(fixedClass);
                allFixed = true;
                $('#' + listId).find('li').each(fixedFunction);
                if (allFixed === true)
                {
                    thisReadAlong.hide();
                }
            }
            else
            {
                obj.hasBeenFixed = false;
                listObj.removeClass(fixedClass);
                listObj.removeClass('hidden');
                obj.isError = true;
                obj.errorMessage = errorMessage;
                listObj.text(errorMessage);
            }
            
            /*iDTGV modification*/
            thisReadAlong.hide();
            return false;
        };
        $(this.obj).bind("blur", data, eventFunction);
        /*iDTGV modif so that error disappears when selecting a value in dropdown list*/
        if ($(this.obj).is("select") == true)
        {
            $(this.obj).bind("change", data, eventFunction);
        }
    };
};

SKYSALES.errorsHeader = 'Please correct the following.\n\n';

/*
    Name: 
        Class Validate
    Param:
        None
    Return: 
        An instance of Validate
    Functionality:
        Provides a way of validating html form elements before they are submitted to the server
    Notes:
        This should be put in the SKYSALES.Class namespace.
    Class Hierarchy:
        Validate
*/
SKYSALES.Validate = function (form, controlID, errorsHeader, regexElementIdFilter)
{
    var thisValidate = this;
    if (errorsHeader === undefined)
    {
        errorsHeader = SKYSALES.errorsHeader;
    }
    // set up properties
    thisValidate.form = form;
    thisValidate.namespace = controlID;
    thisValidate.errors = '';
    thisValidate.validationErrorArray = [];
    thisValidate.setfocus = null;
    thisValidate.clickedObj = null;
    thisValidate.errorDisplayMethod = 'read_along';
    thisValidate.errorsHeader = errorsHeader;
    thisValidate.namedErrors = [];
    
    //array of date strings
    thisValidate.dateRangeArray = [];
        
    if (regexElementIdFilter)
    {
        thisValidate.regexElementIdFilter = regexElementIdFilter;
    }
    // set up attributes
    thisValidate.requiredAttribute = 'required';
    thisValidate.requiredEmptyAttribute = 'requiredempty';
    thisValidate.validationTypeAttribute = 'validationtype';
    thisValidate.regexAttribute = 'regex';
    thisValidate.minLengthAttribute = 'minlength';
    thisValidate.numericMinLengthAttribute = 'numericminlength';
    thisValidate.maxLengthAttribute = 'maxlength';
    thisValidate.numericMaxLengthAttribute = 'numericmaxlength';
    thisValidate.minValueAttribute = 'minvalue';
    thisValidate.maxValueAttribute = 'maxvalue';
    thisValidate.equalsAttribute = 'equals';
    thisValidate.dateRangeAttribute = 'daterange';
    thisValidate.checkboxRefIdAttribute = 'checkboxrefid';
    thisValidate.dateRange1HiddenIdAttribute = 'date1hiddenid';
    thisValidate.dateRange2HiddenIdAttribute = 'date2hiddenid';
    thisValidate.customAttribute = 'custom';

    // set up error handling attributes
    thisValidate.defaultErrorAttribute = 'error';
    thisValidate.requiredErrorAttribute = 'requirederror';
    thisValidate.validationTypeErrorAttribute = 'validationtypeerror';
    thisValidate.regexErrorAttribute = 'regexerror';
    thisValidate.minLengthErrorAttribute = 'minlengtherror';
    thisValidate.maxLengthErrorAttribute = 'maxlengtherror';
    thisValidate.minValueErrorAttribute = 'minvalueerror';
    thisValidate.maxValueErrorAttribute = 'maxvalueerror';
    thisValidate.equalsErrorAttribute = 'equalserror';
    thisValidate.customErrorAttribute = 'customError';
    thisValidate.dateRangeErrorAttribute = 'daterangeerror'; 
    thisValidate.dateNotPastErrorAttribute = 'datenotpasterror';   

    // set up error handling default errors
    thisValidate.defaultError = '{label} est invalide.';
    thisValidate.defaultRequiredError = '{label} est requis.';
    thisValidate.defaultValidationTypeError = '{label} est invalide.';
    thisValidate.defaultRegexError = '{label} est invalide.';
    thisValidate.defaultMinLengthError = '{label} est trop court.';
    thisValidate.defaultMaxLengthError = '{label} est trop long.';
    thisValidate.defaultMinValueError = '{label} doit &ecirc;tre plus grand que {minValue}.';
    thisValidate.defaultMaxValueError = '{label} doit &ecirc;tre plus petit que {maxValue}.';
    thisValidate.defaultEqualsError = '{label} n\' est pas &eacute;gal &agrave; {equals}';
    thisValidate.defaultNotEqualsError = '{label} cannot equal {equals}';

    thisValidate.defaultValidationErrorClass = 'validationError';
    thisValidate.defaultValidationErrorLabelClass = 'validationErrorLabel';
    
    // add methods to object
    thisValidate.run = function ()
    {
        var nodeArray = $(':input', SKYSALES.getSkySalesForm()).get();
        var e = null;
        // run validation on the form elements
        for (var i = 0; i < nodeArray.length; i += 1)
        {
            e = nodeArray[i];
            if (!this.isExemptFromValidation(e))
            {
                thisValidate.validateSingleElement(e);
            }
        }
        return thisValidate.outputErrors();
    };
    thisValidate.runBySelector = function (selectorString)
    {
        var nodeArray = $(selectorString).find(':input').get();
        var node = null;
        var i = 0;
        // run validation on the form elements
        for (i = 0; i < nodeArray.length; i += 1)
        {
            node = nodeArray[i];
            thisValidate.validateSingleElement(node);
        }
        return false;
    };
    thisValidate.validateSingleElement = function (e)
    {
        $(e).removeClass(thisValidate.defaultValidationErrorClass);
        $("label[@for=" + e.id + "]").eq(0).removeClass(this.defaultValidationErrorLabelClass);
        
        var validationError = new SKYSALES.ValidationErrorReadAlong();
        validationError.objId = e.id;
        validationError.obj = e;
        this.validationErrorArray[thisValidate.validationErrorArray.length] = validationError;
        
        this.validateRequired(e);
        // only validate the rest if they actually have something
        var value = thisValidate.getValue(e);
        if ((thisValidate.errors.length < 1) && (value !== null) && (value !== ""))
        {
            thisValidate.validateType(e);
            thisValidate.validateRegex(e);
            thisValidate.validateMinLength(e);
            thisValidate.validateMaxLength(e);
            thisValidate.validateMinValue(e);
            thisValidate.validateMaxValue(e);
            thisValidate.validateEquals(e);
            thisValidate.validateDateRange(e);
            thisValidate.validateCustom(e);
        }
    };
    thisValidate.outputErrors = function ()
    {
        // if there is an error output it
        var errorDisplayMethod = this.errorDisplayMethod.toString().toLowerCase();
        var errorHtml = '';
        var errorArray = [];
        var i = 0;
        var showDefaultErrorMethod = true;
        if (this.errors)
        {
            //errorHtml += '<div class="errorSectionHeader" >' + this.errorsHeader + '<\/div>';
            errorArray = thisValidate.errors.split('\n');
            errorHtml += '<ul class="validationErrorList" >';
            for (i = 0; i < errorArray.length; i += 1)
            {
                if (errorArray[i] !== '')
                {
                    errorHtml += '<li class="validationErrorListItem" >' + errorArray[i] + '<\/li>';
                }
            }
            errorHtml += '<\/ul>';
            if (errorDisplayMethod.indexOf('read_along') > -1)
            {
                thisValidate.outputErrorsReadAlong(errorHtml);
                showDefaultErrorMethod = false;
            }
            if (errorDisplayMethod.indexOf('alert') > -1)
            {
                alert(thisValidate.errorsHeader + thisValidate.errors);
            }
            if (showDefaultErrorMethod === true)
            {
                alert(thisValidate.errorsHeader + thisValidate.errors);
            }
            
            if (thisValidate.setfocus)
            {
                if ($(thisValidate.setfocus).is(':hidden') === false)
                {
                    thisValidate.setfocus.blur();
                    thisValidate.setfocus.focus();
                }
            }
            return false;
        }
        else
        {
            return true;
        }
    };
    thisValidate.outputErrorsReadAlong = function (errorHtml)
    {
        var i = 0;
        var errorHtmlLocal = '';
        var validationError = null;
        var validateObject = this;
        var addErrorEventFunction = function (index)
        {
            this.hasValidationEvents = true;
            this.addFocusEvent(index);
            this.addBlurEvent(index);
        };
        
        validateObject.validationErrorReadAlong = new SKYSALES.ValidationErrorReadAlong();
        validateObject.readAlongDivId = $('#' + this.validationErrorReadAlong.getValidationErrorDivId()).attr('id');
        if (validateObject.readAlongDivId === undefined)
        {
            validateObject.validationErrorReadAlong.addValidationErrorDiv();
            validateObject.validationErrorReadAlong.addCloseEvent();
        }
        errorHtmlLocal += '<ul class="validationErrorList" >';
        for (i = 0; i < validateObject.validationErrorArray.length; i += 1)
        {
            validationError = this.validationErrorArray[i];
            if (validationError.isError === true)
            {
                errorHtmlLocal += '<li class="validationErrorListItem" >' + validationError.errorMessage + '<\/li>';
            }
            else
            {
                errorHtmlLocal += '<li class="validationErrorListItem hidden" >' + validationError.errorMessage + '<\/li>';
            }
        }
        $('#' + validateObject.validationErrorReadAlong.getValidationErrorListId()).html(errorHtmlLocal);
        
        $(validateObject.validationErrorArray).each(addErrorEventFunction);
    };
    thisValidate.checkFocus = function (e)
    {
        if (!thisValidate.setfocus)
        {
            thisValidate.setfocus = e;
        }
    };
    thisValidate.setError = function (e, errorAttribute, defaultTypeError)
    {
        var nameStr = '';
        var error = '';
        var dollarOne = '';
        var i = 0;
        var validationError = null;
        
        if (e.type === 'radio')
        {
            nameStr = e.getAttribute('name');
            if (nameStr.length > 0)
            {
                if (thisValidate.namedErrors[nameStr] !== undefined)
                {
                    return;
                }
                thisValidate.namedErrors[nameStr] = nameStr;
            }
        }
             
        error = e[errorAttribute];
        //var error = e.getAttribute(errorAttribute);
        if (!error)
        {
            if (e[thisValidate.defaultErrorAttribute])
            {
                error = e[thisValidate.defaultErrorAttribute];
            }
            else if (defaultTypeError)
            {
                error = defaultTypeError;
            }
            else
            {
                error = thisValidate.defaultError;
            }
        }
        //alert(errorAttribute + "\n" + error + "\n" + e.requiredError);
        
        // this would make more sense but it doesn't work
        // so i'll do each explicitly while i make this work
        var results = error.match(/\{\s*(\w+)\s*\}/g);
        if (results)
        {
            for (i = 0; i < results.length; i += 1)
            {
                dollarOne = results[i].replace(/\{\s*(\w+)\s*\}/, '$1');
                error = error.replace(/\{\s*\w+\s*\}/, thisValidate.cleanAttributeForErrorDisplay(e, dollarOne));
            }
        }
        
        $(e).addClass(this.defaultValidationErrorClass);
        $("label[@for=" + e.id + "]").eq(0).addClass(thisValidate.defaultValidationErrorLabelClass);
        this.errors += error + '\n';
        
        var errorObjId = e.id;
        for (i = 0; i < thisValidate.validationErrorArray.length; i += 1)
        {
            validationError = thisValidate.validationErrorArray[i];
            if (validationError.objId === errorObjId)
            {
                validationError.errorMessage = error;
                validationError.isError = true;
                break;
            }
        }
        this.checkFocus(e);
        
    };
    thisValidate.cleanAttributeForErrorDisplay = function (e, attributeName)
    {
        var inputLabelObj = null;
        var requiredString = '';
        if (attributeName === undefined)
        {
            attributeName = '';
        }
        attributeName = attributeName.toLowerCase();
        var attribute = "";
        if (attributeName === 'label')
        {
            attribute = $("label[@for=" + e.id + "]").eq(0).text();
            inputLabelObj = new SKYSALES.InputLabel();
            requiredString = inputLabelObj.getInputLabelRequiredFlag();
            attribute = attribute.replace(requiredString, '');
        }
        if (!attribute)
        {
            attribute = e.id;
        }
        
        if (!attribute)
        {
            return attributeName;
        }
        
        if (attributeName.match(/^(minvalue|maxvalue)$/i))
        {
            return attribute.replace(/[^\d.,]/g, '');
        }
        
        return attribute;
    };
    thisValidate.validateRequired = function (e)
    {
        var requiredAttribute = thisValidate.requiredAttribute;
        var requiredEmptyAttribute = thisValidate.requiredEmptyAttribute;
        var required = e[requiredAttribute];
        var requiredEmptyString = e[requiredEmptyAttribute];
        var value = null;
        thisValidate.radioGroupHash = {};
        var radioName = '';
        var isRadioGroupChecked = false;
        if (required !== undefined)
        {
            required = required.toString().toLowerCase();
            if (requiredEmptyString)
            {
                requiredEmptyString = requiredEmptyString.toString().toLowerCase();
            }
            if (required === 'true')
            {
                value = thisValidate.getValue(e);
                if ((e.type === 'checkbox') && (e.checked === false))
                {
                    value = '';
                }
                else if (e.type === 'radio')
                {
                    radioName = e.getAttribute('name');
                    if (thisValidate.radioGroupHash[radioName] === undefined)
                    {
                        thisValidate.radioGroupHash[radioName] = $("input[@name='" + radioName + "']");
                    }
                    isRadioGroupChecked = thisValidate.radioGroupHash[radioName].is(':checked');
                    if (!isRadioGroupChecked)
                    {
                        value = '';
                    }
                }
                // this will not produce an error if value === 0
                if (
                    (value === undefined) || 
                    (value === null) || 
                    (value === '') || 
                    (value.toLowerCase() === requiredEmptyString)
                    )
                {
					///////// Check if the control is displayed (can be hidden by a parent control)
					var isDisplayed = true;
					var parentDiv = $("#"+e.id).parents("div:first");
					if($("#"+parentDiv[0].id).css("display") == "none")
						isDisplayed = false;
						
					if(isDisplayed) /////////////////////////////////////////////
						thisValidate.setError(e, thisValidate.requiredErrorAttribute, thisValidate.defaultRequiredError);
                }
            }
        }
    };
    thisValidate.validateType = function (e)
    {
        var type = e[this.validationTypeAttribute];
        //var type = e.getAttribute(this.validationTypeAttribute);
        var value = this.getValue(e);
        
        if ((type) && (value !== null)) 
        {
            type = type.toLowerCase();
            if ((type === 'address') && (!value.match(thisValidate.stringPattern)))
            {
                thisValidate.setValidateTypeError(e);
            }
            else if ((type === 'alphanumeric') && (!value.match(thisValidate.alphaNumericPattern)))
            {
                thisValidate.setValidateTypeError(e);
            }
            else if ((type === 'amount') && (!thisValidate.validateAmount(value)))
            {
                thisValidate.setValidateTypeError(e);
            }
            else if ((type === 'country') && (!value.match(thisValidate.stringPattern)))
            {
                thisValidate.setValidateTypeError(e);
            }
            else if ((type === 'email') && (!value.match(thisValidate.emailPattern)))
            {
                thisValidate.setValidateTypeError(e);
            }
            else if ((type === 'mod10') && (!thisValidate.validateMod10(value)))
            {
                thisValidate.setValidateTypeError(e);
            }
            else if ((type === 'name') && (!value.match(thisValidate.stringPattern)))
            {
                thisValidate.setValidateTypeError(e);
            }
            else if ((type === 'numeric') && (!thisValidate.validateNumeric(value)))
            {
                thisValidate.setValidateTypeError(e);
            }
            else if ((type.indexOf('date') === 0) && (!thisValidate.validateDate(e, type, value)))
            {
                thisValidate.setValidateTypeError(e);
            }
            else if ((type === 'state') && (!value.match(thisValidate.stringPattern)))
            {
                thisValidate.setValidateTypeError(e);
            }
            else if ((type === 'string') && (!value.match(thisValidate.stringPattern)))
            {
                thisValidate.setValidateTypeError(e);
            }
            else if ((type === 'uppercasestring') && (!value.match(thisValidate.upperCaseStringPattern)))
            {
                thisValidate.setValidateTypeError(e);
            }
            else if ((type === 'zip') && (!value.match(thisValidate.stringPattern)))
            {
                thisValidate.setValidateTypeError(e);
            }
        }
    };
    thisValidate.validateRegex = function (e)
    {
        var regex = e[thisValidate.regexAttribute];
        //var regex = e.getAttribute(this.regexAttribute);
        var value = thisValidate.getValue(e);
        if ((value !== null) && (regex) && (!value.match(regex)))
        {
            this.setError(e, thisValidate.regexErrorAttribute, thisValidate.defaultRegexError);
        }
    };
    thisValidate.validateMinLength = function (e)
    {
        var length = e[thisValidate.minLengthAttribute];
        var numericLength = e[thisValidate.numericMinLengthAttribute];
        var value = this.getValue(e);
        
        if ((0 < length) && (value !== null) && (value.length < length))
        {
            thisValidate.setError(e, thisValidate.minLengthErrorAttribute, thisValidate.defaultMinLengthError);
        }
        else if ((0 < numericLength)  && (0 < value.length) && (value.replace(thisValidate.numericStripper, '').length < numericLength))
        {
            thisValidate.setError(e, thisValidate.minLengthErrorAttribute, thisValidate.defaultMinLengthError);
        }
    };
    thisValidate.validateMaxLength = function (e)
    {
        var length = e[thisValidate.maxLengthAttribute];
        var numericLength = e[thisValidate.numericMaxLengthAttribute];
        var value = this.getValue(e);
                    
        if ((0 < length) && (value !== null) && (length < value.length))
        {
            thisValidate.setError(e, thisValidate.maxLengthErrorAttribute, thisValidate.defaultMaxLengthError);
        }
        else if ((0 < numericLength)  && (0 < value.length) && (numericLength < value.replace(thisValidate.numericStripper, '').length))
        {
            thisValidate.setError(e, thisValidate.maxLengthErrorAttribute, thisValidate.defaultMaxLengthError);
        } 
    };
    thisValidate.validateMinValue = function (e)
    {
        var min = e[thisValidate.minValueAttribute];
        var value = thisValidate.getValue(e);
        
        if ((value !== null) && (min !== undefined) && (0 < min.length))
        {
            
            if ((5 < min.length) && (min.substring(0, 5) === '&gt;='))
            {
                if (value < parseFloat(min.substring(5, min.length)))
                {
                    thisValidate.setError(e, thisValidate.minValueErrorAttribute, thisValidate.defaultMinValueError);
                }
            }
            else if ((4 < min.length) && (min.substring(0, 4) === '&gt;'))
            {
                if (value <= parseFloat(min.substring(4, min.length)))
                {
                    thisValidate.setError(e, thisValidate.minValueErrorAttribute, thisValidate.defaultMinValueError);
                }
            }
            else if (value < parseFloat(min))
            {
                thisValidate.setError(e, thisValidate.minValueErrorAttribute, thisValidate.defaultMinValueError);
            }
        }
    };
    thisValidate.validateMaxValue = function (e)
    {
        var max = e[this.maxValueAttribute];
        var value = this.getValue(e);
        
        if ((value !== null) && (max !== undefined) && (0 < max.length))
        {
            if ((5 < max.length) && (max.substring(0, 5) === '&lt;='))
            {
                if (value > parseFloat(max.substring(5, max.length)))
                {
                    thisValidate.setError(e, thisValidate.maxValueErrorAttribute, thisValidate.defaultMaxValueError);
                }
            }
            else if ((4 < max.length) && (max.substring(0, 4) === '&lt;'))
            {
                if (value >= parseFloat(max.substring(4, max.length)))
                {
                    thisValidate.setError(e, thisValidate.maxValueErrorAttribute, thisValidate.defaultMaxValueError);
                }
            }
            else if (parseFloat(value) > max)
            {
                thisValidate.setError(e, thisValidate.maxValueErrorAttribute, thisValidate.defaultMaxValueError);
            }
        }
    };
    
    thisValidate.validateCustom = function validateCustom(e)
    {
        var customValidation = e[thisValidate.customAttribute];
        
        if (customValidation !== undefined)
        {
             if (customValidation(e) == false)
             {
                thisValidate.setError(e, thisValidate.equalsErrorAttribute);
             }
        }
    };
    
    thisValidate.validateEquals = function validateEquals(e)
    {
        // eventually this should be equipped to do string
        // comparison as well as other element comparisons
        
        var equal = e[thisValidate.equalsAttribute];
        var value = thisValidate.getValue(e);
        
        if ((value !== null) && (equal !== undefined) && (0 < equal.length))
        {
            if ((2 < equal.length) && (equal.substring(0, 2) === '!='))
            {
                if (value === equal.substring(2, equal.length))
                {
                    thisValidate.setError(e, thisValidate.equalsErrorAttribute, thisValidate.defaultEqualsError);
                }
            }
            else if ((2 < equal.length) && (equal.substring(0, 2) === '=='))
            {
                if (value !== equal.substring(2, equal.length))
                {
                    thisValidate.setError(e, thisValidate.equalsErrorAttribute, thisValidate.defaultEqualsError);
                }
            }
            else if (equal.charAt(0) === '=')
            {
                if (value !== equal.substring(1, equal.length))
                {
                    thisValidate.setError(e, thisValidate.equalsErrorAttribute, thisValidate.defaultEqualsError);
                }
            }
            else if (value !== equal)
            {
                thisValidate.setError(e, thisValidate.equalsErrorAttribute, thisValidate.defaultEqualsError);
            }
        }
    };
    var checkDateRangeExists = function (dateHidden2)
	{
			//Idtgv bug fix. the parent1 and parent2 are incorrect.
		var parent = dateHidden2.parent().parent();
		var parent2 = parent.parent();
		var noDateRangeIE = parent.is(':hidden');
		var noDateRangeNonIE = parent2.is(':hidden');
		var retVal = !(noDateRangeIE || noDateRangeNonIE);
		return retVal;
	};
    thisValidate.checkIfValidateDateRangeNeeded = function (e)
    {
        var date = e[thisValidate.dateRangeAttribute];
        var checkboxRefId = e[thisValidate.checkboxRefIdAttribute];
        var date1HiddenId = e[thisValidate.dateRange1HiddenIdAttribute];
        var date2HiddenId = e[thisValidate.dateRange2HiddenIdAttribute];
        var idLastChar = '';
        var idSuffix = '';
        var id = e.id;
        var startValidate = false;
        var dateRangeExists = false;
        var checkboxRef = null;
        var dateHidden1 = null;
        var dateHidden2 = null;
        
        if ((date !== undefined) && (0 < date.length))
        {
            //parse from the id the trailing "count" value
            //e.g. DROPDOWNLISTMARKETDAY2 -> extract 2
            idLastChar = id.charAt(id.length - 1);
            if (this.validateNumeric(idLastChar))
            {
                idSuffix = idLastChar;
            }

            //for flight search page only run check on the first month in the range
            if (('1' === idSuffix) || ('' === idSuffix))
            {
                // If one of the date range items is hidden then it's one way and the validation shouldn't check a pair of dates.
                checkboxRef = $('#' + checkboxRefId);
                dateHidden1 = $('#' + date1HiddenId);
                dateHidden2 = $('#' + date2HiddenId);
                dateRangeExists = checkDateRangeExists(dateHidden2);
                if ((dateRangeExists) && (checkboxRef.attr("checked") == true || checkboxRefId == null))
                {
                    startValidate = true;
                    thisValidate.dateRangeArray[0] = dateHidden1.val();
                    thisValidate.dateRangeArray[1] = dateHidden2.val();
                }
            }
        }
        return startValidate;
    };
    thisValidate.validateDateRange = function (e)
    {
        var marketDate = null;
        var datesInOrder = false;
        
        var startValidate = thisValidate.checkIfValidateDateRangeNeeded(e);
        
        if (startValidate)
        {
            marketDate = new SKYSALES.Class.MarketDate();
            
            datesNotPast = marketDate.datesNotPast(this.dateRangeArray);
            if (!datesNotPast)
            {
                this.setError(e, this.dateNotPastErrorAttribute, this.defaultError);
            }
        
            datesInOrder = marketDate.datesInOrder(this.dateRangeArray);
            if (!datesInOrder)
            {
                this.setError(e, this.dateRangeErrorAttribute, this.defaultError);
            }
        }
    };
    thisValidate.isExemptFromValidation = function (e)
    {
        if (e.id.indexOf(this.namespace) !== 0)
        {
            return true;
        }
        
        if (this.regexElementIdFilter && (!e.id.match(this.regexElementIdFilter)))
        {
            return true;
        } 
        
        return false;
    };
    
    // add validation type methods
    thisValidate.setValidateTypeError = function (e)
    {
        this.setError(e, this.validationTypeErrorAttribute, this.defaultValidationTypeError);
    };
    thisValidate.validateAmount = function (amount)
    {
        if ((!amount.match(this.amountPattern)) || (amount === 0))
        {
            return false;
        }
        
        return true;
    };
    thisValidate.validateDate = function (e, type, value)
    {
        var lowerCaseType = '';
        var today = new Date();
        if (type)
        {
            lowerCaseType = type.toLowerCase();
        }
        
        if ((lowerCaseType === 'dateyear') && ((value < today.getYear()) || (!value.match(thisValidate.dateYearPattern))))
        {
            return false;
        }
        //just make sure it is two digits for now
        else if ((lowerCaseType === 'datemonth') && (!value.match(thisValidate.dateMonthPattern)))
        {
            return false;
        }
        //just make sure it is two digits for now
        else if ((lowerCaseType === 'dateday') && (!value.match(thisValidate.DateDayPattern)))
        {
            return false;
        }
        
        return true;
    };
    thisValidate.validateMod10 = function (cardNumber)
    {
        var ccCheckRegExp = /\D/;
        var cardNumbersOnly = cardNumber.replace(/ /g, "");
        var numberProduct;
        var checkSumTotal = 0;
        var productDigitCounter = 0;
        var digitCounter = 0;
            
        if (!ccCheckRegExp.test(cardNumbersOnly))
        {    
            while (cardNumbersOnly.length < 16)
            {
                cardNumbersOnly = '0' + cardNumbersOnly;
            }

            for (digitCounter = cardNumbersOnly.length - 1; 0 <= digitCounter; digitCounter -= 2)
            {
                checkSumTotal += parseInt(cardNumbersOnly.charAt(digitCounter), 10);
                numberProduct = String((cardNumbersOnly.charAt(digitCounter - 1) * 2));
                for (productDigitCounter = 0; productDigitCounter < numberProduct.length; productDigitCounter += 1)
                {
                    checkSumTotal += parseInt(numberProduct.charAt(productDigitCounter), 10);
                }
            }

            return (checkSumTotal % 10 === 0);
        }
        return false;
    };
    thisValidate.validateNumeric = function (number)
    {
        number = number.replace(/\s/g, '');
        
        if (!number.match(thisValidate.numericPattern))
        {
            return false;
        }
        
        return true;
    };
    
    thisValidate.getValue = function (e)
    {
        return SKYSALES.Common.getValue(e);
    };
    
    //this.nonePattern = '^\.*$';
    thisValidate.stringPattern = /^.+$/;    
    thisValidate.upperCaseStringPattern = /^[A-Z]([A-Z|\s])*$/;
    thisValidate.numericPattern = /^\d+$/;
    thisValidate.numericStripper = /\D/g;
    thisValidate.alphaNumericPattern = /^\w+$/;
    
    thisValidate.amountPattern = /^([\d+\s]*((\.|,)\d+)*)$/;
    
    thisValidate.dateYearPattern = /^\d{4}$/;
    thisValidate.dateMonthPattern = /^\d{2}$/;
    thisValidate.dateDayPattern = /^\d{2}$/;
    
    thisValidate.emailPattern = /^\w+(\-*[\.\']?\-*\w+)*@\w+([\.\-\']?\w+)*(\.\w{1,8})$/;

};

var validateBySelector = function (selectorString)
{
    var validate = null;
    var clickedObj = null;
    if (selectorString !== undefined)
    {
        // run validation on the form elements
        validate = new SKYSALES.Validate(null, '', SKYSALES.errorsHeader, null);
        validate.clickedObj = clickedObj;
        validate.runBySelector(selectorString);
        return validate.outputErrors();
    }
    return true;
};

var validate = function (controlID, elementName, filter)
{
    var clickedObj = null;
    var validate = null;
    var e = null;
    //make sure we can run this javascript
    if (document.getElementById && document.createTextNode)
    {
        // check if you can getAttribute if you can it is an element use the id.
        if (controlID.getAttribute)
        {
            clickedObj = controlID;
            //Idtgv : bug fixing of the regEx
            controlID = controlID.getAttribute("id").replace(/_[^_]+$/, "");
        }
        validate = new SKYSALES.Validate(SKYSALES.getSkySalesForm(), controlID + '_', SKYSALES.errorsHeader, filter);
        validate.clickedObj = clickedObj;
        
        if (elementName)
        {
            e = elementName;
            if (!elementName.getAttribute)
            {
                e = document.getElementById(controlID + "_" + elementName);
            }
            validate.validateSingleElement(e);
            return validate.outputErrors();
        }
        
        return validate.run();
    }
    // could not use javascript rely on server validation
    return true;
};


var preventDoubleClick = function ()
{
    return true;
};


var preventDoubleClickDisabled = function (btn)
{
    if(btn.disabled)
		return false;
	else
	{
		return true;
		btn.disabled = true;
	}
};


var events = [];

var register = function (eventName, functionName)
{
    if (events[eventName] === undefined)
    {
        events[eventName] = [];
    }
    events[eventName][events[eventName].length]    = functionName;
};

var raise = function (eventName, eventArgs)
{
    var ix = 0;
    if (events[eventName] !== undefined)
    {
        for (ix = 0; ix < events[eventName].length; ix += 1)
        {
            if (eval(events[eventName][ix] + "(eventArgs)") === false)
            {
                return false;
            }
        }
    }
    return true;
};

var WindowInitialize = function ()
{
    /*extern raise */
    var originalOnLoad = window.onload;
    //fix this up so initialize is synched with everything else
    var windowLoadFunction = function ()
    {
        raise('WindowLoad', {});
        if (originalOnLoad)
        {
            originalOnLoad();
        }
    };
    $(window).ready(windowLoadFunction);
};

SKYSALES.Util.displayPopUpConverter = function ()
{
    var url = 'CurrencyConverter.aspx';
    var converterWindow = window.converterWindow;
    if (!window.converterWindow || converterWindow.closed)
    {
        converterWindow = window.open(url, 'converter', 'width=360,height=220,toolbar=0,status=0,location=0,menubar=0,scrollbars=0,resizable=0');
    }
    else
    {
        converterWindow.open(url, 'converter', 'width=360,height=220,toolbar=0,status=0,location=0,menubar=0,scrollbars=0,resizable=0');
        if ($(converterWindow).is(':hidden') === false)        
        {
            converterWindow.focus();
        }
    }
};

//Function to hide/show controls. Inputs are the control you want to hide and the dependent control 
//or which control is interacted with to trigger the hide/show of the other control.
var hideShow = function (hideControl, depControl)
{
    var controlHide = hideControl;
    var controlDepend = depControl;
     
    if (document.getElementById && document.getElementById(hideControl))
    {
        if (document.getElementById(controlDepend).checked === true)
        {
            document.getElementById(controlHide).style.display = "inline";
        }
        else
        {
            document.getElementById(controlHide).style.display = "none";
        }
    }
};
var jsLoadedCommon = true;

/* Page Behaviors */

//SKYSALES.toggleAtAGlanceEvent = function ()
//{
//    $(this).next().toggle();
//};
//SKYSALES.toggleAtAGlance = function ()
//{
//    $("div.atAGlanceDivHeader").click(SKYSALES.toggleAtAGlanceEvent);
//};

SKYSALES.initializeTime = function ()
{
    var i = 0;
    var timeOptions = "";
    for (i = 0; i < 23; i += 1)
    {
        timeOptions += "<option value=" + i + ">" + i + "</option>";
    }
    if (timeOptions !== "")
    {
        $("select.Time").append(timeOptions);
    }
};

$("a.animateMe").animate({
    height: 'toggle', 
    opacity: 'toggle'
}, "slow");


SKYSALES.aosAvailabilityShow = function ()
{
    $(this).parent().parent().find('div.hideShowParent').find('div.hideShow').show('slow');
    return false;
};

SKYSALES.aosAvailabilityHide = function ()
{
    $(this).parent().parent('.hideShow').hide('slow');
    return false;
};

SKYSALES.dropDownMenuEvent = function ()
{
    $("div.slideDownUp").toggle('fast');
    return false;
};

SKYSALES.faqHideShow = function () 
{
    $(this).parent('dt').next('.accordianSlideContent').slideToggle("slow");
};

SKYSALES.equipHideShow = function () 
{
    //alert('hey');
    $('div#moreSearchOptions').slideToggle("slow");
    return false;
};

SKYSALES.initializeAosAvailability = function ()
{
    /* AOS Availability */
    $('.hideShow').hide();
    $('a.showContent').click(SKYSALES.aosAvailabilityShow);
    $('a.hideContent').click(SKYSALES.aosAvailabilityHide);
    /* Drop-down menus */
    $('a.toggleSlideContent').click(SKYSALES.dropDownMenuEvent);
    
    $('a.accordian').click(SKYSALES.faqHideShow);
    
    
    $('a.showEquipOpt').click(SKYSALES.equipHideShow);
    $('a.hideEquipOpt').click(SKYSALES.equipHideShow);
};



//load metaobjects (used for validation)
SKYSALES.initializeMetaObjects = function ()
{
    $.metaobjects({clean: false});
};

SKYSALES.common = new SKYSALES.Common();


function formatCurrency(value) 
{
	var cents = 0;
	value = value.toString();	
	if (isNaN(value))
	{
		value = '0';
	}
	if (value.indexOf('.') > -1)
	{
		cents = value.substring(value.indexOf('.') + 1, value.length);
		
		value = value * 100;
	}	
	cents = value % 100;	
	if (cents > 0)
	{
		value = Math.floor(value / 100).toString();
	}	
	if (cents < 10)
	{
		cents = '0' + cents;
	}	
	for (var i = 0; i < Math.floor((value.length - (1 + i)) / 3); i += 1)	
	{
		value = value.substring(0, value.length - (4 * i + 3)) + ',' + value.substring(value.length - (4 * i + 3));
	}	
	return (value + '.' + cents);
}


SKYSALES.Util.sendAspFormFields = function ()
{   
    var clearAllValidity = null;
    var eventTargetElement = window.document.getElementById('eventTarget');
    var eventArgumentElement = window.document.getElementById('eventArgument');
    var viewStateElement = window.document.getElementById('viewState');
    var theForm = window.theForm;
    if (!theForm.onsubmit || (theForm.onsubmit() !== false))
    {
        eventTargetElement.name = '__EVENTTARGET';
        eventArgumentElement.name = '__EVENTARGUMENT';
        viewStateElement.name = '__VIEWSTATE';
        if (theForm.checkValidity)
        {
            clearAllValidity = function ()
            {
                $(this).removeAttr("required");
            };
            SKYSALES.common.getAllInputObjects().each(clearAllValidity);
        }
    }
    return true;
};

SKYSALES.Util.initStripeTable = function ()
{
    $('.hotelResult').hide();

    var stripeMeInputHandler = function ()
    {
        $('.stripeMe tr').removeClass("over");
        $(this).parent().parent().addClass("over");
    };
    $('.stripeMe input').click(stripeMeInputHandler);
};

SKYSALES.Util.ready = function ()
{
    $('form').submit(SKYSALES.Util.sendAspFormFields);

    //Turn validation object tags into javascript, this must run before initializeCommon
    SKYSALES.initializeMetaObjects();

    //Initialize Common
    SKYSALES.common.initializeCommon();

    //Initialize objects
    SKYSALES.Util.initObjects();
    
    SKYSALES.initializeSkySalesForm();
//    SKYSALES.toggleAtAGlance();
    SKYSALES.Util.initStripeTable();
    SKYSALES.initializeAosAvailability();
    
};
$(document).ready(SKYSALES.Util.ready);

/*Idtgv functions*/

var IDTGV = {};

IDTGV.Util = {};

IDTGV.Class = {};

IDTGV.Util.replaceQueryString = function(url,key,value) 
{
   var re = new RegExp("([?|&])" + key + "=.*?(&|$)","i");
   
   if (url.match(re))
   {
       return url.replace(re,'$1' + key + "=" + value + '$2');
   }
   else
   {
       if (url.indexOf('?') == -1)
       {
            return url + '?' + key + "=" + value;
       }
       else
       {
            return url + '&' + key + "=" + value;
       }
   }
       
}

IDTGV.Util.selectValueDropDownList = function(dropdownlist, value)
{
     if (dropdownlist)
     {
         for (i=0; i < dropdownlist.length ; i+=1)
         {
            if (dropdownlist.options[i].value == value)
            {
               dropdownlist.options[i].selected = true;
               break;
            }
         }
     }
     
}

IDTGV.Util.removeValueDropDownList = function(dropdownlist, value)
{
     if (dropdownlist)
     {         
         for (i=0; i < dropdownlist.length ; i+=1)
         {
            if (dropdownlist.options[i].value == value)
            {
               dropdownlist.remove(i);
            }
         }
     }    
}

IDTGV.Util.changeInputRequirementsFromDiv = function(divSelector, enableRequired)
{
    divSelector.find(":input").each( 
        function()
        {
            if ($(this)[0].required !== undefined)
            {
                if ( ($(this)[0].required == 'false') && (enableRequired == true))
                {
                    this.required = 'true';
                }
                else if ( ($(this)[0].required == 'true') && (enableRequired == false))
                {
                   this.required = 'false';
                }
            } 
        });
}


IDTGV.Util.initTBA = function(paxCount)
{
      var number = paxCount + 1;
      for (i=1; i < number ; i+=1)
      {
        var passengerInputContainerID = 'passengerInputContainer' + i;
        var inputList = $('#' + passengerInputContainerID).find(":input");
        for (j=0; j < inputList.length ; j++)
        {
            if ( inputList[j].value == 'TBA')
            {
                for (k=0; k < inputList.length ; k++)
                {
                    if (inputList[k].requiredempty)
                        inputList[k].value = inputList[k].requiredempty;
                    else
                        inputList[k].value = '';
                }
            }
        }
      }
}

IDTGV.Util.checkTBA = function(checked, idDiv)
{
      if(checked)
        $('#'+idDiv).hide();
      else
        $('#'+idDiv).show();
      //$('#'+idDiv).toggle();
      if (checked == true)
      {
        var mesInputs = $('#' + idDiv).find(":input");
        for (i=0; i < mesInputs.length ; i+=1)
        {
            if (mesInputs[i].required == 'true')
                mesInputs[i].required = 'false';
        
             mesInputs[i].value = "";
        }
      }
      else
      {
        var mesInputs = $('#' + idDiv).find(":input");
        for (i=0; i < mesInputs.length ; i+=1)
        {
            if (mesInputs[i].required == 'false')
                mesInputs[i].required = 'true';
        }
      }
}

IDTGV.Class.DateChecker = function(day, month, year)
{
	var thisDateChecker = this;
	thisDateChecker.day = day;
	thisDateChecker.month = month;
	thisDateChecker.year = year;
	
	thisDateChecker.checkDaysOfMonth = function()
	{
		if (this.month < 1 || this.month > 12 || this.day < 1 || this.day > 31)
		{
			return false;
		}
		daysInMonth = new Array(31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
		daysInFeb= (((this.year % 4 == 0) && ( (!(this.year % 100 == 0)) || (this.year % 400 == 0))) ? 29 : 28 );
		if ((this.month==2 && this.day>daysInFeb) || this.day > daysInMonth[this.month-1])
		{
			return false;
		}
		
		return true;
	}
	
	thisDateChecker.isFutureDate = function()
	{
		return !this.isPastDate();
	}
	
	thisDateChecker.isPastDate = function()
	{
		var today = new Date();
		if (today.getFullYear() > this.year ||(today.getFullYear() == this.year && today.getMonth() > (this.month-1)) ||(today.getFullYear() == 		this.year && today.getMonth() == (this.month-1) && today.getDate() > this.day) )
			return true;
		
		return false;
	}
}


/*
    Name: 
        Class Selectable
    Param:
        None
    Return: 
        An instance of Selectable
    Functionality:
        Makes html elements selectable based on css classes
    Notes:
        In order to use this class, call the createObject method.
        the json parameter expected is an array of elements with the properties "groupClass" and "itemSelectedCallback"
        for instance:
         SKYSALES.Class.Selectable.createObject(
        {
          "selectableGroupArray":
          [
          {
            "groupClass":"selectableJourney",
            "itemSelectedCallback": onJourneySelected
          },
          {
            "groupClass":"selectableAmbience",
            "itemSelectedCallback": onAmbienceSelected
          }
          ]
        });
        
        a group of selectable items are identified by the presence of a group class @groupClass. 
        each item with the class "@groupClass-unselected" is considered unselected.
        each item with the class "@groupClass-selected" is considered selected.
        when an unselected item is hovered, it gets the "@groupClass-unselected-hover" class. 
        when a unselected item is clicked, it gets selected and the previous selected item becomes unselected.
        
    Class Hierarchy:
        SkySales -> Selectable
*/
if (!SKYSALES.Class.Selectable)
{ 
    SKYSALES.Class.Selectable = function ()
    {   
        var parent = new SKYSALES.Class.SkySales();
        var thisSelectable = SKYSALES.Util.extendObject(parent);
        thisSelectable.selectableGroupArray = [];
        thisSelectable.unselectedClass = 'unselected';
        thisSelectable.selectedClass = 'selected';
        thisSelectable.hoverClass = 'unselected-hover';
            
        thisSelectable.init = function (paramObject)
        {
            this.setSettingsByObject(paramObject);
            this.setVars();
            this.addEvents();                              
        };
        
        thisSelectable.setSettingsByObject = function (json)
        {
            parent.setSettingsByObject.call(this, json);
        };
        
        thisSelectable.setVars = function() 
        { 
        };
        
        thisSelectable.addEvents = function() 
        {
            //foreach unselected item, adds the selectable events
            for (i=0; i <  this.selectableGroupArray.length; i++)
            {
               var selectableGroup = this.selectableGroupArray[i];
               var context = '.' + selectableGroup.groupClass + '-' + this.unselectedClass ;
			   $(context).each( function() { thisSelectable.addSelectionEventsItem(this,selectableGroup.groupClass,selectableGroup.itemSelectedCallback);});
            }          
        };
        
        thisSelectable.addSelectionEventsItem = function(item, groupClass, callback )
        {
             var selectedGroupClass = groupClass + '-' + thisSelectable.selectedClass;
             var unselectedGroupClass = groupClass + '-' + thisSelectable.unselectedClass;
             var hoverGroupClass = groupClass + '-' + thisSelectable.hoverClass;
             
             $(item).bind('mouseenter mouseleave',function(){$(this).toggleClass(hoverGroupClass);});
			 $(item).bind('click',
			    function() 
			    {              
			        var context = '.' + selectedGroupClass;		        
			        
			        // the previously selected items become selectable
			        $(context).each(
			            function()
			            {
			                $(this).removeClass(selectedGroupClass);
			                $(this).addClass(unselectedGroupClass);
			                thisSelectable.addSelectionEventsItem(this, groupClass, callback);
			            }                                   );
        			
			        //removes all the previous binded selectable events of the newly selected item
			        $(this).unbind('click');
			        $(this).unbind('mouseenter');
			        $(this).unbind('mouseleave');
			        $(this).removeClass(hoverGroupClass);
			        $(this).removeClass(unselectedGroupClass);
			        $(this).addClass(selectedGroupClass);

			        
			        //call the items selected callback
			        if (callback !== undefined)
			        {
			            callback(this);
			        }
			        
			        // stops propagation of the event
			        return false;			        
			    });
        };
           
        return thisSelectable;

    };
    //creates a new Selectable object.
    SKYSALES.Class.Selectable.createObject = function (json)
    {
        SKYSALES.Util.createObject('selectable', 'Selectable', json);
    };
}
