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

    /**
     * 表格控件
     *
     *     @example
     *     var grid = new FR.QuickGrid({
     *                  renderEl : $('body'),
     *                  baseCls: 'fr-grid',
     *                  marginLeft : 20,
     *                  marginRight :0,
     *                  items : [],
     *                  columnsConfig:[],
     *                  page : true,
     *                  pageCount: 15,
     *                  isFootShow :true,
     *                  isHeadShow :true,
     *                  multiSelect : false,
     *                  intervalColor : false,
     *                  isInitWithData : true,
     *                  async: false,
     *                  onBeforeRowCreate: null,
     *                  onAfterRowCreate: null,
     *                  onBeforeHeadCreate: null,
     *                  onAfterHeadCreate: null,
     *                  onRowClick: null,
     *                  items: [
     *                              {
     *                                  name: 'Task1',
     *                                  sender: 'peter',
     *                                  deadline: '2014-09-10',
     *                                  status: '0',
     *                                  operation: '1'
     *                              },
     *                              {
     *                                  name: 'Task2',
     *                                  sender: 'alex',
     *                                  deadline: '2005-12-10',
     *                                  status: '1',
     *                                  operation: '2'
     *                              }
     *                          ],
     *                  columnsConfig: [
     *                      {
     *                          key: 'name',
     *                          value: '任务名称',
     *                          width: 200
     *                      },
     *                      {
     *                          key: 'sender',
     *                          value: '发送人',
     *                          width: 85,
     *                      },
     *                     {
     *                          key: 'sendtime',
     *                          value: '发送时间',
     *                          width: 120
     *                      },
     *                      {
     *                          key: 'status',
     *                          value: '任务状态',
     *                          width: 120
     *                      },
     *                      {
     *                          key: 'operation',
     *                          value: '任务操作',
     *                          width: 120
     *                      },
     *                      {
     *                          onCellCreate: function(rowIdx, colIdx, item, colCfg){
     *                              if(item.operation == '1'){
     *                                  return $('<div/>').html('right');
     *                              }else{
     *                                  return $('<div/>').html('wrong');
     *                              }
     *                          },
     *                          width: 90
     *                      },
     *                      {
     *                          onCellCreate: function(rowIdx, colIdx, item, colCfg){
     *                              if(item.status == '1'){
     *                                  return $('<div/>').html('&lsaquo;');
     *                              }else{
     *                                  return $('<div/>').html('&rsaquo;');
     *                              }
     *                          },
     *                          width: 90
     *                      }
     *                  ]
     *          });
     * @class FR.QuickGrid
     * @extends FR.Widget
     * @since 7.0.6
     *
     * @cfg {JSON} options 配置属性
     * @cfg {String} options.baseCls 控件基础类
     * @cfg {String} options.baseId 控件唯一ID
     * @cfg {Number} options.marginLeft 左间距
     * @cfg {Number} options.marginRight 右间距
     * @cfg {Array} options.items 数据
     * @cfg {Array} options.columnsConfig 列属性配置
     * @cfg {Array} options.localeArray 需要做国际化转换的列名数组
     * @cfg {Function} options.columnsConfig[columnIndex].onCellCreate 单元格生成事件
     * @cfg {Function} options.columnsConfig[columnIndex].onCellClick 单元格点击事件
     * @cfg {Function} options.columnsConfig[columnIndex].onHeadCellCreate 表头单元格生成事件
     * @cfg {Object} options.columnsConfig[columnIndex].css 单元格自定义样式
     * @cfg {Boolean} [options.page=false] 是否分页
     * @cfg {Boolean} [options.autoPage=true] 是否自动计算分页
     * @cfg {Number} [options.pageCount=15] 分页后每页显示的数据数,page属性为true时生效
     * @cfg {String} [options.footAlign='bottom'] 翻页按钮的位置,'bottom'|'top'
     * @cfg {Boolean} [options.isFootShow=true] 是否显示表尾控制按钮,page属性为true时生效
     * @cfg {Boolean} [options.isHeadShow=true] 是否显示表头
     * @cfg {Boolean} [options.intervalColor=false] 是否颜色相间
     * @cfg {Boolean} [options.multiSelect=false] 是否多选
     * @cfg {Boolean} [options.isInitWithData=true] 控件生成时是否初始化数据
     * @cfg {Boolean} [options.hasHoverCls=true] 是否有悬浮样式
     * @cfg {Object} options.async 异步属性配置
     * @cfg {String} options.async.url 异步请求地址
     * @cfg {String} options.async.type 异步请求方式
     * @cfg {Object} options.async.data 异步请求参数
     * @cfg {Function} options.onPageTurn 翻页事件
     * @cfg {Function} options.onBeforeRowCreate 行生成前事件
     * @cfg {Function} options.onAfterRowCreate 行生成后事件
     * @cfg {Function} options.onBeforeHeadCreate 表头行生成前事件
     * @cfg {Function} options.onAfterHeadCreate 表头行生成后事件
     * @cfg {Function} options.onRowClick 行点击事件
     * @cfg {Function} options.onRowMouseDown 行鼠标下按事件
     * @cfg {Function} options.onRowMouseOver 行鼠标悬浮事件
     * @cfg {Function} options.onRowMouseOut 行鼠标移出事件
     * @cfg {Function} options.onAsyncSuccess 异步请求成功事件,async属性配置后生效
     * @cfg {Function} options.onAsyncError 异步请求错误事件,async属性配置后生效
     */
    FR.QuickGrid = FR.extend(FR.Widget, /**@class FR.QuickGrid*/{
        NAV: {
            FIRSTPAGE: 'first', //第一页
            PREVPAGE: 'prev', //上一页
            NEXTPAGE: 'next', //下一页
            LASTPAGE: 'last', //最后一页
            JUMPPAGE: 'jump'  //跳转至某页
        },
        _defaultConfig: function () {
            return $.extend(FR.QuickGrid.superclass._defaultConfig.call(), {
                baseCls: 'fr-grid',
                baseId: null,
                marginLeft: 10,
                marginRight: 10,
                items: [],
                columnsConfig: [],
                page: false,
                autoPage: true,
                pageCount: 15,
                footAlign: 'bottom',
                isFootShow: true,
                isHeadShow: true,
                multiSelect: false,
                intervalColor: false,
                isInitWithData: true,
                async: null,
                hasHoverCls: true,
                onPageTurn: null,
                onAsyncSuccess: null,
                onAsyncError: null,
                onBeforeRowCreate: null,
                onAfterRowCreate: null,
                onBeforeHeadCreate: null,
                onAfterHeadCreate: null,
                localeArray: []
            });
        },

        _init: function () {
            FR.QuickGrid.superclass._init.apply(this, arguments);
            this.$container = $('<div class="fr-grid-table"/>');
            this.element.append(this.$container);
            this.activedPage = 1;
            var o = this.options;
            if(o.baseId){
                this.element.attr('id', o.baseId);
            }
            if (o.isInitWithData) {
                this.refresh();
            } else {
                this._initWidth();
                this.$table = $('<table cellPadding="0" cellSpacing="0"/>');
                this._onCreateHead();
                this._onCreateFoot();
                this.$table.appendTo(this.$container);
            }
        },

        /**
         * 刷新数据并重建数据表格
         * @param {Array} items 需要刷新的静态数据或是异步取数时的其他需要传递的信息
         */
        refresh: function (items) {
            var self = this, o = this.options;
            if ($.isArray(items)) {
                this.options.items = items;
                this.reBuild();
            } else if (o.async) {
                FR.ajax({
                    url: o.async.url,
                    type: o.async.type ? o.async.type : 'POST',
                    data: o.async.data,
                    success: function (res, status) {
                        FR.applyFunc(self, o.onAsyncSuccess, [res, status, items]);
                        self.reBuild();
                    },
                    error: function (res, status) {
                        FR.applyFunc(self, o.onAsyncError, [res, status, items])
                    }
                });
            } else {
                this.reBuild();
            }
        },

        /**
         * 重新构建数据表格,但不刷新原有数据
         */
        reBuild: function () {
            if(this.options.multiSelect){
                this.allBoxes = [];
            }
            if (this.$table) {
                this.$table.remove();
                this.$table = null;
            }
            this._initWidth();
            this.$table = $('<table cellPadding="0" cellSpacing="0"/>');
            this._onCreateHead();
            this._onCreateTable();
            this._onCreateFoot();
            this._bindEvts();
            this.$container.append(this.$table);
        },

        /**
         * 控件总宽度计算
         */
        _initWidth: function () {
            var width = 0, opts = this.options;
            for (var i = 0, len = opts.columnsConfig.length; i < len; i++) {
                width += opts.columnsConfig[i].width;
            }
            if(opts.multiSelect){
                width +=25;
            }
            width += opts.marginLeft;
            width += opts.marginRight;
            opts.width = width;
            this.element.width(width);
        },

        /**
         * 生成表头
         * @private
         */
        _onCreateHead: function () {
            var opts = this.options, self = this;
            var needHead = opts.isHeadShow;
            this.$head = $('<thead/>');
            var $tr = $('<tr/>').appendTo(this.$head);
            FR.applyFunc(this, opts.onBeforeHeadCreate, [$tr], false);
            $('<td/>').append($('<div/>').width(opts.marginLeft)).appendTo($tr);
            if (opts.multiSelect) {
                this.$AllCheck = new FR.CheckBox({
                    width: 25,
                    listeners: [
                        {
                            eventName: FR.Events.STATECHANGE,
                            action: function(){
                                if(!self.allBoxes){
                                    return;
                                }
                                var isSel = this.isSelected();
                                for(var i= 0,len=self.allBoxes.length;i<len;i++){
                                    var box = self.allBoxes[i];
                                    box.setValue(isSel);
                                }
                            }
                        }
                    ]
                });
                $('<td/>').append(this.$AllCheck.element).appendTo($tr);
            }
            for (var colIdx = 0, len = opts.columnsConfig.length; colIdx < len; colIdx++) {
                var itemcfg = opts.columnsConfig[colIdx];
                var $cell = $('<td/>').width(this._calculateWidth(itemcfg));
                var $el = FR.applyFunc(this, itemcfg.onHeadCellCreate, [colIdx, itemcfg], false);
                if ($el === false) {
                    $cell.css('text-align', itemcfg.textAlign ? itemcfg.textAlign : 'left')
                        .text(itemcfg.value ? itemcfg.value : itemcfg.key);
                } else {
                    $cell.append($el);
                }
                $cell.appendTo($tr);
            }
            $('<td/>').append($('<div/>').width(opts.marginRight)).appendTo($tr);
            FR.applyFunc(this, opts.onAfterHeadCreate, [$tr], false);
            if (needHead) {
                this.$table.append(this.$head);
            }
        },
        _calculateWidth: function (itemcfg) {
            if (itemcfg) {
                if (itemcfg.width > 0 && itemcfg.width < 1) {
                    return itemcfg.width * this.element.width();
                } else {
                    return itemcfg.width
                }
            }
            return 0;
        },
        /**
         * 生成表体
         * @private
         */
        _onCreateTable: function () {
            this.$tbody = $('<tbody/>');
            var o = this.options;
            var items = o.items;
            if(o.page && o.autoPage){
                this.totalpages = Math.ceil(o.items.length/o.pageCount);
                items = o.items.slice(o.pageCount * (this.activedPage - 1), o.pageCount * this.activedPage);
            }
            for (var i = 0, len = items.length; i < len; i++) {
                var $row = this.onCreateRow(i, items[i]);
                this.$tbody.append($row);
            }
            this.$table.append(this.$tbody);
        },

        /**
         * 生成表尾的翻页按钮
         * @private
         */
        _onCreateFoot: function(){
            var self = this, o = this.options, nav = this.NAV;
            if(!o.page){
                return;
            }
            if(this.$foot){
                this.$foot.remove();
                this.$foot = null;
            }
            this.$foot = $('<div class="fr-grid-foot"/>').css({'margin-left': o.width - 240 - o.marginRight});
            //到第一页
            var mf = new FR.IconButton({
                imgsrc : 'fr-grid-foot-first',
                width: 24,
                height: 24,
                handler : function() {
                    self.activedPage = 1;
                    if(!FR.applyFunc(self, o.onPageTurn, [self.activedPage, o.pageCount, nav['FIRSTPAGE']], false)){
                        self.reBuild();
                    }
                }
            });
            //到前一页
            var mp = new FR.IconButton({
                imgsrc : 'fr-grid-foot-prev',
                width: 24,
                height: 24,
                handler : function() {
                    self.activedPage --;
                    if(!FR.applyFunc(self, o.onPageTurn, [self.activedPage, o.pageCount, nav['PREVPAGE']], false)){
                        self.reBuild();
                    }
                }
            });
            //到下一页
            var mn = new FR.IconButton({
                imgsrc : 'fr-grid-foot-next',
                width: 24,
                height: 24,
                handler : function() {
                    self.activedPage ++;
                    if(!FR.applyFunc(self, o.onPageTurn, [self.activedPage, o.pageCount, nav['NEXTPAGE']], false)){
                        self.reBuild();
                    }
                }
            });
            //到最后一页
            var ml = new FR.IconButton({
                imgsrc : 'fr-grid-foot-last',
                width: 24,
                height: 24,
                handler : function() {
                    self.activedPage = self.totalpages;
                    if(!FR.applyFunc(self, o.onPageTurn, [self.activedPage, o.pageCount, nav['LASTPAGE']], false)){
                        self.reBuild();
                    }
                }
            });
            var pageLoader = $('<input class="fr-grid-foot-loader" type="text"/>')
                .val(this.activedPage).keydown(function(e) {
                if (e.keyCode === 13) {
                    self.activedPage = $(this).val();
                    if(!FR.applyFunc(self, o.onPageTurn, [self.activedPage, o.pageCount, nav['JUMPPAGE']], false)){
                        self.reBuild();
                    }
                    e.stopEvent();
                }
            });
            var showPage = this.totalpages?this.totalpages: 1;
            if(this.activedPage >= showPage){
                ml.setEnable(false);
                mn.setEnable(false);
            }
            if(this.activedPage <= 1){
                mp.setEnable(false);
                mf.setEnable(false);
            }
            var totalPane = $('<div class="fr-grid-foot-page"/>').text(" /"+showPage +" "+ FR.i18nText("FR-Basic_Page_Number"));
            var table = $('<table/>').attr({id : 'fr-grid-foot-table', cellPadding : 0, cellSpacing : 0});
            $('<tr/>').append($('<td/>').append(mf.element)).append($('<td>').append(mp.element))
                .append($('<td/>').addClass('fr-grid-foot-pageshow').append(pageLoader).append(totalPane))
                .append($('<td/>').append(mn.element)).append($('<td/>').append(ml.element)).appendTo(table);
            this.$foot.append(table);
            if(o.footAlign == 'top'){
                this.$foot.prependTo(this.element);
            }else{
                this.$foot.appendTo(this.element);
            }
        },

        /**
         * 绑定事件
         * @private
         */
        _bindEvts: function () {
            var self = this, o = this.options;
            var proxy = function (event) {
                var target = event.target;
                var type = event.type;
                var $row = self._getTargetDom(target, 'TR');
                if (!$row) {
                    return;
                }
                if (type === 'mousedown') {
                    FR.applyFunc(self, o.onRowMouseDown, [$row], false);
                } else if (type === 'mouseover') {
                    o.hasHoverCls && $row.addClass('hover');
                    FR.applyFunc(self, o.onRowMouseOver, [$row], false);
                } else if (type === "mouseout") {
                    $row.removeClass('hover');
                    FR.applyFunc(self, o.onRowMouseOut, [$row], false);
                } else if (type === "mouseup") {
                    FR.applyFunc(self, o.onRowClick, [$row], false);
                }
            };
            this.element.bind("mousedown", proxy)
                .bind("mouseover", proxy)
                .bind("mouseup", proxy)
                .bind("mouseout", proxy);
        },

        /**
         * 回溯获取指定DOM层对象
         * @param {Object} curDom 当前DOM
         * @param {String} targetTag DOM节点的标签
         * @returns {*} 返回获取的DOM对象
         * @private
         */
        _getTargetDom: function (curDom, targetTag) {
            while (curDom && curDom.tagName) {
                if (curDom.tagName.toUpperCase() !== targetTag.toUpperCase()) {
                    curDom = curDom.parentNode;
                } else {
                    return $(curDom);
                }
            }
            return null;
        },

        /**
         * 生成行数据
         * @param rowIdx 行索引
         * @param item 数据项
         * @returns {*|jQuery|HTMLElement}
         */
        onCreateRow: function (rowIdx, item) {
            var o = this.options ,self = this;
            var $row = $('<tr/>');
            FR.applyFunc(this, o.onBeforeRowCreate, [$row, rowIdx, item], false);
            $('<td/>').width(o.marginLeft).appendTo($row);
            if (o.multiSelect) {
                var $check = new FR.CheckBox({
                    width: 25,
                    gridRowData: item,
                    listeners: [{
                        eventName: FR.Events.STATECHANGE,
                        action: function(){
                            if(!self.$AllCheck){
                                return;
                            }
                            if(this.isSelected()){
                                var isAllsel = true;
                                for(var i= 0,len= self.allBoxes.length;i<len;i++){
                                    var box = self.allBoxes[i];
                                    if(!box.isSelected()){
                                        isAllsel = false;
                                        break;
                                    }
                                }
                                self.$AllCheck.setValue(isAllsel);
                            }else{
                                self.$AllCheck.setValue(false);
                            }
                        }
                    }]
                });
                this.allBoxes.push($check);
                $('<td/>').append($check.element).appendTo($row);
            }
            for (var colIdx = 0, len = o.columnsConfig.length; colIdx < len; colIdx++) {
                var colCfg = o.columnsConfig[colIdx];
                var $cell = this.onCellCreate(rowIdx, colIdx, item, colCfg);
                $cell.appendTo($row);
            }
            if (o.intervalColor && rowIdx % 2 === 0) {
                $row.addClass('even');
            }
            $('<td/>').width(o.marginRight).appendTo($row);
            FR.applyFunc(this, o.onAfterRowCreate, [$row, rowIdx, item], false);
            return $row;
        },

        /**
         * 生成单元格事件
         * @param rowIdx 行索引
         * @param colIdx 列索引
         * @param item 数据项
         * @param colCfg 列属性配置
         * @returns {*|jQuery|HTMLElement}
         */
        onCellCreate: function (rowIdx, colIdx, item, colCfg) {
            var $td = $('<td/>'), self = this;
            var $cell = FR.applyFunc(this, colCfg.onCellCreate, [rowIdx, colIdx, item, colCfg], false);
            if ($cell === false) {
                if (!FR.isEmpty(colCfg.value)) {
                    var val = $.inArray(colCfg.key, self.options.localeArray) == -1 ? item[colCfg.key] : FR.i18nText(item[colCfg.key]);
                    $cell = $('<div class="cell"/>').width(self._calculateWidth(colCfg))
                        .text(val).attr('title', val)
                        .appendTo($td);
                }
            } else {
                $td.append($cell);
            }
            $td.click(function(){
                FR.applyFunc(self, colCfg.onCellClick, [rowIdx, colIdx, item, colCfg, $cell], false);
            });
            FR.applyStyles($cell, colCfg.css);
            return $td;
        },

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

        /*API for QuickGrid*/
        addRowData: function (item) {
            var self = this, o = this.options;
            if (o.async) {

            } else {
                var $row = this.onCreateRow(this.options.items.length, item);
                this.options.items.push(item);
                $row.appendTo(this.$tbody);
            }
        },

        /**
         * multiSelet为true时,可获取选中行的数据
         * @returns {Array} 返回所有选中的数据
         */
        getSelectedData: function(){
            var datas = [];
            if(this.allBoxes){
                for(var i= 0,len=this.allBoxes.length;i<len;i++){
                    var box = this.allBoxes[i];
                    if(box.isSelected()){
                        datas.push(box.options.gridRowData);
                    }
                }
            }
            return datas;
        }

    });
    $.shortcut("quickgrid", FR.QuickGrid);
}(jQuery));