﻿/**
* static object that handles page logic
* @class
* @constructor
* @param {jQuery} $ Reference to the jQuery object
*/
var SearchMain = function($) {

    /**
    * @namespace Private methods and variables
    */
    var priv = {
        freeTextInputElement: "#text-search input",
        freeTextSubmitElement: "#text-search .submitbutton",

        /**
        * Container object, holding references to the lightboxes that have been initialized in this page.
        * Using this each lightbox only has to be instantiated once, when it is first called.
        * @type {Lightbox}
        * @private
        */
        lightboxes: {},

        /**
        * Generic way to open a new lightbox: the contents of the container identified by the supplied id
        * are loaded in a lightbox. Also, the lightbox is cached and thus only has to be initialized once.
        * @param {String} id The id of the container to show in the lightbox
        * @param {Object} options (Optional) Several options can be supplied to override default behavior of just
        * loading the contents of the container. When supplied, these options will be used to initialize the lightbox.
        * @private
        */
        openLightbox: function(id, options) {
            if (typeof (options) == 'undefined' || !options) {
                options = { container: document.getElementById(id) };
            }
            var lightbox = Lightbox.CreateCached(id, options);
            lightbox.Show();
        },

        /**
        * Show the element matching the supplied ID in a lightbox. Used on the offers page.
        * @param {HTMLElement} anchor The anchor element referencing the popup contents.
        * @param {String} id The id of the popup container
        * @return {Boolean} Returns false to allow event handlers to easily stop default browser behavior
        * @private
        */
        showOfferInfoInLightbox: function(anchor, id) {
            priv.openLightbox(id, {
                container: document.getElementById(id),
                contentUrl: $(anchor).attr('href'),
                width: '500px'
            });
            return false;
        },

        /**
        * Bind general events for this page
        * @private
        */
        bindEvents: function() {
            if (location.href.indexOf('personal=') != -1) {
                $('body').addClass('search-personal');
                priv.setCompareChecked();
            } else {
                priv.bindTextSearch();
            }
            priv.bindHighlightRefinements();
            priv.bindShowOccupancyPopup();
            priv.storeOccupancy();
            priv.bindLocationInfoEvents();
            priv.bindMoreInfoEvents();
            priv.bindCompareEvents();
            if ($('body').attr('class').indexOf('search-offers') > -1) {
                priv.bindQuestionPopups();
            }
        },

        /**
        * Bind events on the links to questions popups, both in the left sidebar and in the main content area.
        * @private
        */
        bindQuestionPopups: function() {
            // add container for question popups
            $('body').append("<div id=\"questionPopup\"></div>");

            // Bind methods to show popups for questions in left sidebar
            $("#questions-left ul.questions li a").not(".more-questions").bind('click', function() {
                var $anchor = $(this);
                var options = {
                    container: document.getElementById("questionPopup"),
                    literal: false,
                    title: $anchor.text(),
                    contentUrl: $anchor.attr('href'),
                    width: '643px'
                };
                var lightbox = Lightbox.CreateCached($anchor.attr('href'), options);
                lightbox.Show();
                return false;
            });

            // Open faq in new window
            $("#questions-left ul.questions li a.more-questions").bind('click', function() {
                Utils.newWindow(this, 800, 640);
                return false;
            });
        },

        /**
        * Bind events for showing popups with more information about departures
        * @private
        */
        bindMoreInfoEvents: function() {
            $("body").append("<div id=\"offersDepartureUnknownPopup\"></div>");
            $("body").append("<div id=\"offersDepartureKnownPopup\"></div>");

            $('a.moreinfo').bind("click", function() {
                return priv.showOfferInfoInLightbox(this, "offersDepartureUnknownPopup");
            });
            $('a.moreinfounknown').bind("click", function() {
                return priv.showOfferInfoInLightbox(this, "offersDepartureKnownPopup");
            });
        },

        /**
        * Bind tooltips to the location selection in the left sidebar. Hovering over a country, region or city
        * will show a tooltip with some additional information.
        * @private
        */
        bindLocationInfoEvents: function() {
            var path = Resource.GetText("path_prefix");
            var ttOptions = {
                trigger: "hover",
                autoClose: true,
                source: "ajax",
                type: "GET",
                loadingText: "",
                loadingImg: path + "/images/ajax-loader-smallest.gif",
                url: path + "/_html/location-block.aspx"
            };

            var locations = ["country", "region", "city"];
            for (var i = 0; i < locations.length; i++) {
                $("a." + locations[i]).each(function() {
                    var $this = $(this);
                    ttOptions["data"] = "theme=" + locations[i] + "&id=" + $this.attr("rel");
                    $this.jHelperTip(ttOptions);
                });
            }
        },

        /**
        * Bind the functionality to add or remove items from the compare basket.
        * @private
        */
        bindCompareEvents: function() {
            $('div.compareCheck').bind("click", function() {
                // Update the compare basket to match the checked accos
                var path = Resource.GetText("path_prefix");
                var src = path + "/_search/CompareBasket.aspx";

                if (src != '' || src != null) {
                    var basketsrc = src;
                    var compareUrl = '';

                    $('div.compareCheck.checked').each(function(i) {
                        compareUrl += (compareUrl == '') ? 'id=' + this.id.replace('check_', '') : '&id=' + this.id.replace('check_', '');
                    });

                    basketsrc += '?' + compareUrl;

                    if ($('div.compareCheck.checked').size() > 0) {
                        $('#frmCompareBasket').attr("src", basketsrc);
                        $('#frmCompareBasket').attr("height", "685px");
                    }
                    else {
                        $('#frmCompareBasket').attr("src", '');
                        $('#frmCompareBasket').attr("height", "0px");
                    }
                }
            });
        },

        /**
        * 
        * @private
        */
        setCompareChecked: function() {
            var checkIds = $.query.get("id");
            if (checkIds != "" && checkIds.indexOf(",") != -1) {
                checkIds = checkIds.split(",");

                $('div.compareCheck').each(
                    function(i) {
                        var id = $(this).attr("id").substring($(this).attr("id").indexOf("_") + 1);
                        for (j = 0; j < checkIds.length; j++) {
                            if (id == checkIds[j]) {
                                $(this).addClass("checked");
                                break;
                            }
                        }
                    }
                );
            }
        },

        /**
        * Highlight refinements when hovering in ribbon
        * @private
        */
        bindHighlightRefinements: function() {
            $('#btnHighlight').hover(function() {
                $('div.navigation-refine').css({
                    backgroundColor: '#fffbc3',
                    border: 'solid 1px #FF2200'
                });
            }, function() {
                $('div.navigation-refine').css({
                    backgroundColor: '#fff',
                    border: 'solid 1px #FFF'
                });
            });
        },

        /**
        * Show occupancy popup, when clicking on block in ribbon
        * @private
        */
        bindShowOccupancyPopup: function() {
            $('#btnTipOccupancy').bind('click', Occupancy.showTravelersPopup);
        },

        storeOccupancy: function() {
            $('#reisgezelschap1').bind('change', function() {
                var occupancy = $('#reisgezelschap1').val();
                if (occupancy != Occupancy.getOccupancy()) Occupancy.saveTotalTravelers(occupancy);
                location = location;
            });
        },

        /**
        * bind free text search action
        * @private
        */
        bindTextSearch: function() {
            if ($(priv.freeTextInputElement).length) {
                $(priv.freeTextSubmitElement).bind("click", priv.textSearch);
                if ($(priv.freeTextInputElement).val() != Resource.GetText('search_free_text')) {
                    $(priv.freeTextSubmitElement).get(0).disabled = false;
                }
                $(priv.freeTextInputElement).bind("focus", function() {
                    $(priv.freeTextSubmitElement).get(0).disabled = false;
                    if (this.value == Resource.GetText('search_free_text')) {
                        this.value = '';
                    }
                    else {
                        this.select();
                    }
                });
                $(priv.freeTextInputElement).bind("keydown", function(evt) {
                    if (evt.keyCode == 13) {
                        priv.textSearch();
                    }
                });
            }
        },

        /**
        * Redirects the page with the correct free text search parameter
        * @private
        */
        textSearch: function() {
            $input = $(priv.freeTextInputElement);
            if ($input.val() != '' && $input.val() != Resource.GetText('search_free_text')) {
                document.location.href = document.location.pathname + "?searchtext=" + encodeURI($input.attr("value"));
            }
        },

        /**
        * @private
        */
        buildDepartureCalendar: function() {
            $('div.result-selected .remove').each(function(i) {
                if (this.href.indexOf('daterange=-1') != -1) {
                    this.href = 'javascript:void(0);';
                    $(this).click(function() {
                        SearchMain.changeDateRange('-1');
                    });
                }
            });

            // get the number of days to select before and after the selected date
            var daterange = $.query.get('daterange').toString();
            var addDays = 0;
            if (daterange == '2') {
                addDays = 3;
            } else if (daterange == '3') {
                addDays = 7;
            } else if (daterange == '-1') {
                SearchMain.changeDateRange();
            }

            // get the selected date and get the mindate and maxdate in the range
            var curMinDate = 0;
            var curMaxDate = 0;
            var curSelDate = $.query.get('seldate').toString();
            if (curSelDate != '') {
                var dtCurSelDate = Date.fromString(curSelDate.substring(6, 8) + '/' + curSelDate.substring(4, 6) + '/' + curSelDate.substring(0, 4));
                curMinDate = parseInt(dtCurSelDate.addDays(addDays * -1).asString2());
                curMaxDate = parseInt(dtCurSelDate.addDays(addDays * 2).asString2());
            }
            // build the departure calendar
            $('#start-date').datePicker({
                inline: true,
                createButton: false,
                showYearNavigation: false,
                year: curYear,
                month: curMonth,
                startDate: firstDate,
                endDate: lastDate,
                renderCallback: function($td, thisDate, month, year) {
                    // set the dates selected inside the range
                    if (thisDate.asString2() == curSelDate) {
                        $td.addClass('selected');
                        $td.addClass('click');
                    } else if (thisDate.asString2() >= curMinDate && thisDate.asString2() <= curMaxDate) {
                        $td.addClass('selected');
                    }

                    // disable the dates the aren't departuredays
                    if (departDates['d' + thisDate.asString2()] == null ||
                            departDates['d' + thisDate.asString2()] == '') {
                        $td.addClass('disabled');
                    }
                }
            });

            // bind the action when a date is clicked
            $('#start-date').bind('dateSelected', function(e, selectedDate, $td) {
                if (daterange == '-1') {
                    $('select.daterange').val('1');
                }

                // get the selected daterange
                var minDate = parseInt(selectedDate.addDays(addDays * -1).asString2());
                var maxDate = parseInt(selectedDate.addDays(addDays * 2).asString2());
                selectedDate = selectedDate.addDays(addDays * -1);

                var selectQuery = '';
                var selNValues = '';
                // loop through the date range and build the string with the nvalues to select
                // - and build the string with all the querystrings
                for (var i = minDate; i <= maxDate; i++) {
                    if (departDates['d' + i] != null && departDates['d' + i] != '') {
                        var queryString = departDates['d' + i].split(',')[1];
                        var nValue = departDates['d' + i].split(',')[2];
                        selNValues += selNValues == '' ? nValue : '+' + nValue;

                        var startIndex = queryString.indexOf('N=');
                        if (startIndex != -1) {
                            var endIndex = queryString.indexOf('&', startIndex);
                            if (endIndex == -1) {
                                endIndex = queryString.length + 1;
                            }
                            selectQuery += '||' + queryString.substring(startIndex + 2, endIndex).replace(/\+/g, '||');
                        }
                    }
                }
                selectQuery += '|';

                // remove the departuredays nvalues, so only the other nvalues are left over
                for (var key in departDates) {
                    var nValue2 = departDates[key].split(',')[2];
                    if (selectQuery.indexOf('|' + nValue2 + '|') != -1) {
                        selectQuery = selectQuery.replace(new RegExp('/|' + nValue2 + '|/', 'g'), '');
                    }
                }

                // combine the to selected departuredays nvalues with the other selected nvalues
                var splitOtherNvalues = selectQuery.split('|');
                for (var j = 0; j < splitOtherNvalues.length; j++) {
                    if (splitOtherNvalues[j] != '' && ('+' + selNValues + '+').indexOf('+' + splitOtherNvalues[j] + '+') == -1) {
                        selNValues += '+' + splitOtherNvalues[j];
                    }
                }

                // submit the selected date range
                var newUrl = $.query.SET('N', selNValues).SET('seldate', selectedDate.asString2()).REMOVE('No');
                location.href = decodeURIComponent(newUrl.toString());
            });
        },

        /**
        * @private
        */
        buildCalendar: function() {
            if ($('a.btnSelectDate').length) {
                $('a.btnSelectDate,a.btnSelectDateAnimate').bind('click', function(e) {
                    $('a.btnSelectDate').css({
                        color: '#ccc'
                    });
                    if ($(this).attr('class').indexOf('Animate') != -1) {
                        var offsetAnimate = $('a.btnSelectDateAnimate').offset();
                        var oldTop = offsetAnimate.top + 12;
                        var oldLeft = offsetAnimate.left;
                        $('#calendarContainer').css({
                            "top": (oldTop) + "px",
                            "left": (oldLeft) + "px"
                        });
                        var offsetCalendar = $('a.btnSelectDate').offset();
                        var newTop = offsetCalendar.top + 12;
                        var newLeft = offsetCalendar.left + ($('a.btnSelectDate').width() - 15);
                        $('#calendarContainer').animate({
                            "top": newTop + "px"
                        }, {
                            duration: 300
                        }).animate({
                            "left": newLeft + "px"
                        }, {
                            duration: 600
                        });
                    }
                    if (reloadDates == 'True') {
                        $('#start-date').css({
                            'height': '154px',
                            'width': '157px'
                        });
                        $('#start-date').html('');
                        var type = 'type=search&';
                        if (Resource.GetText('isofferspage') == 'true') {
                            type = 'type=offers&';
                        }
                        $.getJSON(Resource.GetText('path_prefix') + '/js/ajax/departure-dates.aspx', type + location.href.split('?')[1], function(data) {
                            firstDate = data.firstDate;
                            lastDate = data.lastDate;
                            departDates = data.departDates;
                            priv.buildDepartureCalendar();
                        });
                        reloadDates = 'False';
                    }
                }).jHelperTip({
                    trigger: "click",
                    dC: "#date-popup",
                    ttC: "#calendarContainer",
                    initializeOnce: true,
                    autoClose: true
                });
            }
            if (typeof (curYear) != "undefined") {
                priv.buildDepartureCalendar();
            }
        }
    };

    /** @scope SearchMain */
    return {

        changeDateRange: function(parDaterange) {
            if (reloadDates == 'True') {
				var type = 'type=search&';
                if (Resource.GetText('isofferspage') == 'true') {
                    type = 'type=offers&';
                }
                $.getJSON(Resource.GetText('path_prefix') + '/js/ajax/departure-dates.aspx?' + type + location.href.split('?')[1], function(data) {
                    firstDate = data.firstDate;
                    lastDate = data.lastDate;
                    departDates = data.departDates;
                    SearchMain.doChangeDateRange(parDaterange);
                });
                reloadDates = 'False';
            } else {
                SearchMain.doChangeDateRange(parDaterange);
            }
        },

        doChangeDateRange: function(parDaterange, reloadDates) {
            var daterangeVal = parDaterange;
            if (daterangeVal == null)
                daterangeVal = $('select.daterange').val();
            var nValues = $.query.get('N').toString();
            if (daterangeVal == '-1') {
                location.href = location.href.split('?')[0] + SearchMain.getQueryStringWithoutDates();
            } else {
                if (location.href.indexOf('?') == -1) {
                    location.href = location.href + '?daterange=' + daterangeVal;
                } else {
                    var curSelDate = $.query.get('seldate').toString();
                    if (curSelDate != '' && nValues != '') {
                        var addDays = 0;
                        if (daterangeVal == '2') {
                            addDays = 3;
                        } else if (daterangeVal == '3') {
                            addDays = 7;
                        }
                        // get the selected date and get the mindate and maxdate in the range
                        var minDate = 0;
                        var maxDate = 0;
                        if (curSelDate != '') {
                            var dtCurSelDate = Date.fromString(curSelDate.substring(6, 8) + '/' + curSelDate.substring(4, 6) + '/' + curSelDate.substring(0, 4));
                            minDate = parseInt(dtCurSelDate.addDays(addDays * -1).asString2());
                            maxDate = parseInt(dtCurSelDate.addDays(addDays * 2).asString2());
                        }
                        var newNvalues = '';
                        var selectQuery = '';
                        var selNValues = '';
                        // loop through the date range and build the string with the nvalues to select
                        // - and build the string with all the querystrings
                        for (var i = minDate; i <= maxDate; i++) {
                            if (departDates['d' + i] != null && departDates['d' + i] != '') {
                                var queryString = departDates['d' + i].split(',')[1];
                                var nValue = departDates['d' + i].split(',')[2];
                                selNValues += selNValues == '' ? nValue : '+' + nValue;

                                var startIndex = queryString.indexOf('N=');
                                if (startIndex != -1) {
                                    var endIndex = queryString.indexOf('&', startIndex);
                                    if (endIndex == -1) {
                                        endIndex = queryString.length + 1;
                                    }
                                    selectQuery += '||' + queryString.substring(startIndex + 2, endIndex).replace(/\+/g, '||');
                                }
                            }
                        }
                        selectQuery += '|';

                        // remove the departuredays nvalues, so only the other nvalues are left over
                        for (var key in departDates) {
                            var nValue2 = departDates[key].split(',')[2];
                            if (selectQuery.indexOf('|' + nValue2 + '|') != -1) {
                                selectQuery = selectQuery.replace(new RegExp('/|' + nValue2 + '|/', 'g'), '');
                            }
                        }

                        // combine the to selected departuredays nvalues with the other selected nvalues
                        var splitOtherNvalues = selectQuery.split('|');
                        for (var j = 0; j < splitOtherNvalues.length; j++) {
                            if (splitOtherNvalues[j] != '' && ('+' + selNValues + '+').indexOf('+' + splitOtherNvalues[j] + '+') == -1) {
                                selNValues += '+' + splitOtherNvalues[j];
                            }
                        }

                        newNvalues = selNValues;
                        if (newNvalues == '') {
                            newNvalues = '0';
                        }
                        var newUrl = $.query.REMOVE('No').set('N', newNvalues).set('daterange', daterangeVal);
                        location.href = decodeURIComponent(newUrl.toString());
                    } else {
                        location.href = $.query.empty().set('daterange', daterangeVal);
                    }
                }
            }
        },

        getQueryStringWithoutDates: function() {
            var nValues = $.query.get('N').toString().replace(/ /gi, '+');

            if (location.href.indexOf('?') != -1) {
                // undo departure filter
                var queryString = location.href.split('?')[1];
                var arrnValues = nValues.split('+');
                var newNvalues = '';
                for (var key in departDates) {
                    var nValue = departDates[key].split(',')[2];
                    for (var i = 0; i < arrnValues.length; i++) {
                        if (nValue == arrnValues[i]) {
                            arrnValues[i] = '';
                        }
                    }
                }
                for (var j = 0; j < arrnValues.length; j++) {
                    if (arrnValues[j] != '') {
                        // Do not use '+' as the separator which gets url encoded, use '_' instead.
                        newNvalues += newNvalues == '' ? arrnValues[j] : '_' + arrnValues[j];
                    }
                }
                if (newNvalues == '') {
                    newNvalues = '0';
                }
                var newUrl = $.query.load(queryString).REMOVE('seldate').REMOVE('No').set('N', newNvalues);
                // Replace back above separator by the normal nValue separator +
                return newUrl.toString().replace(/_/gi, '+');
            }
        },
        
        clearNdp: function(newSearchText) {
            var newUrl = $.query.REMOVE('ndp').REMOVE('Ndp');
            
            if (typeof (newSearchText) != 'undefined') {
                $.query.SET('searchtext', newSearchText);
            }
            
            location.href = decodeURIComponent(newUrl.toString() == '' ? '?' : newUrl.toString());
        },   
        
        /**
        * Initializes the logic for the current page
        * to be called on $(document).ready
        */
        OnReady: function() {
            priv.bindEvents();
            priv.buildCalendar();
        }
    };
} (jQuery);
