/*
 * Copyright (c) 2001-2014,FineReport Inc, All Rights Reserved.
 */

/**
 * 日期(时间)控件
 *
 *     @example
 *     var $div = $('<div style="position:absolute;left:20px;top:20px;width:400px;height:400px">').appendTo('body');
 *     var editor = new FR.DateTimeEditor({
 *           renderEl : $div,
 *           format : 'yyyy-MM-dd',     //日期格式
 *           startDate : "2010-08-08",  //起始日期
 *           endDate : "2010-10-10",    //结束日期
 *           editable : true,     //是否允许手动输入日期
 *           value : "2010-10-01"
 *      });
 *
 * @class FR.DateTimeEditor
 * @extends FR.BaseDateTimeEditor
 *
 * @cfg {JSON} options 属性配置
 * @cfg {String} [options.format='yyyy-MM-dd'] 日期控件值的格式
 * @cfg {Boolean} [options.directEdit=true] 是否可以直接编辑日期
 */
FR.DateTimeEditor = FR.extend(FR.BaseDateTimeEditor, /**@class FR.DateTimeEditor */{
    _defaultConfig: function () {
        return $.extend(FR.DateTimeEditor.superclass._defaultConfig.apply(), {
            format: 'yyyy-MM-dd',
            directEdit: true
        });
    },
    _init: function () {
        FR.DateTimeEditor.superclass._init.apply(this, arguments);
        this.switchArrow();
        if (this.options.widgetCss && this.options.widgetCss.length !== 0) {
            $.each(this.options.widgetCss, function (i, item) {
                FR.$import(item, 'css', true);
            });
        }
        var o = this.options;
        this.viewMode = this._initViewMode();
        this.std = this._createStartDate(o.startDate, o.format, this.viewMode);
        this.edd = this._createEndDate(o.endDate, o.format, this.viewMode);
        var self = this;
        if(!this.$view){
            this.$view = $('<div/>').appendTo(FR.$view_container).hide();
        }
        this.editComp.keydown(function (e) {
            self.editComp[0].realValue = null;
        });
        $(this.editComp).keyup(function () {
            if ($(this).val() == self.oriText) {
                return;
            }
            self.isValidateInput();
            self.oriText = $(this).val();
            self.fireEvent(FR.Events.AFTEREDIT);
        })
    },
    getArrowIconHeight : function(){
        return 17;
    },
    switchArrow:function(){
        this.arrow.switchClass('fr-trigger-center', 'fr-date-trigger-center');
    },

    _applyInvalidCss: function(title){
        this.errorMsg = title;
        this.invalidateCss();
    },

    onTriggerClick: function (e) {
        if (!this.isEnabled()) {
            return;
        }
        if (document.activeElement != this.editComp[0]) {
            this.editComp.focus();
        }
        // 点击的时候再创建calendar窗口,便于及时的修改某些属性,比如startDate
        if(this.isExpanded()){
            if (FR.Browser.isIE8() && this.$view.css('visibility') == 'hidden') {
                this.$view.css("visibility", "visible");
            } else {
                this.$view.show();
            }
        }else{
            this.$view.empty();
            this._createCalendar();
        }
    },
    _showView: function () {
        if (FR.Browser.isIE8() && this.$view.css('visibility') == 'hidden') {
            this.$view.css("visibility", "visible");
        } else {
            this.$view.show();
        }
    },
    _createStartDate: function(st, fmt, viewMode){
        if(FR.isEmpty(st)){
            return null;
        }
        var std = FR.str2Date(st, fmt);
        switch(viewMode){
            case 0:
                return new Date(std.getFullYear(), std.getMonth(), 1, 0, 0, 0);

            case 1:
                return new Date(std.getFullYear(), std.getMonth(), std.getDate(), 0, 0, 0);
            case 2:
                var today = new Date();
                today.setHours(0);
                today.setMinutes(0);
                today.setSeconds(0);
                return today;
            case 3:
                return new Date(std.getFullYear(), std.getMonth(), std.getDate(), 0, 0, 0);
            default:
                return std;
        }
    },

    _createEndDate: function(ed, fmt, viewMode){
        if(FR.isEmpty(ed)){
            return null;
        }
        var edd = FR.str2Date(ed, fmt);
        switch(viewMode){
            case 0:
                return new Date(edd.getFullYear(), edd.getMonth(), edd.getMonthDays(), 23, 59, 59);
            case 1:
                return new Date(edd.getFullYear(), edd.getMonth(), edd.getDate(), 23, 59, 59);
            case 2:
                var today = new Date();
                today.setHours(23);
                today.setMinutes(59);
                today.setSeconds(59);
                return today;
            case 3:
                return new Date(edd.getFullYear(), edd.getMonth(), edd.getDate(), 23, 59, 59);
            default:
                return edd;
        }
    },

    modifyPosition: function(){
        this.tH = this.$view.height();
        this.tW = this.$view.width();
        FR.DateTimeEditor.superclass.modifyPosition.apply(this, arguments);
    },

    _initViewMode: function(){
        var o = this.options;
        var viewMode = 1;//年月日
        if (o.format.match(/[YyDd]/) && o.format.match(/[Hh]/)) {
            viewMode = 3;//年月日时分秒
        } else if (o.format.match(/[M]/) && !o.format.match(/[Dd]/) && !o.format.match(/[Hh]/)) {
            viewMode = 0;//年月
        } else if (!o.format.match(/[YyMDd]/)) {
            viewMode = 2;//时分秒
        }
        return viewMode;
    },

    _createCalendar: function() {
        var o = this.options;
        var self = this;
        if (this.options.need2BuildConfig === true && this.options.data) {
            this.options.data.resetStatus(this.createDependencePara4Data());
            var data = this.options.data.getData();
            if (data[0].data) {
                if (data[0].data.startDate) {
                    var sd = new Date(data[0].data.startDate);
                    if (!FR.isInvalidDate(sd)) {
                        o.startDate = FR.date2Str(sd, 'yyyy-MM-dd');
                        this.std = this._createStartDate(o.startDate, o.format, this.viewMode);
                    }
                }
                if (data[0].data.endDate) {
                    var ed = new Date(data[0].data.endDate);
                    if (!FR.isInvalidDate(ed)) {
                        o.endDate = FR.date2Str(ed, 'yyyy-MM-dd');
                        this.edd = this._createEndDate(o.endDate, o.format, this.viewMode);
                    }
                }
            }
            this.options.rebuildConfig = false;
        }
        this.datepicker = new FR.DatePicker({
            renderEl: this.$view,
            viewMode: this.viewMode,
            date: FR.str2Date(this.editComp.val(), o.format),
            dateFormat: o.format,
            startDate: this.std,
            endDate: this.edd,
            onDateUpdate:function(){
                self.editComp.val(FR.date2Str(this.getValue(), o.format));
                self.isValidateInput();
                self.fireEvent(FR.Events.AFTEREDIT);
            }
        });
        if (FR.Browser.isIE8() && this.$view.css('visibility') == 'hidden') {
            this.$view.css("visibility", "visible");
        } else {
            this.$view.show();
        }
        $(document).bind('mousedown', this, this.collapseIf);
        this.modifyPosition();
    },

    getValue: function () {
        var format = this.options.format;
        if (!this.options.returnDate) {
            var value = this.editComp.val();
            return FR.str2Date(value, format) == null ? "" : value;
        }
        // richer:这里是用来直接编辑日期的
        var currentValue = new Date();
        if (this.editComp[0].realValue) {
            currentValue.setTime(this.editComp[0].realValue.getTime());
        } else {
            currentValue = this.editComp.val();
        }
        //james:看看填入的值是不是正确的
        if (!currentValue) {
            return '';
        }
        var returnDate = (currentValue instanceof Date) ? currentValue : FR.str2Date(currentValue, format);
        // james:日历控件统一返回Date型的值,如果不是Date,就返回空,这里没有返回undefined
        return (returnDate == null) ? '' : returnDate;
    },

    isValidateInput: function (cValue) {
        var format = this.options.format;
        var startDate = this.std;
        var endDate = this.edd;

        // 这个自动修复输入数据要考虑个问题 正在输入的时候不应该自动修改
        // 应该做个延时处理 一段时间后如果值没变 就执行
        var self = this;
        var matchFormat = true;
        var custom = this.options.customFormat;
        var dv = cValue ? cValue : this.editComp.val();
        var dt = FR.matchDateFormat(dv, format);
        if (!custom && !dt) {
            matchFormat = false;
            var reverse = function() {
                var currentDv = self.editComp.val();
                if (dv == currentDv) {
                    var arr = self.getDefaultSupportFormat();
                    for (var i=0; i<arr.length; i++) {
                        var result = FR.matchDateFormat(dv, arr[i]);
                        if (result) {
                            dt = result;
                            matchFormat = true;
                            self.editComp.val(FR.date2Str(dt, format));
                            this.isValidateInput();
                            break;
                        }
                    }
                }
            };
            reverse.defer(1000, this);
        }
        if (!custom && !matchFormat) {
            // 格式不正确的话dv是"",加上浏览器不支持的日期类型情况都在这里处理
            if (!FR.matchDateFormat(dv, format)) {
                this._applyInvalidCss(FR.i18nText("FR-Designer_Please_input_with_right_format") + ":" + format);
            }
        } else if (startDate && !FR.isInvalidDate(new Date(startDate)) && dt < new Date(startDate)) {
            this._applyInvalidCss(FR.i18nText("Err-The_number_is_less_than_the_minimum_value") + FR.date2Str(startDate, 'yyyy-MM-dd'));
        } else if (endDate && !FR.isInvalidDate(new Date(endDate)) && dt > new Date(endDate)) {
            this._applyInvalidCss(FR.i18nText("Err-The_number_is_larger_than_the_maximum_value") + FR.date2Str(endDate, 'yyyy-MM-dd'));
        } else if (dt > new Date(2999,11,31) || dt < new Date(1900,0,1)) {
            this._applyInvalidCss("out of range");
        } else {
            this.validateCss();
        }
    },

    reset: function() {
        FR.DateTimeEditor.superclass.reset.apply(this, arguments);
        this.editComp[0].realValue = null;
        this.options.currentDateTime = null;
        this.options.need2BuildConfig = true;
        if (this.options.data) {
            delete this.options.data.records;
        }
    }
});
$.shortcut("datetime", FR.DateTimeEditor);