﻿/**
 * 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 = {

        currentDisplayDate: "Kies vertrekdatum",
        currentSelDateValue: "",

        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.bindLocationInfoEvents();
            priv.bindMoreInfoEvents();
            if ($('body').attr('class').indexOf('search-offers') > -1) {
                priv.bindQuestionPopups();
            }

            /* Bind miniski events (regarding the lightbox) */
            priv.bindMiniSkiPopups();

            priv.bindSearchEvents();

            $('div.ordering select').bind('change',
                    function() {
			        var sortValue = $(this).val();
			        if (sortValue != null && sortValue != '-1' && sortValue != '') {
                            var rel = $(':selected', this).attr('rel');
			            location.href = sortValue;
			        }
			    }
			);
            },
        bindSearchEvents: function() {
            if ($('#zoekenboek').length) {
                $('select.search,select.smallsearch, select.search_elm', '#searchbar').bind('change', function() {
                    priv.dropDownHomepageChange();
                });
            }
        },
        /**
         * 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 on the links to MiniSki and MidWeek popups
         * @private
         */
        bindMiniSkiPopups: function() {
            $('.miniski-block a').click(function() {
                var title = $('.item-heading', $(this).parent()).html();
                var lightbox = Lightbox.CreateCached(
                    title,
                    { contentUrl: $(this).attr('href'),
                        container: $('<div>').appendTo('body'),
                        literal: false,
                        title: title,
                     width: '512px'
                    }
                );
                lightbox.Show();
                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() {
        },

        /**
         * 
         * @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() {
        },

        /**
         * 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;
            if (typeof (reloadCalendarWithAjax) != "undefined" && reloadCalendarWithAjax == 'true') curSelDate = priv.currentSelDateValue;
            else 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').unbind('dateSelected').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];
                    }
                }

                priv.currentSelDateValue = selectedDate.asString2();

                if (typeof (reloadCalendarWithAjax) != "undefined" && reloadCalendarWithAjax == 'true') {
                    $('#calendarContainer').empty().remove();
                    priv.selectedDateNValues = selNValues;
                    priv.dropDownHomepageChange();
                    priv.currentDisplayDate = selectedDate.getDayName(true) + ' ' + selectedDate.getDate() + ' ' + selectedDate.getMonthName(true);
                    $('#wanneer').val(priv.currentDisplayDate);
                }
                else {
                    // submit the selected date range                    
                var newUrl = $.query.SET('N', selNValues).SET('seldate', selectedDate.asString2()).REMOVE('No');

                location.href = decodeURIComponent(newUrl.toString());
                }
            });

            //$('#wanneer').val(priv.currentDisplayDate);

        },
        dropDownHomepageChange: function() {
            var selectedNValues = [];

            selectedNValues.push($('#accommodatiesoort').val());
            selectedNValues.push($('#destination').val());
            selectedNValues.push($('#vliegveld').val());
            selectedNValues.push(priv.selectedDateNValues);
            selectedNValues.push($('#reisduur').val());
            selectedNValues.push($('#verzorging').val());
            selectedNValues.push($('#vervoer').val());

            var filteredNValues = [];
            for (var i = 0; i < selectedNValues.length; i++) {
                if (selectedNValues[i] && selectedNValues[i] != -1) {
                    filteredNValues.push(selectedNValues[i]);
                }
            }

            var occupancy = $('#reisgezelschap1').val();
            var currentpage = $('#currentpage').val();

            var loadcontrol = "~/controls/searchbar.ascx";
            if (currentpage == "homepage") {
                loadcontrol = "~/controls/home/searchbar.ascx";
            }


            if (occupancy != Occupancy.getOccupancy()) Occupancy.saveTotalTravelers(occupancy);

            $('#resultcount').hide();
            $('#resultloader').show();

            $.ajax({
                // hack (Alexander): make a sync AJAX request.
                // Under some conditions an unknown handler executes right after this $.ajax call, 
                // but before result is received and parsed, and redirects to the wrong page.
                // The bug is that in FF on test server when on search page you filter by date with datePicker,
                // after filtering by e.g. destination, search result is incorrect
                // and query string in browser is ?unknown instead of ?N=0+... which probably corresponds to the line below:
                // location.href = currentLocation + '?' + $("#queryString").val();
                // async: false helps, because in this case that evil handler does not get an opportunity to execute.
                // As soon as race condition is fixed, async: false should be removed.
                async: false,
                url: Resource.GetText('path_prefix') + "/js/ajax/getcontrol.aspx",
                data: "N=" + filteredNValues.join('+') //todo
                //                "accommodationtypeNValue=" + accommodationtypeNValue +
                //"&maxpriceNValue=" + maxpriceNValue +
                //                        "&destinationsNValue=" + destinationsNValue +
                //                        "&airportNValue=" + airportNValue +
                //                        "&departureValue=" + departureValue +
                //                        "&vacationlengthNValue=" + vacationlengthNValue +
                //                        "&occupancy=" + occupancy +
                        + "&currentpage=" + currentpage
                        + "&loadControl=" + encodeURI(loadcontrol)
                //                        "&hosttypeNValue=" + hosttypeNValue +
                //                        "&transporttypeNValue=" + transporttypeNValue,
                ,
                cache: false,
                success: function(result) {
                    $('#searchbar').html(result);
                    $('#resultcount').show();
                    $('#resultloader').hide();

                    //priv.updateTravelersDropdown();
                    priv.bindSearchEvents();
                    priv.buildCalendar();

                    if (typeof (refreshPageOnSearch) != "undefined" && refreshPageOnSearch == 'true') {

                        var currentLocation = location.protocol + "//" + location.host + location.pathname;

                        /*if (location.href.indexof("?") > -1)
                        currentLocation = location.href.substring(0, location.href.indexof("?"));
                        else currentLocation = location.href;
                        */

                        if ($("#queryString").length) {
                        location.href = currentLocation + '?' + $("#queryString").val();
                    }
                }
                }
            });

        },
        /* Search button (top right corner) */
        bindSearchBoxEvents: function() {
            // Search button
            $('#homesearch').bind("focus",
                function() {
                    this.value = '';
                }
            ).bind("keydown",
                function(evt) {
                    if (evt.keyCode == 13) {
                        priv.inputSubmit();
                    }
                }
            );

            $('#homesearchbutton').bind("click",
                function() {
                    priv.inputSubmit();
                }
            );
        },

        inputSubmit: function() {
            if ($('#homesearch').val() != null && $('#homesearch').val() != "") {
                $('#homesearch').val($('#homesearch').val().replace('bijv: ', ''));
                $('#form-search').get(0).submit();
            }
        },
        /**
         * @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 {

        /* Other */
        changeDateRange: function(parDaterange) {
            if (reloadDates == 'True') {
                $.getJSON(Resource.GetText('path_prefix') + '/js/ajax/departure-dates.aspx?' + location.href.split('?')[1], function(data) {
                    firstDate = data.firstDate;
                    lastDate = data.lastDate;
                    departDates = data.departDates;
                    SearchMain.doChangeDateRange(parDaterange);
                });
                reloadDates = 'False';
            } else {
                SearchMain.doChangeDateRange(parDaterange);
            }
        },
        dropDownHomePageUnselect: function() {
            Occupancy.removeTravelers();
            // remove N querystring
            var currentLocation = location.protocol + "//" + location.host + location.pathname;
            location.href = currentLocation;
        },
        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();
            if (typeof(selectedDateNValue) != 'undefined') {
            priv.selectedDateNValues = selectedDateNValue;
            }
            priv.bindSearchBoxEvents();
        }
    };
} (jQuery);