/**
 * 直接展示的日期控件
 *
 *      @example
 *      var $anchor = $('<div>').css({
 *          position : 'absolute',
 *          top : 5,
 *          left : 5,
 *          width : 300,
 *          height : 300
 *      }).appendTo('body');
 *      var picker = new FR.DatePicker({
 *          renderEl : $anchor,
 *          format : 'yyyy-MM-dd',
 *          viewMode : 0
 *      });
 *
 * @class FR.DatePicker
 * @extends FR.Widget
 * @cfg {JSON} options 配置属性
 * @cfg {String} [options.format] 日期格式
 * @cfg {0/1/2/3} [options.viewMode=1] 显示模式
 */
FR.DatePicker = FR.extend(FR.Widget, {

    CONSTS: {

        VIEWMODE: {
            YM: 0,  //年月
            YMD: 1, //年月日
            HMS: 2, //时分秒
            YMDHMS: 3 //年月日时分秒
        },

        MINYEAR: 1900,
        MAXYEAR: 2999,

        NAV: {
            'prevm': 2, //上个月
            'nextm': 3, //下个月
            'title': 4, //年月显示标题
            'clear': 5, //清除
            'today': 6, //今天
            'dok': 7,   //日期确认
            'prevy': 8, //前十年
            'nexty': 9, //后十年
            'cancel': 10, //取消
            'mok': 11,   //确认
            'plus': 12, //增加时间
            'minus': 13, //减少时间
            'firstday': 14, //周一和周日
            'current': 15, //当前时间
            'day': 100, //日
            'month': 200, //月
            'year': 300 //年
        },

        FIRSTDAY: 0 //每周的第一天,0表示周日,1表示周一,依次类推(全局生效)。
    },

    _TT: {
        CALENDAR: FR.i18nText("FR-Basic_Calendar"),
        WK: FR.i18nText("FR-Basic_Week"),
        CLEAR: FR.i18nText("FR-Basic_Clear"),
        TODAY: FR.i18nText("FR-Basic_Today"),
        OK: FR.i18nText("FR-Basic_OK"),
        CANCEL: FR.i18nText("FR-Basic_Cancel"),
        CURRENT: FR.i18nText("FR-Basic_Current")
    },

    /**
     * @see FR.Widget
     * @returns {*}
     * @private
     */
    _defaultConfig: function () {
        return $.extend(FR.DatePicker.superclass._defaultConfig.apply(this, arguments), {
            widgetName: "datepicker",
            inputField: null,
            format: null,
            viewMode: 1,
            endDate: null, //结束日期
            startDate: null, //起始日期
            date: null, //初始日期
            dateFormat: null, // 日期格式
            //日期更新事件
            onDateUpdate: null,
            //清除按钮事件
            onClear: function () {
                this._hideView();
            },
            //确认按钮事件
            onOK: function () {
                this._hideView();
            },
            //关闭按钮事件
            onClose: function () {
                this._hideView();
            },
            //选取今天按钮事件
            onToday: function () {
                this._hideView();
            }
        });
    },
    _hideView:function(){
        if(FR.Browser.isIE8()){
            this.element.css("visibility","hidden");
        }else{
            this.element.hide();
        }
    },
    /**
     * @see FR.Widget
     * @private
     */
    _init: function () {
        FR.DatePicker.superclass._init.apply(this, arguments);
        this.element.addClass('fr-datepicker');
        this.cache = {
            showYear: null,
            showMonth: null
        };
        this._initTables();
        this._bindEvts();
    },

    _initTables: function () {
        var opts = this.options;
        this.$datetable = this._createDatePicker();
        this._loadDateData(this.$datetable, new Date(this.options.date));
        this.$monthtable = this._createMonthPicker();
        this.$timetable = this._createTimePicker();
        switch (opts.viewMode) {
            case this.CONSTS.VIEWMODE.YM : // 年月
                this._loadMonthData(this.$monthtable, new Date(this.options.date));
                this.$monthtable.appendTo(this.element).show();
                break;
            case this.CONSTS.VIEWMODE.HMS :   // 时分秒
                this._loadTimeData(this.$timetable, this.options.date);
                this._addTimeOptPane(this.$timetable);
                this.$timetable.appendTo(this.element).show();
                break;
            case this.CONSTS.VIEWMODE.YMD : //年月日
                this.$datetable.appendTo(this.element).show();
                this.$monthtable.hide().appendTo(this.element);
                break;
            default : // 年月日、年月日时分秒
                this.$datetable.appendTo(this.element).show();
                this.$monthtable.hide().appendTo(this.element);
                var row = $('<tr/>').prependTo(this.$datetable.find('tfoot'));
                this._loadTimeData(this.$timetable, this.options.date);
                this.$timetable.show().appendTo($('<td colspan="8" class="time"/>').appendTo(row));
                break;
        }
    },

    _createTimePicker: function () {
        var table = $('<table cellspacing = "0" cellpadding = "0" class="tt"/>');
        var tbody = $('<tbody>').appendTo(table);
        var self = this, o = this.options, NAV = this.CONSTS.NAV;
        table.$h = $('<input/>').data('time', 'h').keyup(function () {
            var text = this.value;
            var value = parseInt(text, 10);
            if (value < 24 && value >= 0) {
                o.date.setHours(value);
                FR.applyFunc(self, o.onDateUpdate, arguments);
            }
        }).focus(function () {
                table.focus = $(this);
            });
        table.$m = $('<input/>').data('time', 'm').keyup(function () {
            var text = this.value;
            var value = parseInt(text, 10);
            if (value < 60 && value >= 0) {
                o.date.setMinutes(value);
                FR.applyFunc(self, o.onDateUpdate, arguments);
            }
        }).focus(function () {
                table.focus = $(this);
            });
        table.$s = $('<input/>').data('time', 's').keyup(function () {
            var text = this.value;
            var value = parseInt(text, 10);
            if (value < 60 && value >= 0) {
                o.date.setSeconds(value);
                FR.applyFunc(self, o.onDateUpdate, arguments);
            }
        }).focus(function () {
                table.focus = $(this);
            });
        table.focus = table.$s;
        var $add = $('<td/>').html('&and;').data('nav', NAV['plus']);
        var $min = $('<td/>').html('&or;').data('nav', NAV['minus']);
        var row1 = $('<tr/>').append($('<td rowspan="2"/>').text(FR.i18nText("FR-Basic_Time")))
            .append($('<td rowspan="2"/>').append(table.$h))
            .append($('<td class="common" rowspan="2"/>').text(':'))
            .append($('<td rowspan="2"/>').append(table.$m))
            .append($('<td class="common" rowspan="2"/>').text(':'))
            .append($('<td rowspan="2"/>').append(table.$s))
            .append($add)
            .appendTo(tbody);
        var row2 = $('<tr/>').append($min)
            .appendTo(tbody);
        //绑定鼠标滚动事件
        tbody.find('input').mousewheel(function(e){
            if(this.D < 0){
                //向上滚动时间+
                self._doTimeInc(table, $(this));
            }else{
                //向下滚动时间-
                self._doTimeDec(table, $(this));
            }
            return false;
        });
        return table;
    },

    /**
     * 添加时分秒部分独立显示时的按钮操作面板
     * @param timetable 时间面板
     * @private
     */
    _addTimeOptPane: function(timetable){
        var nav = this.CONSTS.NAV;
        var $foot = $('<tfoot/>');
        var $tr = $('<tr class="optbtns"/>').appendTo($foot);
        //清空按钮
        this._createCell($tr, this._TT["CLEAR"], 2, nav['clear'], 'clear');
        //当前按钮
        this._createCell($tr, this._TT["CURRENT"], 3, nav['current'], 'current');
        //确认按钮
        this._createCell($tr, this._TT["OK"], 2, nav['dok'], 'ok');
        $foot.appendTo(timetable);
    },
    /**
     * 生成日期选择部分
     * @private
     */
    _createDatePicker: function () {
        var table = $('<table cellspacing = "0" cellpadding = "0" class="dt"/>');
        var nav = this.CONSTS.NAV;
        var thead = $('<thead/>').appendTo(table);
        //head
        //head - tools
        row = $('<tr class = "mainhead"/>');
        //head - tools - 前一月
        table.$prevm = this._createCell(row, "&lsaquo;", 1, nav['prevm'], "prevm");
        //head - tools - title(标记年份和月份)
        table.$title = $('<td class="title" colspan="6"/>').data('nav',nav['title']).appendTo(row);
        //head - tools - 后一月
        table.$nextm = this._createCell(row, "&rsaquo;", 1, nav['nextm'], "nextm");
        row.appendTo(thead);
        //head - week names
        row = $('<tr/>');
        $('<td class="name wn">' + this._TT['WK'] + '</td>').appendTo(row);
        for (var i = 7; i > 0; --i) {
            $('<td/>').appendTo(row);
        }
        for (var i = 0; i < 7; ++i) {
            var $fdcell = row.children().eq(i + 1);
            var index = (i+ this.CONSTS.FIRSTDAY)%7;
            $fdcell.addClass('day name').text(Date._SDN[index]);
            if ([0, 6].indexOf(index) != -1) { //周六,周日
                $fdcell.addClass("weekend");
            }
            if ([0, 1].indexOf(index) != -1) { //周一,周日
                $fdcell.addClass("fd").data('nav', this.CONSTS.NAV['firstday']).data('fd', index);
            }
        }
        row.appendTo(thead);
        //body
        var tbody = $('<tbody onselectstart="return false"/>').appendTo(table);
        for (i = 6; i > 0; i--) {
            var row = $('<tr/>').appendTo(tbody);
            for (var t = 0; t <= 7; t++) {
                $('<td/>').appendTo(row);
            }
        }
        //foot
        var tfoot = $('<tfoot/>').appendTo(table);
        var row = $('<tr class = "optbtns"/>');
        //foot - 清除按钮
        this._createCell(row, this._TT["CLEAR"], 2, nav['clear'], 'clear');
        //foot - 今天按钮
        this._createCell(row, this._TT["TODAY"], 4, nav['today'], 'today');
        //foot - 确认按钮
        this._createCell(row, this._TT["OK"], 2, nav['dok'], 'ok');
        row.appendTo(tfoot);
        return table;
    },

    /**
     * 生成年月选择部分
     * @private
     */
    _createMonthPicker: function () {
        var table = $('<table cellspacing = "0" cellpadding = "0" class="mt"/>');
        var nav = this.CONSTS.NAV;
        //tbody
        var tbody = $('<tbody class="datemenubody"/>').appendTo(table);
        //tbody - tools
        var row = $('<tr class="datemenutr"/>').appendTo(tbody);
        for (var n = 0; n < 2; n++) {
            $('<td class="month"/>').appendTo(row);
        }
        //tbody - 翻年按钮
        this._createCell(row, "&laquo;", 1, nav['prevy'], ' prevy');
        this._createCell(row, "&raquo;", 1, nav['nexty'], ' nexty');
        //tbody - years
        for (var m = 0; m < 5; m++) {
            row = $('<tr/>').appendTo(tbody);
            $('<td class="month"/><td class="month"/>' +
                '<td class="year"/><td class="year"/>').appendTo(row);
        }
        //foot - buttons
        var tfoot = $('<tfoot/>').appendTo(table);
        row = $('<tr class="optbtns"/>').appendTo(tfoot);
        //tbody - 确定与取消
        this._createCell(row, this._TT["OK"], 2, nav['mok'], 'ok');
        this._createCell(row, this._TT["CANCEL"], 2, nav['cancel'], 'cancel');
        return table;
    },

    /**
     * 翻到上个月
     * @private
     */
    _toPrevMonth: function () {
        var sd = this.options.startDate, date = this.options.date;
        var month = this.cache.showMonth,
            year = this.cache.showYear;
        if (!sd) {
            if (month > 0) {
                this._setMonth(month - 1);
            } else {
                date.setFullYear(year - 1);
                this._setMonth(11);
            }
            return;
        }
        if (year > sd.getFullYear()) {
            if (month > 0) {
                this._setMonth(month - 1);
            } else {
                date.setFullYear(year - 1);
                this._setMonth(11);
            }
        } else if (year == sd.getFullYear()) {
            if (month > sd.getMonth() && month > 0) {
                this._setMonth(month - 1);
                if (date < sd) {
                    date = new Date(sd);
                }
            }
        }
    },

    /**
     * 翻到下个月
     * @private
     */
    _toNextMonth: function () {
        var edd = this.options.endDate, date = this.options.date;
        var month = this.cache.showMonth,
            year = this.cache.showYear;
        if (!edd) {
            if (month < 11) {
                this._setMonth(month + 1);
            } else {
                date.setFullYear(year + 1);
                this._setMonth(0);
            }
            return;
        }
        if (year < edd.getFullYear()) {
            if (month < 11) {
                this._setMonth(month + 1);
            } else {
                date.setFullYear(year + 1);
                this._setMonth(0);
            }
        } else if (year == edd.getFullYear()) {
            if (month < edd.getMonth()) {
                this._setMonth(month + 1);
                if (date > edd) {
                    date = new Date(edd);
                }
            }
        }
    },

    /**
     * 翻到前十年
     * @private
     */
    _toPrevDecade: function () {
        var sd = this.options.startDate, date = this.options.date;
        var year = date.getFullYear() - 10, month = date.getMonth();
        var minMonth, minYear;
        if (sd && year == (minYear = sd.getFullYear())) {
            minMonth = sd.getMonth();
        }
        if (!minYear || minYear < this.CONSTS.MINYEAR) {
            minYear = this.CONSTS.MINYEAR;
        }
        if (year < minYear) {
            date.setFullYear(minYear);
            if (month < minMonth) {
                date.setMonth(minMonth);
            }
        } else {
            date.setFullYear(year);
        }
    },

    /**
     * 翻到后十年
     * @private
     */
    _toNextDecade: function () {
        var edd = this.options.endDate, date = this.options.date;
        var year = date.getFullYear() + 10, month = date.getMonth();
        var maxMonth, maxYear;
        if (edd && year == (maxYear = edd.getFullYear())) {
            maxMonth = edd.getMonth();
        }
        if (!maxYear || maxYear > this.CONSTS.MAXYEAR) {
            maxYear = this.CONSTS.MAXYEAR;
        }
        if (year > maxYear) {
            date.setFullYear(maxYear);
            if (month < maxMonth) {
                date.setMonth(maxMonth);
            }
        } else {
            date.setFullYear(year);
        }
    },

    _setMonth: function (m) {
        var date = this.options.date;
        var day = date.getDate(),
            edd = this.options.endDate,
            std = this.options.startDate;
        var max = date.getMonthDays(m);
        if (day > max) {
            date.setDate(max);
        }
        date.setMonth(m);
        if (edd && date > edd) {
            date.setDate(edd.getDate());
        }
        if (std && date < std) {
            date.setDate(std.getDate());
        }
    },
    /**
     * 加载日期数据
     * @param table {$} 容器
     * @param date {Date}当前日期
     * @private
     */
    _loadDateData: function (table, date) {
        if (!date) {
            return;
        }
        var year = date.getFullYear(),
            month = date.getMonth(),
            day = date.getDate();
        var today = new Date(),
            TY = today.getFullYear(),
            TM = today.getMonth(),
            TD = today.getDate();
        this.cache.showYear = year;
        this.cache.showMonth = month;
        var std = this.options.startDate,
            edd = this.options.endDate;
        //设置title
        table.$title.text(Date._MN[month] + ", " + year);
        //根据起始和结束日期设置翻月按钮
        var nextDay = new Date(date);
        nextDay.setDate(nextDay.getMonthDays() + 1);
        if ((edd && nextDay > edd) || nextDay.getFullYear() > this.CONSTS.MAXYEAR) {
            table.$nextm.addClass('disabled').removeClass('hover').data('disabled', true);
        } else {
            table.$nextm.removeClass('disabled').data('disabled', false);
        }
        var prevDay = new Date(date);
        prevDay.setDate(0);
        if ((std && prevDay < std) || prevDay.getFullYear() < this.CONSTS.MINYEAR) {
            table.$prevm.addClass('disabled').removeClass('hover').data('disabled', true);
        } else {
            table.$prevm.removeClass('disabled').data('disabled', false);
        }
        //日期设置
        date.setDate(1);
        var day1 = (date.getDay() - this.CONSTS.FIRSTDAY) % 7;
        date.setDate(0 - day1);
        date.setDate(date.getDate() + 1);
        var $frow = table.find('tbody').children().eq(0);
        //根据起始和结束日期设置td日期
        for (var i = 0; i < 6; i++) {
            if (!$frow.length) {
                break;
            }
            var $cell = $frow.children().eq(0);
            $cell.addClass('week wn').text(date.getWeekNumber());
            var iday;
            for (var j = 0; j < 7; ++j, date.setDate(iday + 1)) {
                $cell = $cell.next();
                $cell.removeClass().data('nav', this.CONSTS.NAV['day']);
                if (!$cell.length) {
                    break;
                }
                iday = date.getDate();
                $cell.text(iday);
                var current_month = (date.getMonth() == month);
                if (!current_month) {
                    $cell.addClass('oday').data('disabled',true);
                    continue;
                }
                var disabled = false;
                if ((std != null && std > date) || (edd != null && edd < date)) {
                    //日期范围外
                    $cell.addClass('day disabled');
                    disabled = true;
                } else {
                    //日期范围内
                    $cell.addClass('day');
                }
                $cell.data('disabled', disabled);
                if (!disabled) {
                    if (current_month && iday == day) {
                        this.cache.selectedDate && this.cache.selectedDate.removeClass('selected');
                        $cell.addClass('selected');
                        this.cache.selectedDate = $cell;
                        this.cache.showDay = iday;
                    }
                    if (date.getFullYear() == TY &&
                        date.getMonth() == TM &&
                        iday == TD) {
                        $cell.addClass('today');
                    }
                    var wday = date.getDay();
                    if ([0, 6].indexOf(wday) != -1) {
                        $cell.addClass("weekend");
                    }
                }
            }
            $frow = $frow.next();
        }
    },

    /**
     * 加载年月数据
     * @param table {$} 表格对象
     * @param date {Date} 当前日期
     * @private
     */
    _loadMonthData: function (table, date) {
        if (!date) {
            return;
        }
        var year = date.getFullYear(), month = date.getMonth();
        //处理需要显示的10个年份
        var midyear = $(table).data('midYear');
        if (!midyear) {
            midyear = year;
        } else {
            if (year > midyear + 5) {
                midyear += 10;
            } else if (year < midyear - 4) {
                midyear -= 10;
            }
        }
        $(table).data('midYear', midyear);
        var years = [midyear - 4, midyear - 3, midyear - 2, midyear - 1, midyear,
            midyear + 1, midyear + 2, midyear + 3, midyear + 4, midyear + 5];
        var ycells = $("td.year", table);
        var mcells = $("td.month", table);
        var o = this.options;
        var ed = o.endDate;
        var sd = o.startDate;
        var maxYear, maxMonth, minYear, minMonth;
        //结束日期
        if (ed) {
            if (ed && year == (maxYear = ed.getFullYear())) {
                maxMonth = ed.getMonth();
            }
        }
        if (!maxYear || maxYear > this.CONSTS.MAXYEAR) {
            maxYear = this.CONSTS.MAXYEAR;
        }
        //起始日期
        if (sd) {
            if (sd && year == (minYear = sd.getFullYear())) {
                minMonth = sd.getMonth();
            }
        }
        if (!minYear || minYear < this.CONSTS.MINYEAR) {
            minYear = this.CONSTS.MINYEAR;
        }
        //12个月份数据加载
        for (var i = 0; i < 12; i++) {
            var $mcell = mcells.eq(i).text(Date._MN[i])
                .data('nav', this.CONSTS.NAV['month']).data('month', i);
            if (i == month) {
                this.cache.selectedMonth && this.cache.selectedMonth.removeClass('selected');
                $mcell.addClass("selected");
                this.cache.selectedMonth = $mcell;
            }
            if ((!FR.isEmpty(minMonth) && i < minMonth) || (!FR.isEmpty(maxMonth) && i > maxMonth)) {
                $mcell.addClass("disabled").data('disabled', true);
            } else {
                $mcell.removeClass("disabled").data('disabled', false);
            }
            //一页可显示的10年数据加载
            if (i < 10) {
                var $ycell = ycells.eq(i).text(years[i]).data('nav', this.CONSTS.NAV['year']);
                if (years[i] == year) {
                    this.cache.selectedYear && this.cache.selectedYear.removeClass('selected');
                    $ycell.addClass("selected");
                    this.cache.selectedYear = $ycell;
                }
                if ((!FR.isEmpty(minYear) && years[i] < minYear) || (!FR.isEmpty(maxYear) && years[i] > maxYear)) {
                    $ycell.addClass("disabled").data('disabled', true)
                } else {
                    $ycell.removeClass("disabled").data('disabled', false);
                }
            }
        }
        //翻页按钮 - 向前
        var $prev = $("td.prevy", table).removeClass('disabled').data('disabled', false);
        if (years[0] <= minYear) {
            $prev.addClass("disabled").data('disabled', true).removeClass('hover');
        }
        //翻页按钮 - 向后
        var $next = $("td.nexty", table).removeClass('disabled').data('disabled', false);
        if (years[9] >= maxYear) {
            $next.addClass("disabled").data('disabled', true).removeClass('hover');
        }
    },

    _loadTimeData: function (table, date) {
        if (!date) {
            return;
        }
        var hour = date.getHours(),
            minute = date.getMinutes(),
            second = date.getSeconds();
        table.$h.val(String.leftPad(hour, 2, '0'));
        table.$m.val(String.leftPad(minute, 2, '0'));
        table.$s.val(String.leftPad(second, 2, '0'));
    },

    /**
     * 时间增加单位1
     * @param {Object} timetable 时间表
     * @param {Object} input 时间输入框对象
     * @private
     */
    _doTimeInc: function(timetable, input){
        var t = input.data('time'), o = this.options;
        if (t === 'h') {
            var text = (o.date.getHours() + 1) % 24;
            o.date.setHours(text);
            timetable.$h.val(String.leftPad(text, 2, '0'));
        } else if (t === 'm') {
            var text = (o.date.getMinutes() + 1) % 60;
            o.date.setMinutes(text);
            timetable.$m.val(String.leftPad(text, 2, '0'));
        } else {
            var text = (o.date.getSeconds() + 1) % 60;
            o.date.setSeconds(text);
            timetable.$s.val(String.leftPad(text, 2, '0'));
        }
        input.select();
        FR.applyFunc(this, o.onDateUpdate, arguments);
    },
    /**
     * 时间减少单位1
     * @param {Object} timetable 时间表
     * @param {Object} input 时间输入框对象
     * @private
     */
    _doTimeDec: function(timetable, input){
        var t= input.data('time'), o = this.options;
        if (t === 'h') {
            var text = (o.date.getHours() + 23) % 24;
            o.date.setHours(text);
            timetable.$h.val(String.leftPad(text, 2, '0'));
        } else if (t === 'm') {
            var text = (o.date.getMinutes() + 59 ) % 60;
            o.date.setMinutes(text);
            timetable.$m.val(String.leftPad(text, 2, '0'));
        } else {
            var text = (o.date.getSeconds() + 59) % 60;
            o.date.setSeconds(text);
            timetable.$s.val(String.leftPad(text, 2, '0'));
        }
        input.select();
        FR.applyFunc(this, o.onDateUpdate, arguments);
    },
    /**
     * 所有绑定事件
     * @private
     */
    _bindEvts: function () {
    	// 日期控件展开时会绑定事件,为了避免多次展开选日期绑定多次事件,都先清一下
    	this.element.unbind();
        var self = this, o = this.options, NAV = this.CONSTS.NAV;
        var montable = this.$monthtable, datetable = this.$datetable, timetable = this.$timetable;
        var proxy = function (event) {
            var target = event.target;
            var type = event.type;
            var navitype = $(target).data('nav');
            if ($(target).data('disabled') || target.tagName !== 'TD' || !navitype) {
                return;
            }
            if(!self.options.date){
                self.options.date = new Date();
            }
            if (type === 'mouseover') {
                //MOUSEOVER事件
                $(target).addClass('hover');
            } else if (type === "mouseup") {
                //MOUSEUP事件
                switch (navitype) {
                    case NAV['prevm']:
                        //前月
                        self._toPrevMonth();
                        self._loadDateData(datetable, new Date(self.options.date));
                        FR.applyFunc(self, o.onDateUpdate, arguments);
                        break;
                    case NAV['nextm']:
                        //后月
                        self._toNextMonth();
                        self._loadDateData(datetable, new Date(self.options.date));
                        FR.applyFunc(self, o.onDateUpdate, arguments);
                        break;
                    case NAV['title']:
                        //加载数据
                        self._loadMonthData(montable, new Date(self.cache.showYear, self.cache.showMonth));
                        montable.css({
                            position: 'absolute',
                            top: 0,
                            'z-index': FR.widget.opts.zIndex++
                        }).show("fast");
                        break;
                    case NAV['clear']:
                        //清空按钮
                        self.options.date = null;
                        self.cache.selectedDate && self.cache.selectedDate.removeClass('selected');
                        FR.applyFunc(self, o.onDateUpdate, arguments);
                        FR.applyFunc(self, o.onClear, arguments);
                        break;
                    case NAV['current']:
                        //当前按钮
                        self.options.date = new Date();
                        FR.applyFunc(self, o.onDateUpdate, arguments);
                    case NAV['today']:
                        //今天按钮
                        var today = new Date();
                        if((self.options.startDate && today<self.options.startDate) ||
                            (self.options.endDate && today>self.options.endDate)){
                            return;
                        }else{
                            self.options.date = today;
                        }
                        FR.applyFunc(self, o.onDateUpdate, arguments);
                        FR.applyFunc(self, o.onToday, arguments);
                        break;
                    case NAV['dok']:
                        //日期界面的确认按钮
                        FR.applyFunc(self, o.onDateUpdate, arguments);
                        FR.applyFunc(self, o.onOK, arguments);
                        break;
                    case NAV['prevy']:
                        //前十年
                        self._toPrevDecade();
                        self._loadMonthData(montable, new Date(self.options.date));
                        FR.applyFunc(self, o.onDateUpdate, arguments);
                        break;
                    case NAV['nexty']:
                        //后十年
                        self._toNextDecade();
                        self._loadMonthData(montable, new Date(self.options.date));
                        FR.applyFunc(self, o.onDateUpdate, arguments);
                        break;
                    case NAV['mok']:
                        //年月界面的确认按钮
                        self._loadDateData(datetable, new Date(self.options.date));
                        FR.applyFunc(self, o.onDateUpdate, arguments);
                        montable.hide("fast");
                        break;
                    case NAV['cancel']:
                        //年月界面的取消按钮
                        self._loadDateData(datetable, new Date(self.options.date));
                        montable.hide("fast");
                        break;
                    case NAV['year']:
                        //选中年
                        self.cache.selectedYear && self.cache.selectedYear.removeClass('selected');
                        self.cache.selectedYear = $(target);
                        var date = self.options.date;
                        date.setFullYear($(target).text());
                        self._loadMonthData(montable, new Date(date));
                        FR.applyFunc(self, o.onDateUpdate, arguments);
                        break;
                    case NAV['month']:
                        //选中月
                        self.cache.selectedMonth && self.cache.selectedMonth.removeClass('selected');
                        self.cache.selectedMonth = $(target).addClass('selected');
                        self.options.date.setDate(1);
                        self.options.date.setMonth($(target).data('month'));
                        FR.applyFunc(self, o.onDateUpdate, arguments);
                        break;
                    case NAV['day']:
                        //选中日
                        self.cache.selectedDate && self.cache.selectedDate.removeClass('selected');
                        self.cache.selectedDate = $(target).addClass('selected');
                        var date = self.options.date;
                        date.setFullYear(self.cache.showYear);
                        date.setMonth(self.cache.showMonth);
                        date.setDate($(target).text());
                        FR.applyFunc(self, o.onDateUpdate, arguments);
                        if(!timetable.parent().length){
                            FR.applyFunc(self, o.onClose, arguments);
                        }
                        break;
                    case NAV['plus']:
                        //增加时间
                        self._doTimeInc(timetable, timetable.focus);
                        break;
                    case NAV['minus']:
                        //减少时间
                        self._doTimeDec(timetable, timetable.focus);
                        break;
                    case NAV['firstday']:
                        //选择周一或者周日排序
                        self.CONSTS.FIRSTDAY = $(target).data('fd');
                        self.element.empty();
                        self._init();
                    default:
                        break;
                }
            } else if (type === "mouseout") {
                //MOUSEOUT事件
                $(target).removeClass('hover');
            }
        };
        this.element.bind("mousedown", proxy)
            .bind("mouseover", proxy)
            .bind("mouseup", proxy)
            .bind("mouseout", proxy);
    },

    /**
     * 生成按钮对象
     * @param tr {$} 行
     * @param text {String} 文本内容
     * @param colspan {Number} 合并单元格
     * @param nav {Number} 操作数
     * @param cls {String} 类名
     * @returns {*} 返回TD对象
     * @private
     */
    _createCell: function (tr, text, colspan, nav, cls) {
        var $cell = $('<td class/>')
            .attr('colSpan', colspan)
            .html(text)
            .appendTo(tr);
        if (nav) {
            $cell.data('nav', nav);
        }
        cls = cls ? 'btn ' + cls : 'btn';
        $cell.addClass(cls);
        return $cell;
    },


    getValue: function () {
        return this.options.date;
    },

    setValue: function (value) {
        this.options.date = value;
    },

    getText: function () {
        return this.getValue();
    },

    setText: function (text) {
        this.setValue(text);
    }

});
$.shortcut('datepicker', FR.DatePicker);