/*
    Class: ReservationForm
    Defines the logic for Start, and Return location select boxes.

    Depends on var Locations defined elsewhere.
*/
var ReservationForm = (function () {
    /* 
        Private variables
    */

    var start_field  = '#start_location',
        return_field = '#return_location',
        start_zip    = '#start_location_code',
        return_zip   = '#return_location_code',
        resform      = '#reservationAvailability',
        defaulted_return_date = false;


    /*
        Private methods
    */

    var is_zip_code = function (value) {
        if (value.length != 5) {
            return false;
        }

        var strValidChars = "0123456789";
        var strChar;
        var blnResult = true;

        for (i = 0; i < value.length && blnResult == true; i++) {
            strChar = value.charAt(i);
            if (strValidChars.indexOf(strChar) == -1) {
                blnResult = false;
            }
        }
        return blnResult;
    };

    var is_airport_code = function (value) {
        if (value.length > 4) {
            return false;
        }

        return true;
    };

    var locations_need_autocompletion = function () {
        var start_needs = false,
            return_needs = false;

        if (location_needs_autocomplete('start')) {
            start_needs = true;
        }

        if (location_needs_autocomplete('return')) {
            return_needs = true;
        }

        if (start_needs || return_needs) {
            return true;
        }

        return false;
    };

    var location_needs_autocomplete = function (loc) {
        var entered = $('#' + loc + '_location_code').val(),
                 ac = $('#ac_' + loc).val();

        //if ( ! (is_zip_code(entered) || is_airport_code(entered)) && ac === '0') {
        if ( ! is_zip_code(entered) && ac === '0') {
            return true;
        }
        return false;
    };

    var locations_autocomplete = function () {
        var locations = [];
        if (location_needs_autocomplete('start')) {
            locations.push({type: 'start', value: $('#start_location_code').val()});
        }

        if (location_needs_autocomplete('return')) {
            locations.push({type: 'return', value: $('#return_location_code').val()});
        }

        find_locations(locations);
    };

    var find_locations = function (locations) {
        $.ajax({
            url: BaseUrl + 'reservations/find_location',
            type: 'POST',
            cache: false,
            data: {'q': $.toJSON(locations)},
            dataType: 'json',
            success: function (data, statusText) {
                show_location_options(data);
            }
        });
    };

    var show_location_options = function (data) {
        var dom = null,
            options = [],
            found_locations = false;
        
        for (var i = 0; i < data.length; i++) {
            var locs = build_location_options(data[i]);
            options.push(locs.html);
            if (locs.present) {
                found_locations = true;
            }
        }

        if (found_locations) {
            var select_bt = $.BUTTON({id: 'select_loc'}, 'Select');
            dom = $.DIV({className: 'modal'},
                options,
                $.P({}, select_bt, $.NBSP, $.NBSP, $.NBSP, $.NBSP, $.A({href: '#', className: 'simplemodal-close'}, 'Close'))
            );
        } else {
            var select_bt = $.BUTTON({id: 'select_loc'}, 'Ok');
            dom = $.DIV({className: 'modal'},
                options,
                $.P({}, select_bt)
            );
        }

        $(select_bt).click(function () {
            var op, label;

            if ($('.start_results').length) {
                op = $('.modal .start_results input:checked');
                label = $('#start_display_' + op.attr('id')).val();
                update_location_fields('start', op.val(), label);
            }

            if ($('.return_results').length) {
                op = $('.modal .return_results input:checked');
                label = $('#return_display_' + op.attr('id')).val();
                update_location_fields('return', op.val(), label);
            }

           $.modal.close();
        });

        $.modal(dom, {escClose: false});
        $('#reservationAvailabilitySubmit').removeAttr('disabled');
    };

    var build_location_options = function (data) {
        var dom = null,
            options = [],
            exists = false;

        for (var i = 0; i < data.results.length; i++) {
            var elm = data.results[i];
            var id = data.type + 'loc' + i;
            options.push(
                $.DIV({},
                    $.INPUT({type: 'radio', 'id': id, value: elm.code, name: data.type + '_location'}),
                    $.LABEL({"for": id}, elm.name),
                    $.INPUT({type: 'hidden', 'id': data.type + '_display_' + id, name: data.type + '_display_' + id, value: elm.display})
                )
           );
        }

        if (options.length) {
            dom = $.DIV({className: data.type + '_results'},
                $.H3({}, uppercase_first(data.type) + ' location.'),
                $.P({}, 'You entered: ',  $.STRONG({}, data.query)),
                $.P({}, 'Did you mean?'),
                options
            );

            exists = true;
        } else {
            dom = $.DIV({},
                $.H3({}, uppercase_first(data.type) + ' location.'),
                $.P({}, 'You entered: ',  $.STRONG({}, data.query)),
                $.P({}, 'I\'m sorry, I\'m not sure what you entered. Please try entering a city, zip code, or airport code.')
            );
        }

        return {present: exists, html: dom};
    };

    var uppercase_first = function (value) {
        return value.substr(0, 1).toUpperCase() + value.substr(1);
    };

    var update_location_fields = function (type, code, display) {
        var original_code = code;

        $('#ac_' + type).val(original_code);
        
        if (is_airport_code(code)) {
            code     = display;
            display  = original_code;
        }

        $('#' + type + '_code_desc').empty().append(code);
        $('#' + type + '_location_code').val(display);
        
        if (Locations.indexOf(code) === -1) {
            $('#' + type + '_location').val('0');
            if (type == 'start') {
                $(return_field).val('0');
                $(return_zip).val(display);
                $('#ac_return').val(original_code);
                $('#return_code_desc').empty().append(code);
            }
        }
    };

    var selected = function (field) {
        return $(field + ' option:selected').val();
    };

    var set = function (field, val) {
        $(field).val(val);
    };

    var set_to_other = function (what) {
        var e = what == 'start' ? start_field : return_field;
        $(e).val('0');
        if (what == 'start') {
            $(return_field).val('0');
        }
    };

    var start_location = function () {
        var current = selected(start_field);
        if (current !== '0') {
            set(start_zip, current);
            set('#ac_start', current);
            set('#ac_return', current);
            set(return_field, current);
            set(return_zip, current);
        } else {
            set(start_zip, '');
            set('#ac_start', '0');
            $(start_zip).focus();
        }

        $('#start_code_desc').empty().append('&nbsp;');
        $('#return_code_desc').empty().append('&nbsp;');
    };

    var return_location = function () {
        var current = selected(return_field);
        if (current !== '0') {
            set('#ac_return', current);
            set(return_field, current);
            set(return_zip, current);
        } else {
            set(return_zip, '');
            set('#ac_return', '0');
            $(return_zip).focus();
        }

        $('#return_code_desc').empty().append('&nbsp;');
    };

    var submit = function () {
        if (locations_need_autocompletion()) {
            locations_autocomplete();

            return false;
        }

        if (Locations.indexOf($(start_zip).val()) === -1) {
            $(start_field).val(0);
        }

        if (Locations.indexOf($(return_zip).val()) === -1) {
            $(return_field).val(0);
        }

        $('#loading').show();
        $('#search_results').empty();
        $.ajax({
            url: BaseUrl + 'reservations/step_one',
            type: 'POST',
            cache: false,
            data: get_data(),
            dataType: 'html',
            success: async_callback
        });

        return false;
    };


    var get_data = function () {
        return {
            'reservation': 'reservation',
            'car': $('#car').val(),
            'start_date': $('#start_date').val(),
            'start_time': $('#start_time').val(),
            'start_location': $('#start_location').val(),
            'start_location_code': $('#start_location_code').val(),
            'return_date': $('#return_date').val(),
            'return_time': $('#return_time').val(),
            'return_location': $('#return_location').val(),
            'return_location_code': $('#return_location_code').val(),
            'ac_return': $('#ac_return').val(),
            'ac_start': $('#ac_start').val(),
            'ignore_availability': $('#ignore_availability').is(':checked') ? 1 : 0
        };
    };

    var async_callback = function (data, textStatus) {
        $('#loading').hide();
        $('#search_results').append(data);

        $('.popCar', $('#search_results')).popupWindow({ 
            height: 780, 
            width:870, 
            centerScreen: 1,
            scrollbars: 1,
            resizable: 1
        });

        $('.popCar', $('#search_results')).mouseover(function (e) {
            var tip = $(this).text(),
                div = $('<div class="tipsy tipsy-east  tipsyStepOne"><div class="tipsy-inner"></div></div>'),
                offset = $(this).offset();
            
            if (tip == '') {
                tip = $(this).children('img').attr('alt');
            }
           
            if ($(this).hasClass('carImage')) {
                offset = $(this).parent().siblings('.sr_middle').children('h4').children('a').offset();

            }

            offset.top += 24;
            offset.left -= 468;

            $('.tipsy-inner', div).empty().append('Click for details about this ' + tip);

            $('body').append(div);
            div.css('top', offset.top);
            div.css('left', offset.left);
            div.removeClass('inactive');
        });

        $('.popCar', $('#search_results')).mouseleave(function (e) {
            $('.tipsyStepOne').remove();
        });

        if ($('#addExtraDay', $('#search_results')).length) {
            $('#addExtraDay').click(function () {
                var rdate = new Date($('#return_date').val());
                rdate.setDate(rdate.getDate() + 1);
                $('#return_date').datepicker('setDate', rdate);
                $('#search_results').empty(); 

                submit();

                return false;
            });
        }
        $('#reservationAvailabilitySubmit').removeAttr('disabled');
    };

    /*
        Public methods
    */

    return {
        init: function () {


            // Validation /////////////////////////////////////////////////////

            $.validator.addMethod("mydate", function(value, element) { 

                var submit = new Date(value);
                
                var currentTime = new Date()
                var month = currentTime.getMonth() + 1
                var day = currentTime.getDate()
                var year = currentTime.getFullYear()

                var today = new Date(month + '/' + day + '/' + year);
                return submit.getTime() >= today.getTime();
            }, "Dates in the past are not allowed");

            $(resform).validate({
                onkeyup: false,
                rules: {
                    start_date: {required: true, mydate: true},
                    start_location_code: {required: true},
                    return_date: {required: true, mydate: true},
                    return_location_code: {required: true}
                },
                
                submitHandler: function (form) {
                    $('#reservationAvailabilitySubmit').attr('disabled', 'disabled');
                    submit();
                }
            });
            
            $('#reservationAvailability input, select').change(function(){
            	$('#search_results').empty();
            });


            // Autocompleter //////////////////////////////////////////////////

            var ac_url =  BaseUrl + 'reservations/load_suggestions';

            var format_ac_result = function (init) {
                return function (event, data, formatted) {
                    if (data) {
                        var display, code;

                        if (is_zip_code(data[1]) || is_airport_code(data[1])) {
                            display = data[0].replace(data[1] + ' - ', '');
                            code    = data[1];
                        } else {
                            display = code = data[2];
                        }

                        $('#ac_' + init).val(code);
                        $('#' + init + '_code_desc').empty().append(display);

                        if (Locations.indexOf(data[1]) === -1) {
                            $('#' + init + '_location').val('0');
                            if (init == 'start') {
                                $(return_field).val('0');
                                $(return_zip).val(data[1]);
                                $('#ac_return').val(code);
                                $('#return_code_desc').empty().append(display);
                            }
                        }
                    }
                };
            };

            var ac_options = {
                width: 300,
                selectFirst: false,
                max: 20,
                minChars: 3,
                matchSubset: false,
                formatResult: function (data, value) {
                    if (data) {
                        return data[1];
                    }
                }
            };

            $(start_zip).autocomplete(ac_url, ac_options);
            $(start_zip).result(format_ac_result('start'));

            $(return_zip).autocomplete(ac_url, ac_options);
            $(return_zip).result(format_ac_result('return'));


            // Datepicker /////////////////////////////////////////////////////

            var disable_holidays = function (adate) {
                var result = true,
                    year = adate.getFullYear(),
                    month = adate.getMonth() + 1,
                    day = adate.getDate(),
                    full_date = '';

                month = (month < 10) ? '0' + month : month;
                day = (day < 10) ? '0' + day : day;
               
                full_date = year + '-' + month + '-' + day;
                for (var i = 0; i < HolidaysList.length; i++) {
                    if (HolidaysList[i] == full_date) {
                        result = false;
                    }
                }

                return [result, '', (result ? '' : 'Holidays are not available')];
            };

            $("#return_date").datepicker({
                minDate: new Date(DPYear, DPMonth, DPDay),
                onSelect: function () { 
                    $(resform).validate().element('#return_date');
                    $('#search_results').empty();
                    $('#start_time').trigger('change');
                },
                beforeShowDay: function (adate) {
                    return disable_holidays(adate);
                }
            });

            $("#start_date").datepicker({
                minDate: new Date(DPYear, DPMonth, DPDay),
                onSelect: function (dateText, inst) {
                    set_todays_time(dateText);
                    
                    $(resform).validate().element('#start_date');

                    $('#search_results').empty();

                    if (!defaulted_return_date) {
                        var return_date = new Date(dateText);
                        return_date.setDate(return_date.getDate() + 1);
                        $('#return_date').datepicker('setDate', return_date);

                        $(resform).validate().element('#return_date');
                        defaulted_return_date = true;
                    }

                    $('#start_time').trigger('change');
                },
                beforeShowDay: function (adate) {
                    return disable_holidays(adate);
                }
            });

            var set_todays_time = function (dateSelected) {
                var current_date = $('#start_date').val();
                if (current_date != '' && date_is_today(current_date)) {
                    if (DPHour >= 18 || calc_time_with_zone(DPTimeZone).getHours() >= 18) {
                        var new_start_date = new Date(dateSelected);
                        new_start_date.setDate(new_start_date.getDate() + 1);
                        $('#start_date').datepicker('setDate', new_start_date);
                    } else {
                        var new_start_time = DPHour + 1;
                        var options = $('#times_copy').children('option').clone();

                        $('#start_time').empty();
                        $(options).each(function (i) {
                            if (parseInt($(this).val()) >= new_start_time) {
                                $('#start_time').append(
                                    $('<option>').text( $(this).text() )
                                                 .val( $(this).val() )
                                );
                            }
                        });
     
                        $('#start_time').val(new_start_time);
                    }
                } else {
                    if ($('#start_time').children('option').length < 10) {
                        $('#start_time').empty()
                                        .append($('#times_copy').children('option').clone())
                                        .val(9);
                    }
                }
            };


            // Start/Return locations logic ///////////////////////////////////
            $(start_field).change(start_location);
            $(return_field).change(return_location);

            if (!Prefilled) {
                set(start_zip, selected(start_field));
                set(return_zip, selected(start_field));
            } else {
                if ($(resform).valid()) {
                    $('#reservationAvailabilitySubmit').attr('disabled', 'disabled');
                    submit();
                }
            }
            
            $(start_zip).keypress(function (e) { 
                if (e.which == 13) { // Enter Key
                    return;
                }
                $('#ac_start').val('0');
                $('#start_code_desc').empty().append('&nbsp;');;
                set_to_other('start');
            });

            $(return_zip).keypress(function (e) {
                if (e.which == 13) { // Enter Key
                    return;
                }
                $('#ac_return').val('0');
                $('#return_code_desc').empty().append('&nbsp;');;
                set_to_other('return');
            });

        }
    };
})();

/// Global Functions //////////////////////////////////////////////////////////

var date_is_today = function (aDate) {
    var parts = aDate.split('/');
    if (parseInt(parts[0]) - 1 === DPMonth
        && parseInt(parts[1]) === DPDay
        && parseInt(parts[2]) === DPYear) {
        return true;
    }
    return false;
};

/*
    @param offset - -5 for GMT-5, +8 for GMT+8
    @param date object [optional]
*/
function calc_time_with_zone() {
    var offset, d, utc, nd;

    offset = arguments[0];
    if (arguments.length === 2) {
        d = arguments[1];
    } else {
        // create Date object for current location
        d = new Date();
    }

    // convert to msec
    // add local time zone offset
    // get UTC time in msec
    utc = d.getTime() + (d.getTimezoneOffset() * 60000);
   
    // create new Date object for different city
    // using supplied offset
    nd = new Date(utc + (3600000 * offset));
   
    return nd;
}

/// Init //////////////////////////////////////////////////////////////////////
$(function () {
    ReservationForm.init();

    $('.popCar').popupWindow({ 
        height: 780, 
        width:870, 
        centerScreen: 1,
        scrollbars: 1,
        resizable: 1
    });

    /*
    $('.popCar').mouseover(function (e) {
        $('.hoverMessage .tipsy').removeClass('inactive');
    });

    $('.popCar').mouseleave(function (e) {
        $('.hoverMessage .tipsy').addClass('inactive');
    });
*/
});

$(document).ready(function () {
    var start_time, return_time;
    var friday_return_time = 12;
    var options = $("#start_time").children('option');

    $('#start_time').bind('change', function() {
        start_time = parseInt($(this).val());
        $('#return_time').empty();

        if (friday_return_time && friday_return_time > 0) {
            var day_check = new Date();
            var pd = $('#return_date').val().split('/');

            day_check.setDate(pd[1]);
            day_check.setMonth(parseInt(pd[0]-1));
            day_check.setYear(pd[2]);
            day_check.setHours(start_time);

            day_utc = calc_time_with_zone(-5, day_check);
            var day_nr = day_utc.getDay();
            if (day_nr === 5) { // Friday
                if (start_time >= friday_return_time) {
                    start_time = friday_return_time;
                }
            }
        }

        $(options).each(function(i){
            if (parseInt($(this).val()) <= start_time) {
                $('#return_time').append( 
                    $('<option>').text($(this).text()).val($(this).val())
                );
            }
        });

        $('#return_time').val(12).change();
    });

    $('#start_time').val(12).change();
    $('#return_time').val(12).change();
});
