/**
 * @fileOverview Classes, functions for tour pages
 * 
 * @author Whl Member 
 */

/**
* @namespace Contains common functions, classes for Tour
*/

Whl.Tour = {};

/**
 * 
 * @class Whl.Tour.Rate
 * @param {String} tourUrl Tour URL string
 * @param (Integer) childrenRate
 * @param {Array} initSeason Array of date that has season.
 */
Whl.Tour.Rate = function(initData){
    // Initialize default setting
    this._setting = {siteId: 0,
                     id: $('#tour_id').val(),
                     url: '',
                     childrenRate: null,
                     adult: $('#adults'),
                     child: $('#children'),
                     datePicker: $('#tourDatePicker'),
                     departTime: $('#depart_time'),
                     isInit: false,
                     startDate: '',
                     complete: null,
                     jsonp: false,
                     calendarOpt: {},
                     isEmbed: false};
    this._season = initData.season || {};
    if(Object.isEmpty(this._season)){
        $('#no_rate').show();
        $('#book').hide();
        $('#adult-has-price').hide();
        $('#children-has-price').hide();
    }else {
    	$('#has_rate').show();
    }
    // Override setting from the parameter 
    Object.extend(this._setting, initData.setting);
    this._setting.validRange = true;
    this._setting.initAddTours = false;
    this._setting.selectedDate = '';
    this._setting.adultRateBody = ['', Message.Error.unAvailableRate];
    this._setting.childRateBody = ['', ''];
    // Start the class
    this.initialize();
};

Whl.Tour.Rate.prototype = {
    /**
     * Initialize the class: Calendar, events ...
     * 
     * @returns {void}
     */
    initialize: function(){
        // Settings for the calendar object
        var option = {dateFormat: 'dd M yy', numberOfMonths: 2, stepMonths: 2, minDate: new Date()};
        Object.extend(option, this._setting.calendarOpt);
        var dataId = Whl.getCookie('tour_rate_id');
        var dataDate = Whl.getCookie('tour_rate_date');
        if(!this._setting.startDate && dataDate && dataId == this._setting.id) 
            option.defaultDate = $.datepicker.parseDate('dd M yy', dataDate);
        else {
            Whl.deleteCookie('tour_rate_date');
            dataDate = null;
        }
        option.beforeShowDay = this._beforeShowDay.bind(this);
        option.onChangeMonthYear = this._changeMonthYear.bind(this);
        option.onSelect = this._updateCurrentPrice.bind(this);
        this._setting.datePicker.datepicker(option);
        if (!Object.isUndefined(this._setting.cssClass)) 
            this._setting.datePicker.next().css({float: 'left', 'margin-top': '10px', 'margin-right':'5px', 'margin-top':'7px'});
        // Adult & child
        var firstDate = this._getFirstDate();
        if (Object.isObject(this._setting.adult)) {
            // Get adult data from cookie/first date season
            var dataAdult = Whl.getCookie('tour_rate_adult');
            if (dataAdult) {
                if (dataId == this._setting.id) 
                    firstDate = dataDate ? dataDate : (this._setting.startDate ? this._setting.startDate 
                                                                               : (new Date()).toDateStringExt());
                else {
                    Whl.deleteCookie('tour_rate_adult');
                    dataAdult = null;
                }
            }
            if (!Object.isUndefined(this._season[firstDate])) {
                var rangeMin = parseInt(this._season[firstDate]['min_range']);
                if (dataAdult && parseInt(dataAdult) < rangeMin) {
                    this._setting.validRange = false;
                } else if (!dataAdult) {
                    dataAdult = (rangeMin < 2 ? 2 : rangeMin);
                    this._setting.validRange = true;
                }
            }
            if (dataAdult) this._setting.adult.val(dataAdult);
            // Register Adult change event handler
            this._setting.adult.change(function() {
                this._updateCurrentPrice($.datepicker.formatDate('dd M yy', this._setting.datePicker.datepicker('getDate')));
            }.bind(this));
        }
        if (Object.isObject(this._setting.child)) {
            var dataChild = Whl.getCookie('tour_rate_child');
            if (dataChild && dataId == this._setting.id){
                this._setting.child.val(dataChild);
            } else Whl.deleteCookie('tour_rate_child');
            this._setting.child.change(function() {
                this._updateCurrentPrice($.datepicker.formatDate('dd M yy', this._setting.datePicker.datepicker('getDate')));
            }.bind(this));
        }
        // Departure time
        if (!this._setting.startDate) {
            var dataDepart = Whl.getCookie('tour_rate_depart');
            if (dataDepart && dataId == this._setting.id) 
                this._setting.departTime.val(dataDepart);
            else {
                Whl.deleteCookie('tour_rate_depart');
                dataDepart = null;
            }
            this._setting.departTime.change(function() { 
                Whl.setCookie('tour_rate_depart', $(this).val());
            });
        }
        Whl.setCookie('tour_rate_id', this._setting.id);
        // Add other Text
        if (this._setting.childrenRate == 1) $('#children-price-text').text(Message.free);
        else if (this._setting.childrenRate == 0) $('#children-price-text').text(Message.notAllow);

        // View first date rate
        if (!this._setting.startDate) {
            if(firstDate){
                this._setting.datePicker.datepicker('setDate', firstDate.toDate());
                this._updateCurrentPrice(firstDate);
            }
        } else {
            this._updatePrice(firstDate, true);
        }
        // Add event handler for submit booking
        if (Object.isObject(this._setting.adult)) {
            $('#book').click(function() {
                arguments[0].preventDefault();
                this.submitBooking();
            }.bindEvent(this));
        }
    },
    /**
     * Ajax request SEASON action
     * 
     * @param {Date} date
     * @param {Function} complete Callback function will be executed while request completed
     * @param {Array} params
     * @returns {void}
     */
    get: function(date, complete, params, selDate){
        params = params || [];
        complete = complete || null;
        var data = Object.createQueryString(params);
        selDate = selDate || null;
        if (selDate) data += (data ? '&' : '') + 'selDate=' + date.toDateStringExt();
        else data += (data ? '&' : '') + 'month=' +  (1 + date.getMonth()) + '&year=' + date.getFullYear();
        if (this._setting.childrenRate === null) data += '&setting=1';
        var ajaxOption = {
            url : this._setting.url + '?act=getRate&' + data,
            success: function(data) {
                if (this._setting.childrenRate === null) Object.extend(this._setting, data.setting);
                Object.extend(this._season, data.season);
                if (Object.isFunction(this._setting.complete)) this._setting.complete();
                DP_jQuery.datepicker._adjustDate('#' + this._setting.datePicker.attr('id'));
                if (Object.isFunction(complete)) complete(date.toDateStringExt(), data.season, selDate);
            }.bind(this),
            async: false};
        if (this._setting.jsonp) {
            ajaxOption.dataType = 'jsonp';
        } else {
            ajaxOption.dataType = 'json';
        }
        $.ajax(ajaxOption);
    },
    /**
     * Submit booking 
     * 
     * @returns {void}
     */
    submitBooking: function() {        
        // Validate data
        var validate = function() {
            /*var groupMin = parseInt($('#group_min').val()), groupMax = parseInt($('#group_max').val());
            if(groupSize > groupMax || groupSize < groupMin){
                var message = Message.Error['group_size'].replace('{group_max}', groupMax);
                message = message.replace('{group_min}', groupMin);
                Whl.Dialog.error({remove:true, title: Message.Dlg.error, msg: message.replace(/\r\n/g, '<br/>')});
                return false;
            }*/
            // Validate Price
            var selDate = $.datepicker.formatDate('dd M yy', this._setting.datePicker.datepicker('getDate'));
            var rate = !Object.isUndefined(this._season[selDate]) ? this._season[selDate] : null;
            var groupSize = parseInt(this._setting.child.val()) + parseInt(this._setting.adult.val());
            if(groupSize > rate.max_range || groupSize < rate.min_range){
                var message = Message.Error['group_size'].replace('{group_max}', rate.max_range);
                message = message.replace('{group_min}', rate.min_range);
                Whl.Dialog.error({remove:true, title: Message.Dlg.error, msg: message.replace(/\r\n/g, '<br/>')});
                return false;
            }
            if (parseInt(rate.adult) == 0) {
                Whl.Dialog.error({remove:true, title: Message.Dlg.error, msg: Message.Error.noRate});
                return false;
            }
            return true;
        }.bind(this);
        if (validate()) { 
            var option = {
                type: 'POST',
                url: '?act=Booking',
                dataType: 'json',
                data: $('#frmRate').serialize(),
                success:  function(data) {
                    setTimeout(function() {Whl.Dialog.closeMsg();}, 1);
                    if (data.result) {                    
                        if (this._setting.isEmbed){                                
                            if(!$.browser.webkit ){                                
                                window.open(data.action,'','status=0,toolbar=1,scrollbars=1,menubar=1,'+'width='+screen.width+',height='+screen.height); 
                            }else{//for safari                          
                                if($("#bookingOnSafari").length == 0) $('body').append("<div id='bookingOnSafari'>"+Message.continueBooking+"</div>");
                                $("#bookingOnSafari").dialog({
                                    title : '',
                                    bgiframe: true,
                                    autoOpen: false,
                                    modal: true,
                                    width: 300,
                                    height: 100,
                                    buttons: {
                                        "Close": function() {
                                            $('#bookingOnSafari').dialog('close');
                                        },
                                        "OK": function() {
                                            $('#bookingOnSafari').dialog('close');                                            
                                            window.open(data.action,'','status=0,toolbar=1,scrollbars=1,menubar=1,'+'width='+screen.width+',height='+screen.height); 
                                        }
                                    }
                                });                                
                                $("#bookingOnSafari").dialog('open');                                
                            }                                                       
                        }
                        else  location.href = data.action;
                    } else Whl.Dialog.error({title: 'Error', msg: Message.Error[data.error]});
                }.bind(this),
                error: function(XMLHttpRequest, textStatus, errorThrown) {
                    Whl.Dialog.closeMsg();
                    //Whl.Dialog.error({msg: textStatus, remove: true});
                }
            };
            if (this._setting.isEmbed) option.async = false;
            Whl.Dialog.msg({title: Message.Dlg.title3, msg: Message.Dlg.checking, remove: true});
            $.ajax(option);
        }
    },
    /**
     * Get First date is available
     * toDateStringExt
     * @returns string String date
     */
    _getFirstDate: function() {
        var firstDate = null;
        for (var key in this._season) {
            if (this._setting.startDate) {
                if (this._setting.startDate == key 
                    || Date.compareDate2(this._setting.startDate, key) < 0) {
                    firstDate = key;
                    this._setting.startDate = firstDate;
                    break;
                } else continue;
            } else {
                firstDate = key;
                break;
            }
        }
        return firstDate;
    },
    /**
     * Calculate the price for current selected date
     * 
     * @returns {void}
     */
    _viewPrice: function(date, seasonData) {
        var strDate = date;
        this._setting.validRange = true;
        seasonData = seasonData || null;
        // Get rate of current date
        var rate = !Object.isUndefined(this._season[strDate]) ? this._season[strDate] : null;
        if (!rate) {
            // Get the first rate
            strDate = this._getFirstDate();
            rate = !Object.isUndefined(this._season[strDate]) ? this._season[strDate] : null;
        }
        if (!rate) return;
        var adults = parseInt(this._setting.adult.val()), available = true;
        var children = parseInt(this._setting.child.val());
        var numberPerson = adults + children;
        // Check has price in selection date
        if (numberPerson < parseInt(rate['min_range'])) this._setting.validRange = false;
        if (!this._setting.validRange || (seasonData && Object.isUndefined(seasonData[strDate]))) {
            rate.adult = rate.child = rate.discount = rate.price = rate.price_perpax = '';
            if (this._setting.startDate) {
                if (!this._setting.initAddTours) $('#date-' + this._setting.id).remove();
                else {
                    $('#tour-price-' + this._setting.id).html('');
                    $('#add-tour-' + this._setting.id).hide();
                    Whl.Dialog.error({remove:true, title: Message.Dlg.error, msg: Message.Error[1002]});
                }
                return;
            }
        } else if (this._setting.startDate) $('#add-tour-' + this._setting.id).show();

        // Save cookie if has rate for all requirement
        if (!this._setting.startDate) {
            Whl.setCookie('tour_rate_adult', adults);
            Whl.setCookie('tour_rate_child', this._setting.child.val());
            Whl.setCookie('tour_rate_date', strDate);
        }
        // View Rate info
        if (typeof this._setting.price_perpax == 'boolean' && this._setting.price_perpax == true){
            $('#tour-price-' + this._setting.id).html(rate.price_perpax);
            this._setting.datePicker.val(date);
        } else {
            if (!available) {
                $('#adult-has-price, #children-has-price, #total-price').hide();
                $('.discount').hide();
            } else {
                if (!rate.adult) {
                    if (!this._setting.adultRateBody[0]) this._setting.adultRateBody[0] = $('#adult-has-price').html();
                    $('#adult-has-price').html(this._setting.adultRateBody[1]);
                } else {
                    if (!$('#adult-price').isExist()) {
                        $('#adult-has-price').html(this._setting.adultRateBody[0]);
                    }
                    $('#adult-price').text(rate.adult);
                }
                $('#total-price').text(rate.price);
                $('#adult-has-price, #children-has-price, #total-price, #book').show();
                //if(rate.discount > 1)rate.discount = parseInt(rate.discount);
                if (rate.discount > 0) {
                    $('.discount').show();
                } else $('.discount').hide();
                $('#discount').text(rate.discount);
            }
            if ( this._setting.childrenRate==2 || this._setting.childrenRate==3) {
                if (!rate.adult) {
                    if (!this._setting.childRateBody[0]) this._setting.childRateBody[0] = $('#children-has-price').html();
                    $('#children-has-price').html(this._setting.childRateBody[1]);
                } else {
                    if (!$('#children-price').isExist()) {
                        $('#children-has-price').html(this._setting.childRateBody[0]);
                    }
                    $('#children-price').text(rate.child);
                }
                $('#children-price-text').css('visibility', $(this._setting.child).val()==0 || !available ? 'hidden' : 'visible');
            }
            $('#depart_date').val(strDate);
        }
        this._setting.initAddTours = true;
        this._setting.selectedDate = strDate;
        // Check available alloment
        this._checkAlmStatus($.datepicker.parseDate('dd M yy', strDate));
    },
    /**
     * Update price for the current date
     * 
     * @param date
     */
    _updateCurrentPrice: function(date) {
        if (!Object.isObject(date)) date = Date.toDate(date);
    	this.get(date, this._viewPrice.bind(this), 
                {'adults': Object.isObject(this._setting.adult) ? this._setting.adult.val() : this._setting.adult, 
                        'children': Object.isObject(this._setting.child) ? this._setting.child.val() : this._setting.child}, true);
    },

    /**
     * Update new available price for the 2 next months
     * 
     * @return {void}
     */
    _updatePrice: function(date, callUpdate) {
        callUpdate = callUpdate || false;
    	var updateDate = date || $.datepicker.formatDate('dd M yy', this._setting.datePicker.datepicker('getDate'));
    	if (!Object.isObject(updateDate)) updateDate = Date.toDate(updateDate);
        // Get rate
        this.get(updateDate, callUpdate ? function() {this._updateCurrentPrice(this._setting.selectedDate ? this._setting.selectedDate: this._getFirstDate());}.bind(this) : null, 
                            {'adults': Object.isObject(this._setting.adult) ? this._setting.adult.val() : this._setting.adult, 
                             'children': Object.isObject(this._setting.child) ? this._setting.child.val() : this._setting.child});
    },
    /**
     * Disable or enable day on calendar if has or not has available season
     * 
     * @param {Date} date Date object
     * @return {Array}
     */
    _beforeShowDay: function(date){
        var strDate = $.datepicker.formatDate('dd M yy', date);
        if(!Object.isUndefined(this._season[strDate])){
            return [true, ''];
        }
        return [false, ''];
    },
    /**
     * Event change month handler, get price for this month if not available
     * 
     * @param {Number} year
     * @param {Number} month
     * @param {Object} inst
     * @returns {void}
     */
    _changeMonthYear: function(year, month, inst) {
        if (this._setting.isInit) {
            var date = new Date();
            date.setFullYear(year, month-1, 1);
            this._updatePrice($.datepicker.formatDate('dd M yy', date));
        } else this._setting.isInit = true;
    },
    /**
     * 
     * @param date
     * @return
     */
    _checkAlmStatus: function(date){
        var strDate = $.datepicker.formatDate('dd/mm/yy', date);
        var sendData = 'site_id='+this._setting.siteId+'&svc_type=tour&start_date='+strDate+'&ids='+this._setting.id;
        if(window.almApplied){
            $.ajax({
                type: 'POST',
                url:  '/?act=checkAlmStatus',
                data: sendData, async: true,
                success: function(result){
                    var res = eval('('+result+')');
                    var bHasAlm = false;
                    $('div[id^="alm_"]').hide();
                    for(i=0; i<res.data.length; i++){
                        if(!res.data[i].type){                        
                            if (res.data[i].num<=0) $('#alm_'+res.data[i].id).hide();
                            else{
                                $('#alm_'+res.data[i].id).show();
                                $('#alm_'+res.data[i].id).attr('title', 'Available unit: '+res.data[i].num);
                            }
                        }
                    }
                }
            });
        }
    }
};
