/*
* Autocomplete - jQuery plugin 1.0.2
*
* Copyright (c) 2007 Dylan Verheul, Dan G. Switzer, Anjesh Tuladhar, Jörn Zaefferer
*
* Dual licensed under the MIT and GPL licenses:
*   http://www.opensource.org/licenses/mit-license.php
*   http://www.gnu.org/licenses/gpl.html
*
* Revision: $Id: jquery.autocomplete.js 5747 2008-06-25 18:30:55Z joern.zaefferer $
*
*/

(function($) {

    $.fn.extend({
        autocomplete: function(urlOrData, options) {
            var isUrl = typeof urlOrData == "string";
            options = $.extend({}, $.Autocompleter.defaults, {
                url: isUrl ? urlOrData : null,
                data: isUrl ? null : urlOrData,
                delay: isUrl ? $.Autocompleter.defaults.delay : 10,
                max: options && !options.scroll ? 10 : 150
            }, options);

            // if highlight is set to false, replace it with a do-nothing function
            options.highlight = options.highlight || function(value) { return value; };

            // if the formatMatch option is not specified, then use formatItem for backwards compatibility
            options.formatMatch = options.formatMatch || options.formatItem;

            return this.each(function() {
                new $.Autocompleter(this, options);
            });
        },
        result: function(handler) {
            return this.bind("result", handler);
        },
        search: function(handler) {
            return this.trigger("search", [handler]);
        },
        flushCache: function() {
            return this.trigger("flushCache");
        },
        setOptions: function(options) {
            return this.trigger("setOptions", [options]);
        },
        unautocomplete: function() {
            return this.trigger("unautocomplete");
        }
    });

    $.Autocompleter = function(input, options) {

        var KEY = {
            UP: 38,
            DOWN: 40,
            DEL: 46,
            TAB: 9,
            RETURN: 13,
            ESC: 27,
            COMMA: 188,
            PAGEUP: 33,
            PAGEDOWN: 34,
            BACKSPACE: 8
        };

        // Create $ object for input element
        var $input = $(input).attr("autocomplete", "off");

        var timeout;
        var previousValue = "";
        var cache = $.Autocompleter.Cache(options);
        var hasFocus = 0;
        var lastKeyPressCode;
        var config = {
            mouseDownOnSelect: false
        };
        var select = $.Autocompleter.Select(options, input, selectCurrent, config);

        var blockSubmit;

        // prevent form submit in opera when selecting with return key
        $.browser.opera && $(input.form).bind("submit.autocomplete", function() {
            if (blockSubmit) {
                blockSubmit = false;
                return false;
            }
        });

        // only opera doesn't trigger keydown multiple times while pressed, others don't work with keypress at all
        $input.bind(($.browser.opera ? "keypress" : "keydown") + ".autocomplete", function(event) {
            // track last key pressed
            lastKeyPressCode = event.keyCode;
            switch (event.keyCode) {

                case KEY.UP:
                    event.preventDefault();
                    if (select.visible()) {
                        select.prev();
                    } else {
                        onChange(0, true);
                    }
                    break;

                case KEY.DOWN:
                    event.preventDefault();
                    if (select.visible()) {
                        select.next();
                    } else {
                        onChange(0, true);
                    }
                    break;

                case KEY.PAGEUP:
                    event.preventDefault();
                    if (select.visible()) {
                        select.pageUp();
                    } else {
                        onChange(0, true);
                    }
                    break;

                case KEY.PAGEDOWN:
                    event.preventDefault();
                    if (select.visible()) {
                        select.pageDown();
                    } else {
                        onChange(0, true);
                    }
                    break;

                // matches also semicolon            
                case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA:
                case KEY.TAB:
                case KEY.RETURN:
                    if (selectCurrent()) {
                        // stop default to prevent a form submit, Opera needs special handling
                        event.preventDefault();
                        blockSubmit = true;
                        return false;
                    }
                    break;

                case KEY.ESC:
                    select.hide();
                    break;

                default:
                    clearTimeout(timeout);
                    timeout = setTimeout(onChange, options.delay);
                    break;
            }
        }).focus(function() {
            // track whether the field has focus, we shouldn't process any
            // results if the field no longer has focus
            hasFocus++;
        }).blur(function() {
            hasFocus = 0;
            if (!config.mouseDownOnSelect) {
                hideResults();
            }
        }).click(function() {
            // show select when clicking in a focused field
            if (hasFocus++ > 1 && !select.visible()) {
                onChange(0, true);
            }
        }).bind("search", function() {
            // TODO why not just specifying both arguments?
            var fn = (arguments.length > 1) ? arguments[1] : null;
            function findValueCallback(q, data) {
                var result;
                if (data && data.length) {
                    for (var i = 0; i < data.length; i++) {
                        if (data[i].result.toLowerCase() == q.toLowerCase()) {
                            result = data[i];
                            break;
                        }
                    }
                }
                if (typeof fn == "function") fn(result);
                else $input.trigger("result", result && [result.data, result.value]);
            }
            $.each(trimWords($input.val()), function(i, value) {
                request(value, findValueCallback, findValueCallback);
            });
        }).bind("flushCache", function() {
            cache.flush();
        }).bind("setOptions", function() {
            $.extend(options, arguments[1]);
            // if we've updated the data, repopulate
            if ("data" in arguments[1])
                cache.populate();
        }).bind("unautocomplete", function() {
            select.unbind();
            $input.unbind();
            $(input.form).unbind(".autocomplete");
        });


        function selectCurrent() {
            var selected = select.selected();
            if (!selected)
                return false;

            var v = selected.result;
            previousValue = v;

            if (options.multiple) {
                var words = trimWords($input.val());
                if (words.length > 1) {
                    v = words.slice(0, words.length - 1).join(options.multipleSeparator) + options.multipleSeparator + v;
                }
                v += options.multipleSeparator;
            }

            $input.val(v);
            hideResultsNow();
            $input.trigger("result", [selected.data, selected.value]);
            return true;
        }

        function onChange(crap, skipPrevCheck) {
            if (lastKeyPressCode == KEY.DEL) {
                select.hide();
                return;
            }

            var currentValue = $input.val();

            if (!skipPrevCheck && currentValue == previousValue)
                return;

            previousValue = currentValue;

            currentValue = lastWord(currentValue);
            if (currentValue.length >= options.minChars) {
                $input.addClass(options.loadingClass);
                $input.next().show();
                if (!options.matchCase)
                    currentValue = currentValue.toLowerCase();
                request(currentValue, receiveData, hideResultsNow);
            } else {
                stopLoading();
                select.hide();
            }
        };

        function trimWords(value) {
            if (!value) {
                return [""];
            }
            var words = value.split(options.multipleSeparator);
            var result = [];
            $.each(words, function(i, value) {
                if ($.trim(value))
                    result[i] = $.trim(value);
            });
            return result;
        }

        function lastWord(value) {
            if (!options.multiple)
                return value;
            var words = trimWords(value);
            return words[words.length - 1];
        }

        // fills in the input box w/the first match (assumed to be the best match)
        // q: the term entered
        // sValue: the first matching result
        function autoFill(q, sValue) {
            // autofill in the complete box w/the first match as long as the user hasn't entered in more data
            // if the last user key pressed was backspace, don't autofill
            if (options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE) {
                // fill in the value (keep the case the user has typed)
                $input.val($input.val() + sValue.substring(lastWord(previousValue).length));
                // select the portion of the value not typed by the user (so the next character will erase)
                $.Autocompleter.Selection(input, previousValue.length, previousValue.length + sValue.length);
            }
        };

        function hideResults() {
            clearTimeout(timeout);
            timeout = setTimeout(hideResultsNow, 200);
        };

        function hideResultsNow() {
            var wasVisible = select.visible();
            select.hide();
            clearTimeout(timeout);
            stopLoading();
            if (options.mustMatch) {
                // call search and run callback
                $input.search(
				function(result) {
				    // if no value found, clear the input box
				    if (!result) {
				        if (options.multiple) {
				            var words = trimWords($input.val()).slice(0, -1);
				            $input.val(words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : ""));
				        }
				        else
				            $input.val("");
				    }
				}
			);
            }
            if (wasVisible)
            // position cursor at end of input field
                $.Autocompleter.Selection(input, input.value.length, input.value.length);
        };

        function receiveData(q, data) {
            if (data && data.length && hasFocus) {
                stopLoading();
                select.display(data, q);
                autoFill(q, data[0].value);
                select.show();
            } else {
                hideResultsNow();
            }
        };

        function request(term, success, failure) {
            if (!options.matchCase)
                term = term.toLowerCase();
            var data = cache.load(term);
            // recieve the cached data
            if (data && data.length) {
                success(term, data);
                // if an AJAX url has been supplied, try loading the data now
            } else if ((typeof options.url == "string") && (options.url.length > 0)) {

                var extraParams = {
                    timestamp: +new Date()
                };
                $.each(options.extraParams, function(key, param) {
                    extraParams[key] = typeof param == "function" ? param() : param;
                });

                $.ajax({
                    // try to leverage ajaxQueue plugin to abort previous requests
                    mode: "abort",
                    // limit abortion to this input
                    port: "autocomplete" + input.name,
                    dataType: options.dataType,
                    url: options.url,
                    data: $.extend({
                        q: lastWord(term),
                        limit: options.max
                    }, extraParams),
                    success: function(data) {

                        var parsed = options.parse && options.parse(data) || parse(data);
                        cache.add(term, parsed);
                        success(term, parsed);
                    }
                });
            } else {
                // if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match
                select.emptyList();
                failure(term);
            }
        };

        function parse(data) {
            var parsed = [];
            var rows = data.split("\n");
            for (var i = 0; i < rows.length; i++) {
                var row = $.trim(rows[i]);
                if (row) {
                    row = row.split("|");
                    parsed[parsed.length] = {
                        data: row,
                        value: row[0],
                        result: options.formatResult && options.formatResult(row, row[0]) || row[0]
                    };
                }
            }
            return parsed;
        };

        function stopLoading() {
            $input.removeClass(options.loadingClass);
            $input.next().hide();
        };

    };

    $.Autocompleter.defaults = {
        resultsClass: "ac_results",
        loadingClass: "ac_loading",
        minChars: 1,
        delay: 400,
        matchCase: false,
        matchSubset: true,
        matchContains: false,
        cacheLength: 10,
        max: 100,
        mustMatch: false,
        extraParams: {},
        selectFirst: true,
        formatItem: function(row) { return row[0]; },
        formatMatch: null,
        autoFill: false,
        width: 0,
        multiple: false,
        multipleSeparator: ", ",
        highlight: function(value, term) {
            return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
        },
        scroll: true,
        scrollHeight: 250
    };

    $.Autocompleter.Cache = function(options) {

        var data = {};
        var length = 0;

        function matchSubset(s, sub) {
            if (!options.matchCase)
                s = s.toLowerCase();
            var i = s.indexOf(sub);
            if (i == -1) return false;
            return i == 0 || options.matchContains;
        };

        function add(q, value) {
            if (length > options.cacheLength) {
                flush();
            }
            if (!data[q]) {
                length++;
            }
            data[q] = value;
        }

        function populate() {
            if (!options.data) return false;
            // track the matches
            var stMatchSets = {},
			nullData = 0;

            // no url was specified, we need to adjust the cache length to make sure it fits the local data store
            if (!options.url) options.cacheLength = 1;

            // track all options for minChars = 0
            stMatchSets[""] = [];
            // loop through the array and create a lookup structure
            for (var i = 0, ol = options.data.length; i < ol; i++) {
                var rawValue = options.data[i];
                // if rawValue is a string, make an array otherwise just reference the array
                rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue;

                var value = options.formatMatch(rawValue, i + 1, options.data.length);
                if (value === false)
                    continue;

                var firstChar = value.charAt(0).toLowerCase();
                // if no lookup array for this character exists, look it up now
                if (!stMatchSets[firstChar])
                    stMatchSets[firstChar] = [];

                // if the match is a string
                var row = {
                    value: value,
                    data: rawValue,
                    result: options.formatResult && options.formatResult(rawValue) || value
                };

                // push the current match into the set list
                stMatchSets[firstChar].push(row);

                // keep track of minChars zero items
                if (nullData++ < options.max) {
                    stMatchSets[""].push(row);
                }
            };

            // add the data items to the cache
            $.each(stMatchSets, function(i, value) {
                // increase the cache size
                options.cacheLength++;
                // add to the cache
                add(i, value);
            });
        }

        // populate any existing data
        setTimeout(populate, 25);

        function flush() {
            data = {};
            length = 0;
        }

        return {
            flush: flush,
            add: add,
            populate: populate,
            load: function(q) {
                if (!options.cacheLength || !length)
                    return null;
                /* 
                * if dealing w/local data and matchContains than we must make sure
                * to loop through all the data collections looking for matches
                */
                if (!options.url && options.matchContains) {
                    // track all matches
                    var csub = [];
                    // loop through all the data grids for matches
                    for (var k in data) {
                        // don't search through the stMatchSets[""] (minChars: 0) cache
                        // this prevents duplicates
                        if (k.length > 0) {
                            var c = data[k];
                            $.each(c, function(i, x) {
                                // if we've got a match, add it to the array
                                if (matchSubset(x.value, q)) {
                                    csub.push(x);
                                }
                            });
                        }
                    }
                    return csub;
                } else
                // if the exact item exists, use it
                    if (data[q]) {
                    return data[q];
                } else
                    if (options.matchSubset) {
                    for (var i = q.length - 1; i >= options.minChars; i--) {
                        var c = data[q.substr(0, i)];
                        if (c) {
                            var csub = [];
                            $.each(c, function(i, x) {
                                if (matchSubset(x.value, q)) {
                                    csub[csub.length] = x;
                                }
                            });
                            return csub;
                        }
                    }
                }
                return null;
            }
        };
    };

    $.Autocompleter.Select = function(options, input, select, config) {
        var CLASSES = {
            ACTIVE: "ac_over"
        };

        var listItems,
		active = -1,
		data,
		term = "",
		needsInit = true,
		element,
		list;

        // Create results
        function init() {
            if (!needsInit)
                return;
            element = $("<div/>")
		.hide()
		.addClass(options.resultsClass)
		.attr("id", "ac_results")
		.css("position", "absolute")
		.appendTo(document.body);

            list = $("<ul/>").appendTo(element).mouseover(function(event) {
                if (target(event).nodeName && target(event).nodeName.toUpperCase() == 'LI') {
                    active = $("li", list).removeClass(CLASSES.ACTIVE).index(target(event));
                    $(target(event)).addClass(CLASSES.ACTIVE);
                }
            }).click(function(event) {
                $(target(event)).addClass(CLASSES.ACTIVE);
                select();
                // TODO provide option to avoid setting focus again after selection? useful for cleanup-on-focus
                input.focus();
                return false;
            }).mousedown(function() {
                config.mouseDownOnSelect = true;
            }).mouseup(function() {
                config.mouseDownOnSelect = false;
            });

            if (options.width > 0)
                element.css("width", options.width);

            needsInit = false;
        }

        function target(event) {
            var element = event.target;
            while (element && element.tagName != "LI")
                element = element.parentNode;
            // more fun with IE, sometimes event.target is empty, just ignore it then
            if (!element)
                return [];
            return element;
        }

        function moveSelect(step) {
            listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
            movePosition(step);
            var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);
            if (options.scroll) {
                var offset = 0;
                listItems.slice(0, active).each(function() {
                    offset += this.offsetHeight;
                });
                if ((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
                    list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());
                } else if (offset < list.scrollTop()) {
                    list.scrollTop(offset);
                }
            }
        };

        function movePosition(step) {
            active += step;
            if (active < 0) {
                active = listItems.size() - 1;
            } else if (active >= listItems.size()) {
                active = 0;
            }
        }

        function limitNumberOfItems(available) {
            return options.max && options.max < available
			? options.max
			: available;
        }

        function fillList() {
            list.empty();
            var max = limitNumberOfItems(data.length);
            for (var i = 0; i < max; i++) {
                if (!data[i])
                    continue;
                var formatted = options.formatItem(data[i].data, i + 1, max, data[i].value, term);
                if (formatted === false)
                    continue;
                var li = $("<li/>").html(options.highlight(formatted, term)).addClass(i % 2 == 0 ? "ac_even" : "ac_odd").appendTo(list)[0];
                $.data(li, "ac_data", data[i]);
            }
            listItems = list.find("li");


            if (options.selectFirst) {
                listItems.slice(0, 1).addClass(CLASSES.ACTIVE);
                active = 0;
            }

            // apply bgiframe if available
            if ($.fn.bgiframe)
                list.bgiframe();
        }

        return {
            display: function(d, q) {
                init();
                data = d;
                term = q;
                fillList();
            },
            next: function() {
                moveSelect(1);
            },
            prev: function() {
                moveSelect(-1);
            },
            pageUp: function() {
                if (active != 0 && active - 8 < 0) {
                    moveSelect(-active);
                } else {
                    moveSelect(-8);
                }
            },
            pageDown: function() {
                if (active != listItems.size() - 1 && active + 8 > listItems.size()) {
                    moveSelect(listItems.size() - 1 - active);
                } else {
                    moveSelect(8);
                }
            },
            hide: function() {
                element && element.hide();
                listItems && listItems.removeClass(CLASSES.ACTIVE);
                active = -1;
            },
            visible: function() {
                return element && element.is(":visible");
            },
            current: function() {
                return this.visible() && (listItems.filter("." + CLASSES.ACTIVE)[0] || options.selectFirst && listItems[0]);
            },
            show: function() {
                var offset = $(input).offset();
                if ($.browser.msie) {
                    element.css({
                        width: $(input).width(),
                        top: offset.top + input.offsetHeight,
                        left: offset.left
                    }).show();
                }
                else {
                    element.css({
                        width: typeof options.width == "string" || options.width > 0 ? options.width : $(input).width(),
                        top: offset.top + input.offsetHeight,
                        left: offset.left
                    }).show();
                }
                if (options.scroll) {
                    list.scrollTop(0);
                    list.css({
                        maxHeight: options.scrollHeight,
                        overflow: 'auto'
                    });

                    if ($.browser.msie && typeof document.body.style.maxHeight === "undefined") {
                        var listHeight = 0;
                        listItems.each(function() {
                            listHeight += this.offsetHeight;
                        });
                        var scrollbarsVisible = listHeight > options.scrollHeight;
                        list.css('height', scrollbarsVisible ? options.scrollHeight : listHeight);
                        if (!scrollbarsVisible) {
                            // IE doesn't recalculate width when scrollbar disappears
                            listItems.width(list.width() - parseInt(listItems.css("padding-left")) - parseInt(listItems.css("padding-right")));
                        }
                    }

                }
            },
            selected: function() {
                var selected = listItems && listItems.filter("." + CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);
                return selected && selected.length && $.data(selected[0], "ac_data");
            },
            emptyList: function() {
                list && list.empty();
            },
            unbind: function() {
                element && element.remove();
            }
        };
    };

    $.Autocompleter.Selection = function(field, start, end) {
        try {
            if (field.createTextRange) {
                var selRange = field.createTextRange();
                selRange.collapse(true);
                selRange.moveStart("character", start);
                selRange.moveEnd("character", end);
                selRange.select();
            } else if (field.setSelectionRange) {
                field.setSelectionRange(start, end);
            } else {
                if (field.selectionStart) {
                    field.selectionStart = start;
                    field.selectionEnd = end;
                }
            }
            field.focus();
        } catch (e) {
        }
    };

})(jQuery);SearchEngineCookie = function(){}
//saves the search type
SearchEngineCookie.SetSearchBy = function(strSearchBy) {
var oSECookie = SearchEngineCookie.GetSearchCookie()
    oSECookie.searchBy = strSearchBy;
    SaveCookie(oSECookie);
}

SearchEngineCookie.SetLocationForDre = function(strLocation) {
var oSECookie = SearchEngineCookie.GetSearchCookie();
    oSECookie.suburb = strLocation;
    SaveCookie(oSECookie);
}

//saves the location 
SearchEngineCookie.SetLocationCookie = function(strCountry, strCity, strSuburb) {
var oSECookie = SearchEngineCookie.GetSearchCookie()
    oSECookie.country = strCountry;
    oSECookie.city = strCity;
    oSECookie.suburb = strSuburb;
    SaveCookie(oSECookie);
}

//save dates to cookie
SearchEngineCookie.SetDatesCookie = function(inDate, outDate) {
    var oSECookie = SearchEngineCookie.GetSearchCookie();
    oSECookie.inDate = inDate;
    oSECookie.outDate = outDate;
    SaveCookie(oSECookie);
}

SearchEngineCookie.SetSearchEngineCookieForDRE = function(inDate, outDate, strLocation) {
    var oSECookie = SearchEngineCookie.GetSearchCookie();
    oSECookie.inDate = inDate;
    oSECookie.outDate = outDate;
    oSECookie.suburb = strLocation;
    oSECookie.searchBy = "LocationKey";
    SaveCookie(oSECookie);
}


SearchEngineCookie.SetSearchEngineCookie = function(inDate, outDate, strCountry, strCity, strSuburb) {
    var oSECookie = SearchEngineCookie.GetSearchCookie();
    oSECookie.inDate = inDate;
    oSECookie.outDate = outDate;
    oSECookie.country = strCountry;
    oSECookie.city = strCity;
    oSECookie.suburb = strSuburb;
    oSECookie.searchBy = "criteria";
    SaveCookie(oSECookie);
}

SearchEngineCookie.SetSearchEngineCookieWithSearchBy = function(inDate, outDate, strCountry, strCity, strSuburb , strSearchBy) {
    var oSECookie = SearchEngineCookie.GetSearchCookie();
    oSECookie.inDate = inDate;
    oSECookie.outDate = outDate;
    oSECookie.country = strCountry;
    oSECookie.city = strCity;
    oSECookie.suburb = strSuburb;
    oSECookie.searchBy = strSearchBy;
    SaveCookie(oSECookie);
}


function SaveCookie(oSECookie) {
    var CheckinDate;   
    var CheckoutDate;    
    var dfmt = GetDateFormat();

    var inDArray;
    var outDArray;
    if (oSECookie.inDate.indexOf("/") > 0) {
        inDArray = oSECookie.inDate.split("/")
        outDArray = oSECookie.outDate.split("/")
    }
    else {
        inDArray = oSECookie.inDate.split("-")
        outDArray = oSECookie.outDate.split("-")
    }


    if (dfmt == "dd/mm/yyyy") {
        defInD = inDArray[0]
        defInM = inDArray[1]
        defInY = inDArray[2]
        defOutD = outDArray[0]
        defOutM = outDArray[1]
        defOutY = outDArray[2]
    }
    else if (dfmt == "yyyy/mm/dd") {
        defInY = inDArray[0]
        defInM = inDArray[1]
        defInD = inDArray[2]
        defOutY = outDArray[0]
        defOutM = outDArray[1]
        defOutD = outDArray[2]
    }

    var strInDate = defInY + "-" + defInM + "-" + defInD;
    var strOutDate = defOutY + "-" + defOutM + "-" + defOutD;
    document.cookie =
		escape("|SearchEng|") + "=" +
		escape("|" + oSECookie.country + "|" + oSECookie.city + "|" + oSECookie.suburb + "|" + strInDate + "|" + strOutDate + "|" + oSECookie.searchBy + "|") +
		";path=/"
}

function GetDateFormat() {
    if (typeof (window['calDateFormat']) != 'undefined') {
        if (calDateFormat == "yyyy/mm/dd")
            return "yyyy/mm/dd";
        else if (calDateFormat == "dd/mm/yyyy")
            return "dd/mm/yyyy";
    }
    else {
        return "dd/mm/yyyy";
    }
}

//returns object containing search engine cookie elements
SearchEngineCookie.GetSearchCookie = function() {
    
    var oSECookie = new Object()
    oSECookie.searchBy = ""
    oSECookie.country = ""
    oSECookie.city = ""
    oSECookie.suburb = ""
    oSECookie.inDate = ""
    oSECookie.outDate = ""

    var cookieArray = URLDecode(document.cookie).split("|")

    for (var i = 0; i < cookieArray.length; i++) {
        if (cookieArray[i] == "SearchEng") {
            oSECookie.country = cookieArray[i + 2]
            oSECookie.city = cookieArray[i + 3]
            oSECookie.suburb = cookieArray[i + 4]
            oSECookie.inDate = cookieArray[i + 5]
            oSECookie.outDate = cookieArray[i + 6]
            oSECookie.searchBy = cookieArray[i + 7]
            break
        }
    }
    return oSECookie
}


function ProcessSearchEngineSubmit() {
    
    if (ValidateDate()) {
        var strChkin = document.getElementById('Cal1').value;
        var strChkout = document.getElementById('Cal2').value;
        var strCountry = document.getElementById('country').value;
        var strCity = document.getElementById('city_region').value;
        var strSuburb = document.getElementById('location').value;
        var strSrchBy = document.getElementById('SearchBy').value;
        SearchEngineCookie.SetSearchEngineCookieWithSearchBy(strChkin, strChkout, strCountry, strCity, strSuburb, strSrchBy);
        //return false;
        return true;        
    }
    else {
        return false;
    }
    

}//SEP03
var AXPAGE = "ajaxxsl.asp";
var HINT_DRE = "City, Region, Suburb or Landmark"
var gc_country = "";
var gc_city = "";
var gc_suburb = "";
var gc_searchby = "";
var gc_lc = "";

var _cache = new Cache(); //Cache object

function UpdateDirectHotelLink() {
    var checkInDate, checkOutDate;
    checkInDate = document.getElementById("inYear").value + "-" + document.getElementById("inMonth").value + "-" + document.getElementById("inDay").value
    checkOutDate = document.getElementById("outYear").value + "-" + document.getElementById("outMonth").value + "-" + document.getElementById("outDay").value

    for (var i = 0; i < 3; i++) {
        var LMDealUrl, lmArr1, lmArr2;
        if (document.getElementById("LMDeals" + i).href) {
            lmArr1 = document.getElementById("LMDeals" + i).href.split("Checkin=");
            lmArr2 = lmArr1[1].split("Checkout=");

            if (document.getElementById("LMDeals" + i).href) {
                LMDealUrl = lmArr1[0] + "Checkin=" + checkInDate + "&Checkout=" + checkOutDate;
                document.getElementById("LMDeals" + i).href = LMDealUrl;
            }
        }
    }

    var MemberReviewUrl, mrArr1, mrArr2;
    if (document.getElementById("MemberReview").href) {
        mrArr1 = document.getElementById("MemberReview").href.split("Checkin=");
        mrArr2 = mrArr1[1].split("Checkout=");

        if (document.getElementById("MemberReview").href) {
            MemberReviewUrl = mrArr1[0] + "Checkin=" + checkInDate + "&Checkout=" + checkOutDate;
            document.getElementById("MemberReview").href = MemberReviewUrl;
        }
    }
}

function changeSearchByAndLMDeals() {
    document.getElementById('SearchBy').value = 'LocationKey';
    FavTopCitiesLMDealsAJAXRequest(document.getElementById('country').value, "");
}

function changeToClassicSearch(ctl) {
    FavTopCitiesLMDealsAJAXRequest(document.getElementById('country').value, document.getElementById('city').value);
}

function FavTopCitiesLMDealsAJAXRequest(county, city) {
    var destinationControl;
    var action;
    action = "getlmdeals";
    destinationControl = "divfavtopcitieslmdeals";

    $("#" + destinationControl).html("<div id='pageloaderwrap'><img src='SiteEngine/HTC/images/page-loader-grey.gif' alt='' width='94' height='12' /><br /><span>Loading ...</span></div>");
    $.ajax({
        url: AXPAGE + '?action=' + action + '&country=' + county + '&city=' + escape(city) + "&proxyid=" + DRE_GUID,
        type: 'get',
        cache: true,
        success: function(results) {
            $("#" + destinationControl).html(results);
        }
    });
}

function loginmember() {

    var destinationControl;
    var action;
    var email;
    var password;

    email = $('#email').val();
    password = $('#pwd').val();
    $("#error_message").hide();

    action = "validatememberlogin";
    destinationControl = "MemberLoginTemplate";

    $("#loadingmemberlogin").show();
    $("#MemberLoginTemplate").hide();

    $.ajax({
        url: AXPAGE + '?action=' + action + '&email=' + email + '&password=' + password + "&proxyid=" + DRE_GUID,
        type: 'get',
        cache: true,
        success: function(results) {
            $("#loadingmemberlogin").hide();
            $("#MemberLoginTemplate").show();
            if (results == "") {
                $("#error_message").show();
            }
            else {
                $("#error_message").hide();
                $("#" + destinationControl).html(results);
            }
        }

    });

}

function logoutMember(destControl, destTemplate) {

    var destinationControl;
    destinationControl = destControl;
    $.ajax({
        url: AXPAGE + "?action=logoutMember" + "&proxyid=" + DRE_GUID + "&template=" + destTemplate,
        type: 'get',
        cache: true,
        success: function(results) {
            $("#" + destinationControl).html(results);
        }

    });

}

/* Ajax Load for Search Box using JQuery syntax */


$(function() {



    if ($.browser.opera) {
        LoadSearchEngineFromCookie();
    }
    else {
        // Initiate Lm Deals population
        //FavTopCitiesLMDealsAJAXRequest($("select#country").val(), $("select#city_region").val());
    }

    function FadeSearchEngine() {
        $('#TabbedPanels1 :input').attr('disabled', true);
        $('#TabbedPanels1 :input').css('opacity', '0.1');
        $('#TabbedPanels1 :input').css('filter', 'alpha(opacity=10)');
        $('#TabbedPanels1 :input').css('-ms-filter', 'progid:DXImageTransform.Microsoft.Alpha(opacity=10)');
    }

    function ShineSearchEngine() {
        $('#TabbedPanels1 :input').attr('disabled', false);
        $('#TabbedPanels1 :input').css('opacity', '');
        $('#TabbedPanels1 :input').css('filter', '');
        $('#TabbedPanels1 :input').css('-ms-filter', '');
    }

    function FadeDetailSearch() {
        $('#detailedsearch :input').attr('disabled', true);
        $('#detailedsearch :input').css('opacity', '0.1');
        $('#detailedsearch :input').css('filter', 'alpha(opacity=10)');
        $('#detailedsearch :input').css('-ms-filter', 'progid:DXImageTransform.Microsoft.Alpha(opacity=10)');
    }

    function ShineDetailSearch() {
        $('#detailedsearch :input').attr('disabled', false);
        $('#detailedsearch :input').css('opacity', '');
        $('#detailedsearch :input').css('filter', '');
        $('#detailedsearch :input').css('-ms-filter', '');
    }


    function LoadSearchEngineFromCookie() {

        // FadeSearchEngine();


        // Populate from coolie to gc_ variables
        ReadFromCookie()

        if (gc_searchby.toLowerCase() == "criteria") {
            $("#default_search").val("dest")
            switchoption();
        }
        else if (gc_searchby.toLowerCase() == "locationkey" || gc_searchby.toLowerCase() == "name") {
            $("#default_search").val("crit")
            if (gc_searchby.toLowerCase() == "locationkey") {
                $("#sbdest").attr("checked", "true");
            }
            else if (gc_searchby.toLowerCase() == "name") {
                $("#sbhname").attr("checked", "true");
            }
            if (gc_lc.toLowerCase() == "en") switchoption();
            //ShineSearchEngine();
            // FadeDetailSearch();
        }
        else {
            var i;
            i = 0;
            // ShineSearchEngine();
            //  FadeDetailSearch();
        }


        // select coumtry if cookie as country
        if (gc_country != "") {
            $("#country").val(gc_country);
        }

        var cityname;
        $.getJSON(AXPAGE, { param1: $("#country").val(), action: 'getcities', proxyid: DRE_GUID }, function(j) {
            _cache.setItem("C_" + $("#country").val(), j);
            //$.jCache.setItem("C_" + $("#country").val(), j);
            popCities(j);
            // select city
            if (gc_city != "") {
                $("#city_region").val(gc_city);
            }
            // Initiate Lm Deals population
            FavTopCitiesLMDealsAJAXRequest($("select#country").val(), $("select#city_region").val());
            $.getJSON(AXPAGE, { param1: $("#city_region").val(), action: 'getlocations', proxyid: DRE_GUID }, function(j) {
                _cache.setItem("L_" + $("#city_region").val(), j);
                //$.jCache.setItem("L_" + $("#city_region").val(), j);
                popLoc(j)
                // select location
                $("#location").val(gc_suburb);
            });

        });

    }

    $("select#country").change(function() {
        $("#city_regionAJAXloading").show();
        if (_cache.getItem("C_" + $("#country").val())) {
            var k = _cache.getItem("C_" + $("#country").val())
            popCitiesAndLoc(k);
            FavTopCitiesLMDealsAJAXRequest($("select#country").val(), $("select#city_region").val());
            return;
        }
        /*
        if ($.jCache.hasItem("C_" + $("#country").val())) {
        var k = $.jCache.getItem("C_" + $("#country").val());
        popCitiesAndLoc(k);
        FavTopCitiesLMDealsAJAXRequest($("select#country").val(), $("select#city_region").val());
        return;
        }
        */
        $.getJSON(AXPAGE, { param1: $(this).val(), action: 'getcities', proxyid: DRE_GUID }, function(j) {
            _cache.setItem("C_" + $("#country").val(), j);
            //$.jCache.setItem("C_" + $("#country").val(), j);
            popCitiesAndLoc(j);
            SaveCookieFromClient();
            FavTopCitiesLMDealsAJAXRequest($("select#country").val(), $("select#city_region").val());
        });
    });

    /*

    function popCities(j) {
    var options = '';
    ct = j.cities;
    for (var i = 0; i < ct.length; i++) {
    if (ct[i].name != -2)
    options += '<option value="' + ct[i].name + '">' + ct[i].displayname + '</option>';
    else
    options += '<option disabled="disabled" value="' + ct[i].name + '">' + ct[i].displayname + '</option>';
    }
    $("select#city_region").html(options);

        $("#city_regionAJAXloading").hide();
    }



    function popCitiesAndLoc(j) {
    var options = '';
    ct = j.cities;
    for (var i = 0; i < ct.length; i++) {
    if (ct[i].name != -2)
    options += '<option value="' + ct[i].name + '">' + ct[i].displayname + '</option>';
    else
    options += '<option disabled="disabled" value="' + ct[i].name + '">' + ct[i].displayname + '</option>';
    }
    $("select#city_region").html(options);

        options = '';
    lo = j.locations;

        for (var i = 0; i < lo.length; i++) {
    options += '<option value="' + lo[i].name + '">' + lo[i].displayname + '</option>';
    }
    $("select#location").html(options);
    $("#city_regionAJAXloading").hide();
    }

    function popLoc(j) {
    var options = '';
    lo = j.locations;

        for (var i = 0; i < lo.length; i++) {
    options += '<option value="' + lo[i].name + '">' + lo[i].displayname + '</option>';
    }
    $("select#location").html(options);
    $("#locationAJAXloading").hide();
    }
    
    */

    function popCities(j) {
        var options = '';

        dc = j.DefaultCities;

        for (var i = 0; i < dc.length; i++) {
            if (dc[i].Name != -2)
                options += '<option value="' + dc[i].Name + '">' + dc[i].DisplayName + '</option>';
            else
                options += '<option disabled="disabled" value="' + dc[i].Name + '">' + dc[i].DisplayName + '</option>';
        }
        if (dc.length > 0)
            options += '<option disabled="disabled" value="-2">---------------</option>';
        ct = j.Cities;
        for (var i = 0; i < ct.length; i++) {
            if (ct[i].Name != -2)
                options += '<option value="' + ct[i].Name + '">' + ct[i].DisplayName + '</option>';
            else
                options += '<option disabled="disabled" value="' + ct[i].Name + '">' + ct[i].DisplayName + '</option>';
        }
        $("select#city_region").html(options);

        $("#city_regionAJAXloading").hide();
    }



    function popCitiesAndLoc(j) {
        var options = '';
        ct = j.Cities;

        dc = j.DefaultCities;

        for (var i = 0; i < dc.length; i++) {
            if (dc[i].Name != -2)
                options += '<option value="' + dc[i].Name + '">' + dc[i].DisplayName + '</option>';
            else
                options += '<option disabled="disabled" value="' + dc[i].Name + '">' + dc[i].DisplayName + '</option>';
        }
        if (dc.length > 0)
            options += '<option disabled="disabled" value="-2">---------------</option>';
        for (var i = 0; i < ct.length; i++) {
            if (ct[i].Name != -2)
                options += '<option value="' + ct[i].Name + '">' + ct[i].DisplayName + '</option>';
            else
                options += '<option disabled="disabled" value="' + ct[i].Name + '">' + ct[i].DisplayName + '</option>';
        }
        $("select#city_region").html(options);

        options = '';
        lo = j.Locations;

        for (var i = 0; i < lo.length; i++) {
            options += '<option value="' + lo[i].Name + '">' + lo[i].DisplayName + '</option>';
        }
        $("select#location").html(options);
        $("#city_regionAJAXloading").hide();
    }

    function popLoc(j) {
        var options = '';
        lo = j.Locations;

        for (var i = 0; i < lo.length; i++) {

            options += '<option value="' + lo[i].Name + '">' + lo[i].DisplayName + '</option>';
        }
        $("select#location").html(options);
        $("#locationAJAXloading").hide();
    }

    //Unused function bcoz,item with text '------' cannot be selectable now.
    function cancelAjaxLoad(ctl) {
        var oldValue, oldIndex;
        oldIndex = 0;

        for (j = 0; j < ctl.options.length; j++) {

            if (ctl.options[j].defaultSelected) {
                ctl.options[j].defaultSelected = false;
                oldValue = ctl.options[j].value;
                oldIndex = j;
            }

        }

        // If the selected city is "---------" (value -2); Change event to be cancelled  and previous value selected
        if (ctl.value == -2) {
            ctl.selectedIndex = oldIndex;
            ctl.options[oldIndex].defaultSelected = true;
            return false;
        }
        ctl.options[ctl.selectedIndex].defaultSelected = true;

        // Some cities are duplicated above and below "---------"; Change event to be cancelled if selected city is a duplicate city
        if (oldValue == ctl.options[ctl.selectedIndex].value) {
            return false;
        }
    }

    function ReadCookie(cookieName) {
        var theCookie = "" + document.cookie;
        var ind = theCookie.indexOf(cookieName);
        if (ind == -1 || cookieName == "") return "";
        var ind1 = theCookie.indexOf(';', ind);
        if (ind1 == -1) ind1 = theCookie.length;
        return unescape(theCookie.substring(ind + cookieName.length + 1, ind1));
    }

    function ReadFromCookie() {
        var cookietext = document.cookie.indexOf("%7CSearchEng%7C=");
        var c_start = document.cookie.indexOf("%7CSearchEng%7C=");
        var c_end = document.cookie.length;
        var cookiedetails = document.cookie.substring(c_start, c_end);

        var cookieArray = cookiedetails.split("%7C");
        var country;
        var cityname;
        var suburbname;
        var searchby;
        for (var i = 0; i < cookieArray.length; i++) {

            if (cookieArray[i] == "SearchEng") {
                country = cookieArray[i + 2];
                cityname = cookieArray[i + 3];
                suburbname = cookieArray[i + 4];
                searchby = cookieArray[i + 7];
                //alert(country + "***" + cityname + "***" + suburbname + "***" + searchby);
                gc_country = URLDecode(country);
                gc_city = URLDecode(cityname);
                gc_suburb = URLDecode(suburbname);
                gc_searchby = searchby;
                break;
            }
        }
        gc_lc = ReadCookie("lc");
    }

    function populateFromCookie() {

        ReadFromCookie()
        if ((gc_city == "") || (typeof (gc_city) == 'undefined')) {
            return;
        }

        $("#city_region").val(URLDecode(gc_city));
        if ($("#city_region").val() == "undefined") {
            return;
        }
        $.getJSON(AXPAGE, { param1: $("#city_region").val(), action: 'getlocations', proxyid: DRE_GUID }, function(j) {
            _cache.setItem("L_" + $("#city_region").val(), j);
            //$.jCache.setItem("L_" + $("#city_region").val(), j);
            popLoc(j)
            FavTopCitiesLMDealsAJAXRequest($("select#country").val(), $("select#city_region").val());
        });
    }


    $("select#city_region").change(function() {
        //if (cancelAjaxLoad(document.getElementById("city_region")) == false) return; -- unused bcoz,item with text '------' cannot be selectable now.
        $("#locationAJAXloading").show();
        if (_cache.getItem("L_" + $("#city_region").val())) {
            var k = _cache.getItem("L_" + $("#city_region").val())
            popLoc(k);
            FavTopCitiesLMDealsAJAXRequest($("select#country").val(), $("select#city_region").val());
            return;
        }
        /*
        if ($.jCache.hasItem("L_" + $("#city_region").val())) {
        var k = $.jCache.getItem("L_" + $("#city_region").val());
        popLoc(k);
        FavTopCitiesLMDealsAJAXRequest($("select#country").val(), $("select#city_region").val());
        return;
        }
        */
        $.getJSON(AXPAGE, { param1: $(this).val(), action: 'getlocations', proxyid: DRE_GUID }, function(j) {
            _cache.setItem("L_" + $("#city_region").val(), j);
            //$.jCache.setItem("L_" + $("#city_region").val(), j);
            popLoc(j)
            SaveCookieFromClient();
            FavTopCitiesLMDealsAJAXRequest($("select#country").val(), $("select#city_region").val());
        });

    });

    $("select#location").change(function() {
        SaveCookieFromClient();
    });

});



$().ready(function() {

    $("#destination").keydown(function() {
        if ($("#destination").val() == HINT_DRE) {
            $("#destination").val("");
        }
        $("#destination").css("color", "#000");
    });

    $("#destination").click(function() {
        if ($("#destination").val() == HINT_DRE) {
            $("#destination").val("");
        }
        $("#destination").css("color", "#000");
    });

    
    $(".radio_button").click(function(evt) {
        var selopt = $(".radio_button:checked").val();
        if (selopt == "dest") {
            $("#SearchBy").val("LocationKey");
            $("#hotelname").hide();
            $("#destination").val(HINT_DRE);
            $("#destination").css("color", "#C0C0C0");
            $("#destination").show();
            $("#destination").focus();
        }
        else if (selopt == "hname") {
            $("#SearchBy").val("Name");
            $("#hotelname").show();
            $("#destination").hide();
            $("#hotelname").val("");
            $("#hotelname").focus();
        }
        SaveCookieFromClient();
    });

    var autocompleteJSON = function(raw) {
        var json = typeof (raw) === "array" ? raw : raw.destinations;
        var parsed = [];
        for (var i = 0; i < json.length; i++) {
            var row = json[i];
            parsed.push({
                data: row,
                value: row["text"] + ' [' + row["id"] + ']',
                result: row["text"]
            });
        }

        return parsed;
    };

    $("input[name='destination']").result(function(event, data,
            formatted) {

        $("input[name='hdnLocationID']").val(data["id"]);
        $("input[name='hdnLocationKey']").val(data["loc"]);
    });


    $("input[name='destination']").autocomplete("DREWebServiceProxy.asp?lc=EN&affid=5&ctryid=3&SiteCode=HTC&proxyid=" + DRE_GUID,
                  { width: "inherit"
                   , minChars: 3
                   , max: 25
                   , delay: 400
                   , dataType: "json"
                   , parse: autocompleteJSON
                   , formatItem: function(row) { return row["text"] }
                   , mustMatch: false
                   , selectFirst: false
                  });


    $("#destination").val(HINT_DRE);
    $("#destination").css("color", "#C0C0C0");
    $("#destination").focus();
});




function URLDecode(urlStr) {
    return unescape(urlStr.replace(/\+/g, " "))
}

function setDestination(locationid, location) {

    if (document.getElementById('destination') != null)
        document.getElementById('destination').value = location;
    if (document.getElementById('hdnLocationKey') != null)

        document.getElementById('hdnLocationKey').value = location;
    if (document.getElementById('hdnLocationID') != null)
        document.getElementById("hdnLocationID").value = locationid;
}

function activateDRESearch(enable) {
    var searchBy = document.getElementById("SearchBy");

    if (searchBy != null) {
        searchBy.value = (enable ? "LocationKey" : "criteria");
    }
}


function CheckVal(form) {
    var str = trim($("#membershipid").val());

    if (str.indexOf("@") != -1) {
        if (typeof (Membership_MemLogin_MemID) == "undefined")
            Membership_MemLogin_MemID = "The e-mail you entered is not a valid e-mail address."

        if (notEmail(form.membershipid, "", Membership_MemLogin_MemID)) return false
    } else {
        if (notNumber(trim(form.membershipid.value))) {
            if (typeof (Membership_MemLogin_NotVldEmail) == "undefined")
                Membership_MemLogin_NotVldEmail = "The e-mail you entered is not a valid e-mail address."

            alert(Membership_MemLogin_NotVldEmail)
            return false
        }
    }

    if (typeof (Membership_MemLogin_EntEmail) == "undefined")
        Membership_MemLogin_EntEmail = "Please enter E-mail."

    if (isEmpty(form.membershipid, "", Membership_MemLogin_EntEmail)) return false
    if (typeof (Membership_MemLogin_EntPsw) == "undefined")
        Membership_MemLogin_EntPsw = "Please enter Password."

    if (isEmpty(form.password, "", Membership_MemLogin_EntPsw)) return false
    return true;
}

function Retrivevalues() {
    $.getJSON(AXPAGE, { action: 'retrivevalues', proxyid: DRE_GUID }, function(j) {
        var results = j.values;
        if (results[0].data == "True" && (results[2].data == "LocationKey" || results[2].data == "HotelName")) {
            $("#default_search").val("crit");
            $("input[name='hdnLocationID']").val("");
            $("#destinationsearch").show();
            $("#detailedsearch").hide();
            $("#caption").html('Use our classic search');
            if (results[2].data == "LocationKey") {
                document.getElementById("sbdest").checked = true;
                document.getElementById("sbhname").checked = false;
                $("#SearchBy").val("LocationKey");
                $("#hotelname").hide();
                $("#destination").show();
                $("#destination").val(HINT_DRE);
                $("#destination").css("color", "#C0C0C0");
            }
            else if (results[2].data == "HotelName") {
                document.getElementById("sbhname").checked = true;
                document.getElementById("sbdest").checked = false;
                $("#SearchBy").val("Name");
                $("#hotelname").show();
                $("#destination").hide();
                $("#hotelname").val("");
            }
        }
        else if (results[0].data == "True") {
            document.getElementById("sbdest").checked = true;
            document.getElementById("sbhname").checked = false;
            $("#default_search").val("dest");
            $("#SearchBy").val("criteria");
            $("#destinationsearch").hide();
            $("#detailedsearch").show();
            $("#caption").html('Use our new search now!');
            $("input[name='hdnLocationID']").val("");
        }
    });
    if (navigator.userAgent.indexOf("Firefox") != -1)
        clearTimeout(timerID);
}


function SaveCookieFromClient() {
    var strChkin = document.getElementById('Cal1').value;
    var strChkout = document.getElementById('Cal2').value;
    var strCountry = document.getElementById('country').value;
    var strCity = document.getElementById('city_region').value;
    var strSuburb = document.getElementById('location').value;
    var strSrchBy = document.getElementById('SearchBy').value;
    SearchEngineCookie.SetSearchEngineCookieWithSearchBy(strChkin, strChkout, strCountry, strCity, strSuburb, strSrchBy);
}
/*
MIT LICENSE
Copyright (c) 2007 Monsur Hossain (http://www.monsur.com)

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*/

// ****************************************************************************
// CachePriority ENUM
// An easier way to refer to the priority of a cache item
var CachePriority = {
    Low: 1,
    Normal: 2,
    High: 4
}

// ****************************************************************************
// Cache constructor
// Creates a new cache object
// INPUT: maxSize (optional) - indicates how many items the cache can hold.
//                             default is -1, which means no limit on the 
//                             number of items.
function Cache(maxSize) {
    this.items = {};
    this.count = 0;
    if (maxSize == null)
        maxSize = -1;
    this.maxSize = maxSize;
    this.fillFactor = .75;
    this.purgeSize = Math.round(this.maxSize * this.fillFactor);
    
    this.stats = {}
    this.stats.hits = 0;
    this.stats.misses = 0;
}

// ****************************************************************************
// Cache.getItem
// retrieves an item from the cache, returns null if the item doesn't exist
// or it is expired.
// INPUT: key - the key to load from the cache
Cache.prototype.getItem = function(key) {

    // retrieve the item from the cache
    var item = this.items[key];
    
    if (item != null) {
        if (!this._isExpired(item)) {
            // if the item is not expired
            // update its last accessed date
            item.lastAccessed = new Date().getTime();
        } else {
            // if the item is expired, remove it from the cache
            this._removeItem(key);
            item = null;
        }
    }
    
    // return the item value (if it exists), or null
    var returnVal = null;
    if (item != null) {
        returnVal = item.value;
        this.stats.hits++;
    } else {
        this.stats.misses++;
    }
    return returnVal;
}

// ****************************************************************************
// Cache.setItem
// sets an item in the cache
// parameters: key - the key to refer to the object
//             value - the object to cache
//             options - an optional parameter described below
// the last parameter accepts an object which controls various caching options:
//      expirationAbsolute: the datetime when the item should expire
//      expirationSliding: an integer representing the seconds since
//                         the last cache access after which the item
//                         should expire
//      priority: How important it is to leave this item in the cache.
//                You can use the values CachePriority.Low, .Normal, or 
//                .High, or you can just use an integer.  Note that 
//                placing a priority on an item does not guarantee 
//                it will remain in cache.  It can still be purged if 
//                an expiration is hit, or if the cache is full.
//      callback: A function that gets called when the item is purged
//                from cache.  The key and value of the removed item
//                are passed as parameters to the callback function.
Cache.prototype.setItem = function(key, value, options) {

    function CacheItem(k, v, o) {
        if ((k == null) || (k == ''))
            throw new Error("key cannot be null or empty");
        this.key = k;
        this.value = v;
        if (o == null)
            o = {};
        if (o.expirationAbsolute != null)
            o.expirationAbsolute = o.expirationAbsolute.getTime();
        if (o.priority == null)
            o.priority = CachePriority.Normal;
        this.options = o;
        this.lastAccessed = new Date().getTime();
    }

    // add a new cache item to the cache
    if (this.items[key] != null)
        this._removeItem(key);
    this._addItem(new CacheItem(key, value, options));
    
    // if the cache is full, purge it
    if ((this.maxSize > 0) && (this.count > this.maxSize)) {
        this._purge();
    }
}

// ****************************************************************************
// Cache.clear
// Remove all items from the cache
Cache.prototype.clear = function() {

    // loop through each item in the cache and remove it
    for (var key in this.items) {
      this._removeItem(key);
    }  
}

// ****************************************************************************
// Cache._purge (PRIVATE FUNCTION)
// remove old elements from the cache
Cache.prototype._purge = function() {
    
    var tmparray = new Array();
    
    // loop through the cache, expire items that should be expired
    // otherwise, add the item to an array
    for (var key in this.items) {
        var item = this.items[key];
        if (this._isExpired(item)) {
            this._removeItem(key);
        } else {
            tmparray.push(item);
        }
    }
    
    if (tmparray.length > this.purgeSize) {

        // sort this array based on cache priority and the last accessed date
        tmparray = tmparray.sort(function(a, b) { 
            if (a.options.priority != b.options.priority) {
                return b.options.priority - a.options.priority;
            } else {
                return b.lastAccessed - a.lastAccessed;
            }
        });
        
        // remove items from the end of the array
        while (tmparray.length > this.purgeSize) {
            var ritem = tmparray.pop();
            this._removeItem(ritem.key);
        }
    }
}

// ****************************************************************************
// Cache._addItem (PRIVATE FUNCTION)
// add an item to the cache
Cache.prototype._addItem = function(item) {
    this.items[item.key] = item;
    this.count++;
}

// ****************************************************************************
// Cache._removeItem (PRIVATE FUNCTION)
// Remove an item from the cache, call the callback function (if necessary)
Cache.prototype._removeItem = function(key) {
    var item = this.items[key];
    delete this.items[key];
    this.count--;
    
    // if there is a callback function, call it at the end of execution
    if (item.options.callback != null) {
        var callback = function() {
            item.options.callback(item.key, item.value);
        }
        setTimeout(callback, 0);
    }
}

// ****************************************************************************
// Cache._isExpired (PRIVATE FUNCTION)
// Returns true if the item should be expired based on its expiration options
Cache.prototype._isExpired = function(item) {
    var now = new Date().getTime();
    var expired = false;
    if ((item.options.expirationAbsolute) && (item.options.expirationAbsolute < now)) {
        // if the absolute expiration has passed, expire the item
        expired = true;
    } 
    if ((expired == false) && (item.options.expirationSliding)) {
        // if the sliding expiration has passed, expire the item
        var lastAccess = item.lastAccessed + (item.options.expirationSliding * 1000);
        if (lastAccess < now) {
            expired = true;
        }
    }
    return expired;
}

Cache.prototype.toHtmlString = function() {
    var returnStr = this.count + " item(s) in cache<br /><ul>";
    for (var key in this.items) {
        var item = this.items[key];
        returnStr = returnStr + "<li>" + item.key.toString() + " = " + item.value.toString() + "</li>";
    }
    returnStr = returnStr + "</ul>";
    return returnStr;
}
// The below function showDestinationDiv seems obsolete may be removed after confirming with SEO / Affiliates.
function showDestinationDiv(show) {
        alert("Please report a defect if this alert is shown REF:7691428");
        document.getElementById("destinationsearch").style.display  = show ? "block" : "none";
        document.getElementById("hotelsearch").style.display        = show ? "none"  : "none";
        document.getElementById("detailedsearch").style.display     = show ? "none"  : "block";
        document.getElementById('linkswitchback').style.display     = show ? "block" : "none";
        document.getElementById('linknewsearch').style.display      = show ? "none"  : "block";
    }
/*
    function switchoption() {
        if (document.getElementById('detailedsearch').style.display == '') {
            document.getElementById('destinationsearch').style.display = '';
            document.getElementById('detailedsearch').style.display = 'none';
            document.getElementById('caption').innerHTML = 'Switch to classic search';
            document.getElementById("searchOption").value = "New";
            if (document.getElementById("hotelname").value.length > 0) {
                document.getElementById("hotelname").focus();
                document.getElementById("SearchBy").value = "Name";  
                }
            else {
                document.getElementById("destination").focus();
                document.getElementById("SearchBy").value = "LocationKey";  
            }
            
           
        } else {
            document.getElementById('detailedsearch').style.display = '';
            document.getElementById('destinationsearch').style.display = 'none';
            document.getElementById('caption').innerHTML = 'Use our new search now!';
            document.getElementById("searchOption").value = "Old";
            document.getElementById("SearchBy").value = "criteria"     
        }
        
    }

*/
    function switchoption() {
        if ($("#default_search").val() == "crit") {
            $("#default_search").val("dest");
            $("input[name='hdnLocationID']").val("");
                $("#destinationsearch").show();
                $("#detailedsearch").hide();
                $("#caption").html('Use our classic search');
                var selopt = $(".radio_button:checked").val();
                if (selopt == "dest") {
                    $("#SearchBy").val("LocationKey");
                    $("#hotelname").hide();
                    $("#destination").show();
                    $("#destination").val(HINT_DRE);
                    $("#destination").css("color", "#C0C0C0");
                }
                else if (selopt == "hname") {
                    $("#SearchBy").val("Name");
                    $("#hotelname").show();
                    $("#destination").hide();
                    $("#hotelname").val("");
                }
        }
        else if ($("#default_search").val() == "dest") {
                $("#default_search").val("crit");
                $("#SearchBy").val("criteria");
                $("#destinationsearch").hide();
                $("#detailedsearch").show();
                $("#caption").html('Use our new search now!');
                $("input[name='hdnLocationID']").val("");
        }
    }

    function getSerachResultsBy(sortValue) {
        window.location.replace(replaceQueryString(replaceQueryString(window.location + "", "rpage", document.getElementById("rpage").value), "OrderBy", sortValue));
    }

/* SpryTabbedPanels.js - Revision: Spry Preview Release 1.4 */

// Copyright (c) 2006. Adobe Systems Incorporated.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of Adobe Systems Incorporated nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

var Spry;
if (!Spry) Spry = {};
if (!Spry.Widget) Spry.Widget = {};

Spry.Widget.TabbedPanels = function(element, opts) {
    this.element = this.getElement(element);
    this.defaultTab = 0; // Show the first panel by default.
    this.bindings = [];
    this.tabSelectedClass = "TabbedPanelsTabSelected";
    this.tabHoverClass = "TabbedPanelsTabHover";
    this.tabFocusedClass = "TabbedPanelsTabFocused";
    this.panelVisibleClass = "TabbedPanelsContentVisible";
    this.focusElement = null;
    this.hasFocus = false;
    this.currentTabIndex = 0;
    this.enableKeyboardNavigation = true;
    this.disabledTabs = {};

    Spry.Widget.TabbedPanels.setOptions(this, opts);

    // If the defaultTab is expressed as a number/index, convert
    // it to an element.

    if (typeof (this.defaultTab) == "number") {
        if (this.defaultTab < 0)
            this.defaultTab = 0;
        else {
            var count = this.getTabbedPanelCount();
            if (this.defaultTab >= count)
                this.defaultTab = (count > 1) ? (count - 1) : 0;
        }

        this.defaultTab = this.getTabs()[this.defaultTab];
    }

    // The defaultTab property is supposed to be the tab element for the tab content
    // to show by default. The caller is allowed to pass in the element itself or the
    // element's id, so we need to convert the current value to an element if necessary.

    if (this.defaultTab)
        this.defaultTab = this.getElement(this.defaultTab);

    this.attachBehaviors();
};

Spry.Widget.TabbedPanels.prototype.getElement = function(ele) {
    if (ele && typeof ele == "string")
        return document.getElementById(ele);
    return ele;
}

Spry.Widget.TabbedPanels.prototype.getElementChildren = function(element) {
    var children = [];
    var child = element.firstChild;
    while (child) {
        if (child.nodeType == 1 /* Node.ELEMENT_NODE */) {
            // CODE MODIFIED FOR DISABLED TAB : BY JYOTHIS RAJ
            var isDisabled = false;
            if (this.disabledTabs) {
                for (var disTab in this.disabledTabs) {
                    if (child.id == this.disabledTabs[disTab])
                        isDisabled = true;
                }
            }
            if (!isDisabled)
                children.push(child);
            else
                child.className = "TabbedPanelsTabDisabled";

        }
        child = child.nextSibling;
    }
    return children;
};

Spry.Widget.TabbedPanels.prototype.addClassName = function(ele, className) {
    if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) != -1))
        return;
    ele.className += (ele.className ? " " : "") + className;

};

Spry.Widget.TabbedPanels.prototype.removeClassName = function(ele, className) {
    if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) == -1))
        return;
    ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), "");
};

Spry.Widget.TabbedPanels.setOptions = function(obj, optionsObj, ignoreUndefinedProps) {
    if (!optionsObj)
        return;
    for (var optionName in optionsObj) {
        if (ignoreUndefinedProps && optionsObj[optionName] == undefined)
            continue;
        obj[optionName] = optionsObj[optionName];
    }
};

Spry.Widget.TabbedPanels.prototype.getTabGroup = function() {
    if (this.element) {
        var children = this.getElementChildren(this.element);
        if (children.length)
            return children[0];
    }
    return null;
};

Spry.Widget.TabbedPanels.prototype.getTabs = function() {
    var tabs = [];
    var tg = this.getTabGroup();
    if (tg)
        tabs = this.getElementChildren(tg);
    return tabs;
};

Spry.Widget.TabbedPanels.prototype.getContentPanelGroup = function() {
    if (this.element) {
        var children = this.getElementChildren(this.element);
        if (children.length > 1)
            return children[1];
    }
    return null;
};

Spry.Widget.TabbedPanels.prototype.getContentPanels = function() {
    var panels = [];
    var pg = this.getContentPanelGroup();
    if (pg)
        panels = this.getElementChildren(pg);
    return panels;
};

Spry.Widget.TabbedPanels.prototype.getIndex = function(ele, arr) {
    ele = this.getElement(ele);
    if (ele && arr && arr.length) {
        for (var i = 0; i < arr.length; i++) {
            if (ele == arr[i])
                return i;
        }
    }
    return -1;
};

Spry.Widget.TabbedPanels.prototype.getTabIndex = function(ele) {
    var i = this.getIndex(ele, this.getTabs());
    if (i < 0)
        i = this.getIndex(ele, this.getContentPanels());
    return i;
};

Spry.Widget.TabbedPanels.prototype.getCurrentTabIndex = function() {
    return this.currentTabIndex;
};

Spry.Widget.TabbedPanels.prototype.getTabbedPanelCount = function(ele) {
    return Math.min(this.getTabs().length, this.getContentPanels().length);
};

Spry.Widget.TabbedPanels.addEventListener = function(element, eventType, handler, capture) {
    try {
        if (element.addEventListener)
            element.addEventListener(eventType, handler, capture);
        else if (element.attachEvent)
            element.attachEvent("on" + eventType, handler);
    }
    catch (e) { }
};

Spry.Widget.TabbedPanels.prototype.onTabClick = function(e, tab) {
    this.showPanel(tab);
};

Spry.Widget.TabbedPanels.prototype.onTabMouseOver = function(e, tab) {
    this.addClassName(tab, this.tabHoverClass);
};

Spry.Widget.TabbedPanels.prototype.onTabMouseOut = function(e, tab) {
    this.removeClassName(tab, this.tabHoverClass);
};

Spry.Widget.TabbedPanels.prototype.onTabFocus = function(e, tab) {
    this.hasFocus = true;
    this.addClassName(this.element, this.tabFocusedClass);
};

Spry.Widget.TabbedPanels.prototype.onTabBlur = function(e, tab) {
    this.hasFocus = false;
    this.removeClassName(this.element, this.tabFocusedClass);
};

Spry.Widget.TabbedPanels.ENTER_KEY = 13;
Spry.Widget.TabbedPanels.SPACE_KEY = 32;

Spry.Widget.TabbedPanels.prototype.onTabKeyDown = function(e, tab) {
    var key = e.keyCode;
    if (!this.hasFocus || (key != Spry.Widget.TabbedPanels.ENTER_KEY && key != Spry.Widget.TabbedPanels.SPACE_KEY))
        return true;

    this.showPanel(tab);

    if (e.stopPropagation)
        e.stopPropagation();
    if (e.preventDefault)
        e.preventDefault();

    return false;
};

Spry.Widget.TabbedPanels.prototype.preorderTraversal = function(root, func) {
    var stopTraversal = false;
    if (root) {
        stopTraversal = func(root);
        if (root.hasChildNodes()) {
            var child = root.firstChild;
            while (!stopTraversal && child) {
                stopTraversal = this.preorderTraversal(child, func);
                try { child = child.nextSibling; } catch (e) { child = null; }
            }
        }
    }
    return stopTraversal;
};

Spry.Widget.TabbedPanels.prototype.addPanelEventListeners = function(tab, panel) {
    var self = this;
    Spry.Widget.TabbedPanels.addEventListener(tab, "click", function(e) { return self.onTabClick(e, tab); }, false);
    Spry.Widget.TabbedPanels.addEventListener(tab, "mouseover", function(e) { return self.onTabMouseOver(e, tab); }, false);
    Spry.Widget.TabbedPanels.addEventListener(tab, "mouseout", function(e) { return self.onTabMouseOut(e, tab); }, false);

    if (this.enableKeyboardNavigation) {
        // XXX: IE doesn't allow the setting of tabindex dynamically. This means we can't
        // rely on adding the tabindex attribute if it is missing to enable keyboard navigation
        // by default.

        // Find the first element within the tab container that has a tabindex or the first
        // anchor tag.

        var tabIndexEle = null;
        var tabAnchorEle = null;

        this.preorderTraversal(tab, function(node) {
            if (node.nodeType == 1 /* NODE.ELEMENT_NODE */) {
                var tabIndexAttr = tab.attributes.getNamedItem("tabindex");
                if (tabIndexAttr) {
                    tabIndexEle = node;
                    return true;
                }
                if (!tabAnchorEle && node.nodeName.toLowerCase() == "a")
                    tabAnchorEle = node;
            }
            return false;
        });

        if (tabIndexEle)
            this.focusElement = tabIndexEle;
        else if (tabAnchorEle)
            this.focusElement = tabAnchorEle;

        if (this.focusElement) {
            Spry.Widget.TabbedPanels.addEventListener(this.focusElement, "focus", function(e) { return self.onTabFocus(e, tab); }, false);
            Spry.Widget.TabbedPanels.addEventListener(this.focusElement, "blur", function(e) { return self.onTabBlur(e, tab); }, false);
            Spry.Widget.TabbedPanels.addEventListener(this.focusElement, "keydown", function(e) { return self.onTabKeyDown(e, tab); }, false);
        }
    }
};

var SelectedTab;

Spry.Widget.TabbedPanels.prototype.showPanel = function(elementOrIndex) {
    var tpIndex = -1;

    if (typeof elementOrIndex == "number")
        tpIndex = elementOrIndex;
    else // Must be the element for the tab or content panel.
        tpIndex = this.getTabIndex(elementOrIndex);

    if (!tpIndex < 0 || tpIndex >= this.getTabbedPanelCount())
        return;

    var tabs = this.getTabs();
    var panels = this.getContentPanels();

    var numTabbedPanels = Math.max(tabs.length, panels.length);

    for (var i = 0; i < numTabbedPanels; i++) {
        if (tabs[i]) {
            tabs[i].style.zIndex = "1000";
        }
        if (i != tpIndex) {
            if (tabs[i]) {
                this.removeClassName(tabs[i], this.tabSelectedClass);

            }
            if (panels[i]) {
                this.removeClassName(panels[i], this.panelVisibleClass);
                panels[i].style.display = "none";
            }
        }
    }

    this.addClassName(tabs[tpIndex], this.tabSelectedClass);
    var tabFilter
    
    if (SelectedTab && SelectedTab != tabs[tpIndex]) {
        if (tabs[tpIndex].childNodes.length >= 2) {
            var index = tabs[tpIndex].childNodes.length - 1
            if (tabs[tpIndex].childNodes[index].filters && tabs[tpIndex].childNodes[index].filters.length == 1) {

                tabFilter = tabs[tpIndex].childNodes[index].filters(0).src;

                if (SelectedTab.childNodes.length >= 2 && SelectedTab.childNodes[index].filters && SelectedTab.childNodes[index].filters.length == 1) {
                    tabs[tpIndex].childNodes[index].filters(0).src = SelectedTab.childNodes[index].filters(0).src;
                    SelectedTab.childNodes[index].filters(0).src = tabFilter;
                }

            }
        }
    }

    SelectedTab = tabs[tpIndex];


    tabs[tpIndex].style.zIndex = "1003";
    this.addClassName(panels[tpIndex], this.panelVisibleClass);
    panels[tpIndex].style.display = "block";

    this.currentTabIndex = tpIndex;
};

Spry.Widget.TabbedPanels.prototype.attachBehaviors = function(element) {
    var tabs = this.getTabs();
    var panels = this.getContentPanels();
    var panelCount = this.getTabbedPanelCount();

    for (var i = 0; i < panelCount; i++)
        this.addPanelEventListeners(tabs[i], panels[i]);

    this.showPanel(this.defaultTab);
};
