﻿// Encapsulate names in a closure
(function() {
    //Opens popup window with airport list
    function OpenAirportPopUpWindow(type, lang) {
        if (type == "from")
            window.open("http://www.pamediakopes.gr/dreamflight/AirportsList.aspx?type=from&lang=" + lang, null, "width=712,height=600,status=no,toolbar=no,scrollbars=yes");
        else if (type == "to")
            window.open("http://www.pamediakopes.gr/dreamflight/AirportsList.aspx?type=to&lang=" + lang, null, "width=712,height=600,status=no,toolbar=no,scrollbars=yes");
    }

    function ForceDisplayOfAutoCompleteForElement(el) {
        var keyEvent = jQuery.Event("keydown");
        keyEvent.which = 46;
        keyEvent.keyCode = 46;
        $(el).trigger("focus");
        $(el).trigger(keyEvent);
    }

    function CheckAllFlightsValidations() {
        var isValid = true;

        validAirportRegExp = new RegExp(".*[\\(|\\[][a-zA-Z]{3}[\\]|\\)]|^[a-zA-Z]{3}$");

        if ($('#from').val().length < 3) {
            $('#from').trigger("blur");
            ForceDisplayOfAutoCompleteForElement($('#from'));
            isValid = false;
        }
        else if (!validAirportRegExp.test($('#from').val())) {
            $('#from').trigger("blur");
            ForceDisplayOfAutoCompleteForElement($('#from'));
            isValid = false;
        }

        if ($('#to').val().length < 3) {
            $('#to').trigger("blur");
            ForceDisplayOfAutoCompleteForElement($('#to'));
            isValid = false;
        }
        else if (!validAirportRegExp.test($('#to').val())) {
            $('#to').trigger("blur");
            ForceDisplayOfAutoCompleteForElement($('#to'));
            isValid = false;
        }

        if ($('#from').val().toLowerCase() == $('#to').val().toLowerCase() && $('#to').val().length > 1) {
            $('#to').trigger("blur");
            $('#to').trigger("focus");
            isValid = false;
        }
        if (parseInt($('#adults').val(), 10) + parseInt($('#children').val(), 10) + parseInt($('#infants').val(), 10) > 8) {
            isValid = false;
        }
        if (parseInt($('#adults').val(), 10) < parseInt($('#infants').val(), 10)) {
            isValid = false;
        }

        return isValid;
    }


    function SubmitNewFlightsSearch() {
        if (CheckAllFlightsValidations()) {

            var tmpDepDate = $('#depDate').val().split("/");
            var depDay = tmpDepDate[0];
            var depMonth = tmpDepDate[1];
            var depYear = tmpDepDate[2];
            $('#completeDepDate').val(depYear + '-' + depMonth + '-' + depDay);

            var tmpRetDate = $('#retDate').val().split("/");
            var retDay = tmpRetDate[0];
            var retMonth = tmpRetDate[1];
            var retYear = tmpRetDate[2];
            $('#completeRetDate').val(retYear + '-' + retMonth + '-' + retDay);

            //Hack Netvolution submit page
            $('#__VIEWSTATE').remove();
            $('#NetvolutionPage').attr("method", "get");
            $('#SearchFlightForm').attr("method", "get");
            var pathname = location.pathname;
            pathname = pathname.toLowerCase();
            var action = $('#SearchFlightForm').attr("action");
            action = action.toLowerCase();
            if (pathname.match("dreamflightstage")) {
                action = action.replace("dreamflight", "dreamflightstage");
                $('#SearchFlightForm').attr("action", action);
            }

            //Set aid if aid was passed as a param in the url
            var aidValue = $(document).getUrlParam("aid");
            try {
                var aidInt = parseInt(aidValue, 10);
                if (aidInt > 0) {
                    $('#aid').val(aidValue);
                }
            }
            catch (err) { }

            //$('#NetvolutionPage').attr("action",$('#SearchFlightForm').attr("action")); 	
            //$('#NetvolutionPage').submit();
            $('#SearchFlightForm').submit();

        }
    }


    function init() {
        /* Date format used in date <-> string conversions using the datepicker functions */
        var dateFormat = 'dd/mm/yy',
        /* data from the flightsearchform cookie. This stores the date and place selections */
        cookieDataRaw = $.cookie("flightsearchform"),
        /* Parsed cookie data */
        cookieData,
        /* Splitted cookie data */
        expandedCookie;

        /* Set Defauls for radio button */
        $("#flighttype_1").attr("checked", "checked");

        /* Function: customRange
        * Description: Link the start and end date fields on both calendars.
        *   When you select a starting date. The ending date has to be bigger than it.
        */
        function customRange(input) {
            var minimum = 0;

            if (input.id == 'retDate') {
                minimum = $('#depDate').datepicker("getDate");
                minimum.setDate(minimum.getDate());
            }
            return {
                minDate: minimum
            };
        }

        /* If we have a cookie with previous data, we recover it */

        if (typeof (cookieDataRaw) == "string") {
            expandedCookie = cookieDataRaw.split("\t");
            cookieData = {
                place: expandedCookie[0],
                start: expandedCookie[1],
                end: expandedCookie[2]
            };
        }

        /* Configures the datepicker */
        $.datepicker.setDefaults({
            dateFormat: dateFormat,
            numberOfMonths: 2,
            mandatory: true,
            minDate: 0,
            firstDay: 1,
            changeFirstDay: false,
            showOn: "both",
            buttonImage: "http://www.pamediakopes.gr/homepageassets/theme/images/calendar.gif",
            buttonImageOnly: true
        });

        $("#retDate").datepicker({
            beforeShow: customRange,
            onSelect: function(datetext) {
                var newend = $.datepicker.parseDate(dateFormat, datetext);
            }

        });

        $("#depDate").datepicker({
            beforeShow: customRange,
            /* This will make the ending date as bigger as the starting date if the starting
            date changs */
            onSelect: function(datetext, datebox) {

                var newstart = $('#depDate').datepicker('getDate');
                var end = $('#retDate').datepicker('getDate');

                if (newstart >= end) {
                    /* If you select a starting date bigger than the ending date, the ending date
                    * will be CHANGED to depDate + 3 days */
                    newstart.setDate(newstart.getDate() + 3);
                    document.getElementById('retDate').value = $.datepicker.formatDate(dateFormat, newstart);
                }
            }
        });

        /* Start with today + 1 week, and end 3 days after */
        var today = new Date();
        var shouldstart = new Date();
        shouldstart.setDate(today.getDate() + 7);

        /* Let's validate the stored dates from the cookies. 
        * previous date: this date was stored in the cookie and has been recovered.
        * proposed date: default initialization date.
        *
        * It can hapen that even if we have a date, this date is older than the default initial date.
        * In this case, even if we have a previous date, we choose the proposed date
        */
        function shouldIUseTheCookie(previous, proposed) {
            if (previous && $.datepicker.parseDate(dateFormat, previous) > proposed) return true;
            return false;
        }

        /* If we have previous data, we use it, if not, we get todays date */
        var usecookie = false;
        if (cookieData)
            usecookie = shouldIUseTheCookie(cookieData.start, today);

        document.getElementById('depDate').value = (usecookie) ? cookieData.start : $.datepicker.formatDate(dateFormat, shouldstart);
        shouldstart.setDate(shouldstart.getDate() + 3);
        document.getElementById('retDate').value = (usecookie) ? cookieData.end : $.datepicker.formatDate(dateFormat, shouldstart);

        // Datepicker
        $('#depDate').datepicker({ inline: true });
        $('#retDate').datepicker({ inline: true });

        //Enable Return Datepicker if the flighttype_1 radio button is clicked  
        $('#flighttype_1').bind(
		'click',
		function() {
		    $('#retDate').datepicker("enable");
		    $('#timeRet').removeAttr("disabled", "disabled");
		}
	);

        //Disable Return Datepicker if the flighttype_2 radio button is clicked  
        $('#flighttype_2').bind('click',
		function() {
		    $('#retDate').datepicker("disable");
		    $('#timeRet').attr("disabled", "disabled");
		}
	);

        $('.link_red_airport').hover(
		function() {
		    $(this).addClass('cursor-hand');
		},
		function() {
		    $(this).removeClass('cursor-hand');
		}
	);

        //Validations and Error messages start here!

        //Check airport textboxes for error
        $('#from').blur(function() {

            a = new RegExp(".*[\\(|\\[][a-zA-Z]{3}[\\]|\\)]|^[a-zA-Z]{3}$");

            if ($('#from').val().length < 3) {
                $("#error-from-is-empty").show();
            }
            else if (!a.test($('#from').val())) {
                $("#error-from-is-empty").show();
            }
            else {
                $("#error-from-is-empty").hide();
            }
        });

        $('#to').blur(function() {

            a = new RegExp(".*[\\(|\\[][a-zA-Z]{3}[\\]|\\)]|^[a-zA-Z]{3}$");

            if ($('#to').val().length < 3) {
                $("#error-to-is-empty").show();
            }
            else if (!a.test($('#to').val())) {
                $("#error-to-is-empty").show();
            }
            else {
                $("#error-to-is-empty").hide();
            }

            if ($('#from').val().toLowerCase() == $('#to').val().toLowerCase()) {
                $("#error-from-and-to-are-the-same").show();
            }
            else {
                $("#error-from-and-to-are-the-same").hide();
            }
        });


        // Add Select All behaviour on click for all textboxes
        var inputSelected = undefined;
        $("input[type=text]").focus(function() {
            // Select field contents
            if (inputSelected == this)
                return;
            inputSelected = this;
            this.select();
        });

        //Check total number of passengers is 8 or less
        $('#adults, #children, #infants').blur(function() {
            if (parseInt($('#adults').val(), 10) + parseInt($('#children').val(), 10) + parseInt($('#infants').val(), 10) > 8) {
                $("#error-too-many-passengers").show();
            }
            else {
                $("#error-too-many-passengers").hide();
            }
        });

        //Check the number of infants is not more than the number of adults
        $('#infants').blur(function() {
            if (parseInt($('#adults').val(), 10) < parseInt($('#infants').val(), 10)) {
                $("#error-too-many-infants-for-adults").show();
            }
            else {
                $("#error-too-many-infants-for-adults").hide();
            }
        });

        $('#findFlight').bind('click', SubmitNewFlightsSearch);

        // show links after thickbox related stuff has loaded
        // j.gonel note: this is bad - css goes in the css files.
        $('#airport-select-from-link,#airport-select-to-link').css('display', 'inline');
        // Accent folding
        var accentMap = {
            'á': 'a',
            'é': 'e',
            'í': 'i',
            'ó': 'o',
            'ú': 'u',
            'ά': 'α',
            'έ': 'ε',
            'ί': 'ι',
            'ή': 'ι',
            'ύ': 'ι',
            'η': 'ι',
            'υ': 'ι',
            'ό': 'ο',
            'ώ': 'ο',
            'o': 'ο'
        };

        function accent_fold(s) {
            if (!s) { return ''; }
            var ret = '';
            s = s.toLowerCase();
            for (var i = 0; i < s.length; i++) {
                ret += accentMap[s.charAt(i)] || s.charAt(i);
            }
            return ret;
        };

        var previous_autocomplete = $.fn.autocomplete;
        $.getScript
		(
			"/template/js/jquery.ui.autocomplete.js",
			function() {
			    configureAutoComplete();
			    $.fn.autocomplete = previous_autocomplete || $.fn.autocomplete;
			}
		);

        function configureAutoComplete() {
            // Configuration for the autocomplete
            $("input.airportlist").autocomplete({
                // This list should be preloaded before
                list: pd.flights.settings.autocompleteList,

                wrapper: "<ul class='jq-ui-autocomplete-custom'></ul>",

                timeout: 200,
                autoSelectWhenOneItemInList: true,
                insertText: function(entry) {
                    var name = entry[1][0],
				idx = entry.matchedIdx;
                    if (idx > 0 && idx < entry[1].length)
                        name = entry[1][idx];
                    return name;
                },
                adjustWidth: false,

                matcher: function(typed) {
                    return new RegExp(accent_fold(typed));
                },

                template: function(entry) {
                    var name = entry[1][0],
				country = entry[2][0],
				idx = entry.matchedIdx;
                    if (idx > 0) {
                        if (idx < entry[1].length) name = entry[1][idx];
                        if (idx < entry[2].length) country = entry[2][idx];
                    }
                    return '<li class="airportItem depth' + entry.depth + '"><div class="airport-autocomplete-item"><div class="country">' + country + '</div>' + name + '</div></li>';
                },
                match: function(typed, matcher, depth) {
                    var i = 0,
			        res = undefined,
			        totalLanguages = this[1].length;

                    if (!this.accentFolded) {
                        this.accentFolded = [new Array(totalLanguages), new Array(totalLanguages)];
                        for (; i < totalLanguages; i++) {
                            this.accentFolded[0][i] = accent_fold(this[1][i]);
                            this.accentFolded[1][i] = accent_fold(this[2][i]);
                        }
                    }

                    for (i = 0; i < totalLanguages; i++) {
                        res = this.accentFolded[0][i].match(matcher) || this.accentFolded[1][i].match(matcher);
                        if (res) break;
                    }

                    if (!res) return false;
                    this.depth = depth;
                    this.matchedIdx = i;
                    return true;
                },
                filterList: function(list, val) {
                    if (list.length == 0) return [];

                    var stack = [[list, 0, 0]],
				results = [],
				currentDepth = 0,
				matcher = this.matcher(val),
				totalMatches = 0;

                    while (stack.length > 0) {
                        var stackItem = stack.pop(),
					currentList = stackItem[0],
					currentIndex = stackItem[1];
                        currentDepth -= stackItem[2];

                        while (currentList[currentIndex]) {
                            if (this.maxResults && this.maxResults == totalMatches)
                                break;

                            var currentElement = currentList[currentIndex],
						matched = 0;

                            if (this.match.call(currentElement, val, matcher, currentDepth)) {
                                results.push(currentElement);
                                totalMatches++;
                                matched = 1;
                            }
                            currentIndex++;
                            if (currentElement[3]) {
                                stack.push([currentList, currentIndex, matched]);
                                currentList = currentElement[3];
                                currentIndex = 0;
                                currentDepth += matched;
                            }
                        }
                    }

                    return results;
                }
            }).bind("activated.autocomplete", function(e) {
                if (typeof (pageTracker) != "undefined") {
                pageTracker._trackEvent('Flight search box', 'Autocomplete airport selected', 'Flight search box');
                }
            });
        }

        // Initialization for input elements persistence. Check the relevant section for
        // definitions.
        var searchBoxCookieCollection = new SearchBoxCookieCollection(inputElements);
        searchBoxCookieCollection.loadObjects();

        // Determine which option is active, and run the appropriate click event.
        if ($("#flighttype_1").attr("checked") == true) $("#flighttype_1").click();
        else $("#flighttype_2").click();

        // bind saving the cookies to window.unload.
        $(window).bind("unload", function() { searchBoxCookieCollection.saveObjects(); });


        // Set the colorbox to play.
        $(".airport-choice-link").colorbox({ iframe: true, innerWidth: 670, innerHeight: 450 });
    }


    ////////////////////////////// Input Elements Section ////////////////////////////////
    // The elements to persist into cookies. Name is the object's id (and inferred cookie name),
    // while property determines the property of the DOM object that will be loaded and saved.
    var inputElements = [
		{ name: "from", property: "value" },
		{ name: "to", property: "value" },
		{ name: "depDate", property: "value" },
		{ name: "retDate", property: "value" },
		{ name: "calendarCheckBox", property: "checked" },
		{ name: "directflight", property: "checked" },
		{ name: "adults", property: "value" },
		{ name: "children", property: "value" },
		{ name: "infants", property: "value" },
		{ name: "timeDep", property: "value" },
		{ name: "timeRet", property: "value" },
		{ name: "seatclass", property: "value" },
		{ name: "airline", property: "value" },
		{ name: "flighttype_1", property: "checked" },
		{ name: "flighttype_2", property: "checked" }
	];


    /**
    * An object that manages saving and loading all cookie elements.
    * It does this by creating proxy objects to load and save cookies.
    * It requires an array of objects like [inputElements] to work.
    */
    function SearchBoxCookieCollection(arr) {
        // The proxy objects array.
        this.objects = [];

        // A string to prepend to each cookie's name to make sure it's unique.
        this.inputElementsCookie = "dreamflight.searchbox.elements";

        // A function that returns the default cookie save options.
        // Currently only contains the expiration date, which is set to 2 hours.
        this.inputElementCookieOptions = function() {
            var d = new Date();
            var plus2Hours = 60 * 60 * 1000 * 2;
            d.setTime(d.getTime() + plus2Hours);
            return { expires: d }
        }

        // This loop creates the proxy objects responsible for loading and saving the cookies.
        // Each object defines some necessary properties and two methods (set, get).
        for (var i = 0; i < arr.length; i++) {
            this.objects.push({
                name: arr[i].name,
                property: arr[i].property,

                // Depending on the target property of each object, we have 2 different behaviors:
                // If target property = "checked", then the passed value is evaluated as a boolean.
                // Else, it 's evaluated as a string.
                set: function(val) {
                    if (val)
                        if (this.property == "checked")
                        $("#" + this.name).attr(this.property, (val == "true"));
                    else
                        $("#" + this.name).attr(this.property, val);
                },

                // This returns the contents of the object.
                get: function() {
                    return $("#" + this.name).attr(this.property);
                }
            });
        }

        // The three functions below are implemented for ease of use.
        this.saveObjects = function() {
            var cookieStr = "";

            for (var i = 0; i < this.objects.length; i++)
                cookieStr += "\t" + this.objects[i].get();

            $.cookie(this.inputElementsCookie,
				cookieStr.substr(1), this.inputElementCookieOptions);
        }

        this.loadObjects = function() {
            var cookieStr = $.cookie(this.inputElementsCookie);
            if (!cookieStr) return;
            cookieStr = cookieStr.split("\t");

            for (var i = 0; i < this.objects.length; i++) {
                this.objects[i].set(cookieStr[i]);
            }
        }

        this.clearObjects = function() {
            $.cookie(this.inputElementsCookie, null);
        }
    }

    $(init);
})();