jQuery.noConflict();
(function ($) {
    "use strict";
    createNamespace('Rtk.ThIntl.Option');

    $.fn.extend({
        closestByTagName: function(tagname) {
            var tag = tagname.toUpperCase(),
                i = this.length,
                found = [],
                node;

            while (i--) {
                node = this[i];
                while (node.nodeName != tag && (node = node.parentElement));
                if (node) {
                    found[found.length] = node;
                }
            }
            return $(found);
        }
    });

    /** @constructor **/
    var CalendarWidget = Rtk.ThIntl.Option.CalendarWidget = function (options) {
        var _localeConv = Rtk.ThIntl.Util.Locale(options.localeInfo),
            self = $.extend(CalendarWidget.prototype, options);

        self.localeString = _localeConv.localeString;
        self.parseDate    = Rtk.ThIntl.Option.Daterangepicker.parseDate;
        self.thWeek       = Rtk.ThIntl.Option.Daterangepicker.thWeek;
        self.setDate      = Rtk.ThIntl.Option.Daterangepicker.setDate;

        self._initialize();

        return self;
    };

    CalendarWidget.prototype = {
        _inputNo :
            function (input) {
                return input.id.substr(input.id.length - 1);
            },
        _onInputChange :
            function (event) {
                var self  = this,
                    _this = event.currentTarget,
                    date  = self.parseDate(_this.value),
                    minDate,
                    maxDate,
                    thisDate,
                    thatDate,
                    other,
                    shouldSwapDates,
                    form;

                if (self.usesAjax) {
                    minDate = $.datepicker._defaults.minDate;
                    maxDate = $.datepicker._defaults.maxDate;

                    if (date) {
                        if (self.isWeekpicker) {
                            date = self.thWeek(date);
                        }

                        if (maxDate && date.isAfter(maxDate)) {
                            date = self.isWeekpicker ? self.thWeek(maxDate) : maxDate;
                        } else if (minDate && date.isBefore(minDate)) {
                            date = minDate;
                        }

                        _this.value = date.toString(self.dateFormat);

                        if (self.isWeekpicker) {
                            self.jqOption.val(date.toString('yyyyMMdd') + ' 00:00:00');
                        }
                    } else {
                        _this.value = '';
                    }
                } else if (date) {
                    _this.value = self.asString(date);

                    if (!self.enableShowAll) {
                        self.removeError(_this);
                    }
                } else {
                    _this.value = '';

                    if (!self.enableShowAll && (self._inputNo(_this) !== '2')) {
                        self.addError(_this);
                    }
                }

                if (!self.isSingleInput) {
                    other    = self.jqInput.not(_this);
                    thatDate = self.parseDate(other.val());

                    self.jqOption.val('RANGE');

                    if (self.enableShowAll) {
                        if (!_this.value) {
                            if (!other.val()) {
                                self.jqOption.val('ALL');
                                other.add(_this).each(function () {
                                    self.removeError(_this);
                                });
                            } else if (self._inputNo(_this) === '1') {
                                self.addError(_this);
                            }
                        } else {
                            self.removeError(_this);
                            if ((self._inputNo(_this) === '2') && !other.val()) {
                                self.addError(other);
                            }
                        }
                    } else if (self._inputNo(_this) === '1') {
                        if (!_this.value) {
                            self.addError(_this);
                        } else {
                            self.removeError(_this);
                        }
                    }

                    thisDate = self.parseDate(_this.value);

                    shouldSwapDates = (self._inputNo(_this) === '1')
                        ? (thisDate && thatDate && thisDate.isAfter(thatDate))
                        : (thisDate && thatDate && thisDate.isBefore(thatDate));

                    if (shouldSwapDates) {
                        other.val(self.asString(thisDate));
                        $(_this).val(self.asString(thatDate));
                    }

                    if (self.isDaterange) {
                        self.jqInput.unbind('change');

                        self.leftInput().datepicker('option', 'maxDate', self.rightDate());
                        self.rightInput().datepicker('option', 'minDate', self.leftDate());

                        self.jqInput.change($.proxy(self, '_onInputChange'));
                        if(self.enableWeekToggleForRange){
                            self.jqOption.change($.proxy(self, '_optionChanged'));
                        }
                    }
                } else if (self.enableShowAll) {
                    if (!_this.value) {
                        self.jqOption.val('ALL');
                    }
                } else {
                    if (date) {
                        self.removeError(_this);
                    } else {
                        self.addError(_this);
                    }
                }

                if (self.isWeekpicker || self.enableWeekToggleForRange) {
                    if (date) {
                        if (minDate && (new Date(date).add({days: -7}).isBefore(minDate))) {
                            self.unbindArrow('#prevWeek');
                        } else {
                            if(self.isWeekpicker || self.isWeekRequest){
                                self.bindArrow('#prevWeek');
                            }
                        }

                        if (maxDate && (new Date(date).add({days: 7}).isAfter(maxDate))) {
                            self.unbindArrow('#nextWeek');
                        } else {
                            if(self.isWeekpicker || self.isWeekRequest){
                                self.bindArrow('#nextWeek');
                            }
                        }
                    } else {
                        self.unbindArrow('#prevWeek, #nextWeek');
                    }
                }

                if ($(_this).is(':disabled')) {
                    self.disableIcon();
                    self.unbindArrow('#prevWeek, #nextWeek');
                } else {
                    self.enableIcon();
                }

                form = $(_this).parents('form');
                if (form.find('.validationError').length > 0) {
                    form.find('.go-button')
                        .removeClass('go-activate')
                        .addClass('ui-state-disabled')
                        .attr('disabled', 'disabled');
                } else {
                    form.find('.go-button')
                        .addClass('go-activate')
                        .removeClass('ui-state-disabled')
                        .removeAttr('disabled');
                }

                if (!self.isSingleInput) {
                    self.setDate($('.range-start'), self.leftInput().val());
                    self.setDate($('.range-end'), self.rightInput().val());
                }
            },
        _onInputFocus :
            function () {
                var self     = this,
                    presetNo = self.calendars.length - 1,
                    option   = self.jqOption.val(),
                    offset   = (option.substr(0, 5) == 'THIS_' || self.parseDate(option)) ? 1 : 0;

                if (!$('.ui-daterangepicker').filter(':visible,:animated').length) {
                    self.jqImage.click();
                }
                if (!$('.ui-daterangepicker').find('.ranges:visible, :animated').length) {
                    presetNo = presetNo ? presetNo - offset : presetNo;
                    $('.ui-daterangepicker-calendar.preset_' + presetNo).click();
                }
            },
        _onInputKeydown :
            function () {
                var self     = this,
                    presetNo = self.calendars.length - 1;

                if (!$('.ui-daterangepicker').find('.range-end:visible, :animated').length) {
                    $('.ui-daterangepicker-calendar.preset_' + presetNo).click();
                }
            },
        leftInput :
            function () {
                var self = this;

                return $('#' + self.name + '_1');
            },
        leftDate :
            function () {
                var self = this;

                return self.parseDate(self.leftInput().val());
            },
        rightInput :
            function () {
                var self = this;

                return $('#' + self.name + '_2');
            },
        rightDate :
            function () {
                var self = this;

                return self.parseDate(self.rightInput().val());
            },
        _initialize :
            function () {
                var self = this,
                    dpOptions,
                    drpOptions;

                if (self.usesAjax) {
                    self.setMinMaxDates();
                    $('#country-id-select').change(function () {
                        if (this.value) self.updateDatepickerSettings(this.value);
                    });
                }

                if(self.enableWeekToggleForRange){
                    self.jqOption
                        .unbind()
                        .change($.proxy(self, '_optionChanged'));
                }

                self.jqInput
                    .unbind()
                    .focus($.proxy(self, '_onInputFocus'))
                    .change($.proxy(self, '_onInputChange'));


                if (self.isDaterangepicker) {
                    drpOptions = self.dateRangePickerOptions(self.firstDayOfWeek, self.treeJSON);

                    self.jqInput
                        .keydown($.proxy(self, '_onInputKeydown'))
                        .add(self.jqOption)
                        .dateRangePicker(self.jqImage, drpOptions);
                } else {
                    dpOptions = {
                        changeMonth: true,
                        changeYear: true,
                        showOtherMonths: true,
                        selectOtherMonths: true,
                        showButtonPanel: true,
                        onClose: function () { self.jqInput.change(); }
                    };

                    if (self.isDaterange) {
                        dpOptions.onSelect = function (dateText) {
                            var datePicker = $(this),
                                sibling    = datePicker.parent().siblings('td').children(self.jqInput),
                                date       = self.parseDate(dateText),
                                option     = datePicker.is('#' + self.name + '_1') ? 'minDate' : 'maxDate';

                            sibling.datepicker('option', option, date);
                        };
                    }

                    self.jqInput.datepicker(dpOptions);
                }

                $.datepicker.enableShowAll = self.enableShowAll;

                if (self.isDaterange) {
                    $('#' + self.name + '_2').datepicker('option', 'minDate', self.parseDate(self.fromDate));
                    $('#' + self.name + '_1').datepicker('option', 'maxDate', self.parseDate(self.toDate));
                } else if (self.isWeekpicker || self.enableWeekToggleForRange) {
                    self._createArrows();
                }

                $('.go-button').click(function () {
                    if (self.isWeekpicker || self.enableWeekToggleForRange) {
                        self.unbindArrow('#prevWeek, #nextWeek');
                    }

                    self.disableIcon();
                    $(this).addClass('ui-state-disabled').attr('disabled', 'disabled').unbind('click');
                    $('#go_button_value').attr('name', $(this).attr('name')).val($(this).val());
                    $(this).closestByTagName('form').submit();
                });

                if (self.jqInput.change().is(':disabled')) {
                    self.disableIcon();
                }

                self.jqOption.val(self.option);
            },
        _createArrows :
            function () {
                var self    = this,
                    hoverIn = function () {
                        $(this).addClass('ui-state-hover');
                    },
                    hoverOut = function () {
                        $(this).removeClass('ui-state-hover');
                    },
                    prevLink,
                    nextLink;

                $.datepicker.thisWeek = self.thisWeek;

                prevLink = $('<a id="prevWeek" class="ui-corner-all" title="'
                    + self.localeString('Previous Week')
                    + '" style="border:0"><span class="ui-icon ui-icon-circle-triangle-w">'
                    + self.localeString('Previous Week')
                    + '</span></a>');

                nextLink = $('<a id="nextWeek" class="ui-corner-all" title="'
                    + self.localeString('Next Week')
                    + '" style="border:0"><span class="ui-icon ui-icon-circle-triangle-e">'
                    + self.localeString('Next Week')
                    + '</span></a>');

                var input = self.enableWeekToggleForRange ? self.leftInput() : self.jqInput;

                input.before(prevLink)
                     .after(nextLink)
                     .parent()
                     .find('a')
                     .click($.proxy(self, 'changeWeek'))
                     .hover(hoverIn, hoverOut);

                if(self.isWeekRequest){
                    $('td.pad-right-s.pad-left-s.to-range-toggler').hide();
                    self.rightInput().hide();
                } else {
                    self.unbindArrow('#prevWeek, #nextWeek');
                    $('#prevWeek, #nextWeek').hide();
                }
            },
        removeError :
            function (element) {
                $(element).css({ borderWidth:   '',  borderColor:   '',   backgroundColor:   ''   })
                    .removeClass('validationError');
            },
        addError :
            function (element) {
                $(element).css({ borderWidth: '1px', borderColor: '#C00', backgroundColor: '#FDD' })
                    .addClass('validationError');
            },
        asString :
            function (date, optionalFormat) {
                var self = this;

                if (!date) { return ''; }
                if (typeof date === 'string') { date = self.parseDate(date); }
                return date.toString(optionalFormat || self.dateFormat);
            },
        disableIcon :
            function () {
                var self = this;

                self.jqImage
                    .addClass('ui-state-disabled')
                    .attr('disabled', 'disabled')
                    .unbind('click');
            },
        enableIcon :
            function () {
                var self = this;

                self.jqImage
                    .removeClass('ui-state-disabled')
                    .removeAttr('disabled');
            },
        bindArrow :
            function (ids) {
                $(ids).unbind('click')
                    .click($.proxy(this, 'changeWeek'))
                    .find('span')
                    .removeClass('ui-state-disabled');
            },
        unbindArrow :
            function (ids) {
                $(ids).unbind('click')
                    .find('span')
                    .addClass('ui-state-disabled');
            },
        changeWeek :
            function (event) {
                var self         = this,
                    _this        = event.currentTarget,
                    daysToAdd    = (_this.id === 'prevWeek' ? -7 : 7),
                    dateInput    = self.jqInput.change().val(),
                    dateObj      = self.parseDate(dateInput).add({ days: daysToAdd });
    
                if(self.enableWeekToggleForRange){
                    var dateInputTwo = self.rightInput().change().val(),
                        dateObjTwo   = self.parseDate(dateInputTwo).add({ days: daysToAdd });
                    self.leftInput()
                        .val(self.asString(dateObj))
                        .attr('disabled', 'disabled')
                        .change();
                    self.rightInput()
                        .val(self.asString(dateObjTwo))
                        .attr('disabled', 'disabled')
                        .change();
                    self.jqOption.val(dateObj.toString('yyyyMMdd') + ' 00:00:00').change();
                } else {
                    self.jqInput
                        .val(self.asString(dateObj))
                        .attr('disabled', 'disabled')
                        .change();
                }

                self.disableIcon();
                self.unbindArrow('#prevWeek, #nextWeek');
                $(_this).closestByTagName('form').find('.go-button').click();
            },
        dateRangePickerOptions :
            function (day1, tree) {
                var self      = this,
                    parseTree = function (element) {
                        var selected = element[0],
                            text     = element[1],
                            value    = element[2],
                            children = $.grep(element, function (e, i) { return i > 2; });

                        if (children.length > 0) {
                            return new $.DateRangeGroup(selected, text, $.map(children, parseTree));
                        } else {
                            return new $.DateRange(selected, text, value[0], value[1], value[2]);
                        }
                    },
                    minYear = self.leastRecentWeek
                        ? self.asString(self.leastRecentWeek, 'yyyy')
                        : 'c-10',
                    maxYear = self.mostRecentWeek
                        ? self.asString(self.mostRecentWeek, 'yyyy')
                        : 'c+10',
                    options = {
                        dateFormat:      self.dateFormat,
                        doneText:        self.localeString('Done'),
                        firstDayOfWeek:  day1,
                        rangeStartTitle: self.localeString('Start Date'),
                        rangeEndTitle:   self.localeString('End Date'),
                        ranges:          [],
                        groups:          $.map(tree, parseTree),
                        datepickerOptions: {
                            dateFormat:        self.dpDateFormat,
                            changeMonth:       true,
                            changeYear:        true,
                            yearRange:         minYear + ':' + maxYear,
                            showOtherMonths:   true,
                            selectOtherMonths: true
                        }
                    };

                if (self.calendars.length) {
                    options.calendars = self.calendars;
                }

                return options;
            },
        setMinMaxDates :
            function () {
                var self    = this,
                    minWeek = self.leastRecentWeek,
                    maxWeek = self.mostRecentWeek;

                if (!minWeek && !maxWeek) {
                    self.jqInput.attr('disabled', 'disabled');
                    if (self.isWeekpicker || self.enableWeekToggleForRange) {
                        self.unbindArrow('#prevWeek, #nextWeek');
                    }
                    return;
                } else {
                    self.jqInput.removeAttr('disabled');
                    self.enableIcon();
                }
                $.datepicker.setDefaults({
                    minDate: minWeek ? self.parseDate(minWeek) : null,
                    maxDate: maxWeek
                        ? self.showWeekpicker
                            ? self.parseDate(maxWeek).add({ days: 6 })
                            : self.parseDate(maxWeek)
                        : null
                });
            },
        updateDatepickerSettings :
            function (country_id) {
                var self     = this,
                    params   = self.paramString + '&country_id=' + country_id,
                    title_no = $('[name="title_no"]').first().val();

                if (title_no) { params += '&title_no=' + title_no; }
                $('.calendar_widget[name=' + self.name + ']').each(function () {
                    params += '&' + this.name + '=' + encodeURIComponent(this.value);
                });

                $.getJSON('/reports/option_collection_list_data.html', params, function (obj) {
                    $.datepicker.firstDayOfWeek = obj.firstDayOfWeek;
                    $.datepicker.thisWeek = obj.thisWeek;
                    self.leastRecentWeek = obj.minWeek;
                    self.mostRecentWeek = obj.maxWeek;
                    self.setMinMaxDates();

                    if (self.isDaterangepicker) {
                        var treeObj = $.parseJSON(obj.tree);

                        $('.ui-daterangepickercontain').remove();
                        self.jqInput.add(self.jqOption).dateRangePicker(self.jqImage,
                            self.dateRangePickerOptions(obj.firstDayOfWeek, treeObj));
                    }

                    $('.hasDatepicker').each(function () {
                        self.setDate($(this), $(this).datepicker('getDate'));
                    });
                });
            },
        _optionChanged :
            function (event) {
                var self             = this,
                    _this            = event.currentTarget,
                    option           = self.jqOption.val(),
                    is_week_option   = (option.substr(0, 5) == 'THIS_' || self.parseDate(option)) ? 1 : 0;

                if(is_week_option == 0){
                    self.rightInput().show();
                    $('td.pad-right-s.pad-left-s.to-range-toggler').show();
                    self.unbindArrow('#prevWeek, #nextWeek');
                    $('#prevWeek, #nextWeek').hide();
                } else {
                    self.rightInput().hide();
                    $('td.pad-right-s.pad-left-s.to-range-toggler').hide();
                    self.bindArrow('#prevWeek, #nextWeek');
                    $('#prevWeek, #nextWeek').show();
                }
                return false;
            }
    };
}(jQuery));

