/**
 * propertygrid - jQuery EasyUI
 *
 * Copyright (c) 2009-2013 www.jeasyui.com. All rights reserved.
 *
 * Licensed under the GPL or commercial licenses
 * To use it on other terms please contact us: info@jeasyui.com
 * http://www.gnu.org/licenses/gpl.txt
 * http://www.jeasyui.com/license_commercial.php
 *
 * Dependencies:
 *     datagrid
 *
 */
(function ($) {
    var currTarget;

    function buildGrid(target) {
        var state = $.data(target, 'propertygrid');
        var opts = $.data(target, 'propertygrid').options;
        $(target).datagrid($.extend({}, opts, {
            cls: 'propertygrid',
            view: (opts.showGroup ? groupview : undefined),
            onClickRow: function (index, row) {
                if (currTarget != this) {
//					leaveCurrRow();
                    stopEditing(currTarget);
                    currTarget = this;
                }
                if (opts.editIndex != index && row.editor) {
                    var col = $(this).datagrid('getColumnOption', "value");
                    col.editor = row.editor;
//					leaveCurrRow();
                    stopEditing(currTarget);
                    $(this).datagrid('beginEdit', index);
                    $(this).datagrid('getEditors', index)[0].target.focus();
                    opts.editIndex = index;
                }
                opts.onClickRow.call(target, index, row);
            },
            loadFilter: function (data) {
                stopEditing(this);
                return opts.loadFilter.call(this, data);
            },
            onLoadSuccess: function (data) {
//				$(target).datagrid('getPanel').find('div.datagrid-group').css('border','');
                $(target).datagrid('getPanel').find('div.datagrid-group').attr('style', '');
                opts.onLoadSuccess.call(target, data);
            }
        }));
        $(document).unbind('.propertygrid').bind('mousedown.propertygrid', function (e) {
            var p = $(e.target).closest('div.datagrid-view,div.combo-panel');
//			var p = $(e.target).closest('div.propertygrid,div.combo-panel');
            if (p.length) {
                return;
            }
            stopEditing(currTarget);
            currTarget = undefined;
        });

//		function leaveCurrRow(){
//			var t = $(currTarget);
//			if (!t.length){return;}
//			var opts = $.data(currTarget, 'propertygrid').options;
//			var index = opts.editIndex;
//			if (index == undefined){return;}
//			var ed = t.datagrid('getEditors', index)[0];
//			if (ed){
//				ed.target.blur();
//				if (t.datagrid('validateRow', index)){
//					t.datagrid('endEdit', index);
//				} else {
//					t.datagrid('cancelEdit', index);
//				}
//			}
//			opts.editIndex = undefined;
//		}
    }

    function stopEditing(target) {
        var t = $(target);
        if (!t.length) {
            return
        }
        var opts = $.data(target, 'propertygrid').options;
        var index = opts.editIndex;
        if (index == undefined) {
            return;
        }
        var ed = t.datagrid('getEditors', index)[0];
        if (ed) {
            ed.target.blur();
            if (t.datagrid('validateRow', index)) {
                t.datagrid('endEdit', index);
            } else {
                t.datagrid('cancelEdit', index);
            }
        }
        opts.editIndex = undefined;
    }

    $.fn.propertygrid = function (options, param) {
        if (typeof options == 'string') {
            var method = $.fn.propertygrid.methods[options];
            if (method) {
                return method(this, param);
            } else {
                return this.datagrid(options, param);
            }
        }

        options = options || {};
        return this.each(function () {
            var state = $.data(this, 'propertygrid');
            if (state) {
                $.extend(state.options, options);
            } else {
                var opts = $.extend({}, $.fn.propertygrid.defaults, $.fn.propertygrid.parseOptions(this), options);
                opts.frozenColumns = $.extend(true, [], opts.frozenColumns);
                opts.columns = $.extend(true, [], opts.columns);
                $.data(this, 'propertygrid', {
                    options: opts
                });
            }
            buildGrid(this);
        });
    }

    $.fn.propertygrid.methods = {
        options: function (jq) {
            return $.data(jq[0], 'propertygrid').options;
        }
    };

    $.fn.propertygrid.parseOptions = function (target) {
        var t = $(target);
        return $.extend({}, $.fn.datagrid.parseOptions(target), $.parser.parseOptions(target, [{showGroup: 'boolean'}]));
    };

    // the group view definition
    var groupview = $.extend({}, $.fn.datagrid.defaults.view, {
        render: function (target, container, frozen) {
            var state = $.data(target, 'datagrid');
            var opts = state.options;
            var rows = state.data.rows;
            var fields = $(target).datagrid('getColumnFields', frozen);

            var table = [];
            var index = 0;
            var groups = this.groups;
            for (var i = 0; i < groups.length; i++) {
                var group = groups[i];

                table.push('<div class="datagrid-group" group-index=' + i + ' style="height:25px;overflow:hidden;border-bottom:1px solid #ccc;">');
                table.push('<table cellspacing="0" cellpadding="0" border="0" style="height:100%"><tbody>');
                table.push('<tr>');
                table.push('<td style="border:0;">');
                if (!frozen) {
                    table.push('<span style="color:#666;font-weight:bold;">');
                    table.push(opts.groupFormatter.call(target, group.fvalue, group.rows));
                    table.push('</span>');
                }
                table.push('</td>');
                table.push('</tr>');
                table.push('</tbody></table>');
                table.push('</div>');

                table.push('<table class="datagrid-btable" cellspacing="0" cellpadding="0" border="0"><tbody>');
                for (var j = 0; j < group.rows.length; j++) {
                    // get the class and style attributes for this row
                    var cls = (index % 2 && opts.striped) ? 'class="datagrid-row datagrid-row-alt"' : 'class="datagrid-row"';
                    var styleValue = opts.rowStyler ? opts.rowStyler.call(target, index, group.rows[j]) : '';
                    var style = styleValue ? 'style="' + styleValue + '"' : '';
                    var rowId = state.rowIdPrefix + '-' + (frozen ? 1 : 2) + '-' + index;
                    table.push('<tr id="' + rowId + '" datagrid-row-index="' + index + '" ' + cls + ' ' + style + '>');
                    table.push(this.renderRow.call(this, target, fields, frozen, index, group.rows[j]));
                    table.push('</tr>');
                    index++;
                }
                table.push('</tbody></table>');
            }

            $(container).html(table.join(''));
        },

        onAfterRender: function (target) {
            var opts = $.data(target, 'datagrid').options;
            var dc = $.data(target, 'datagrid').dc;
            var view = dc.view;
            var view1 = dc.view1;
            var view2 = dc.view2;

            $.fn.datagrid.defaults.view.onAfterRender.call(this, target);

            if (opts.rownumbers || opts.frozenColumns.length) {
                var group = view1.find('div.datagrid-group');
            } else {
                var group = view2.find('div.datagrid-group');
            }
            $('<td style="border:0;text-align:center;width:25px"><span class="datagrid-row-expander datagrid-row-collapse" style="display:inline-block;width:16px;height:16px;cursor:pointer">&nbsp;</span></td>').insertBefore(group.find('td'));

            view.find('div.datagrid-group').each(function () {
                var groupIndex = $(this).attr('group-index');
                $(this).find('span.datagrid-row-expander').bind('click', {groupIndex: groupIndex}, function (e) {
                    if ($(this).hasClass('datagrid-row-collapse')) {
                        $(target).datagrid('collapseGroup', e.data.groupIndex);
                    } else {
                        $(target).datagrid('expandGroup', e.data.groupIndex);
                    }
                });
            });
        },

        onBeforeRender: function (target, rows) {
            var opts = $.data(target, 'datagrid').options;
            var groups = [];
            for (var i = 0; i < rows.length; i++) {
                var row = rows[i];
                var group = getGroup(row[opts.groupField]);
                if (!group) {
                    group = {
                        fvalue: row[opts.groupField],
                        rows: [row],
                        startRow: i
                    };
                    groups.push(group);
                } else {
                    group.rows.push(row);
                }
            }

            function getGroup(fvalue) {
                for (var i = 0; i < groups.length; i++) {
                    var group = groups[i];
                    if (group.fvalue == fvalue) {
                        return group;
                    }
                }
                return null;
            }

            this.groups = groups;

            var newRows = [];
            for (var i = 0; i < groups.length; i++) {
                var group = groups[i];
                for (var j = 0; j < group.rows.length; j++) {
                    newRows.push(group.rows[j]);
                }
            }
            $.data(target, 'datagrid').data.rows = newRows;
        }
    });

    $.extend($.fn.datagrid.methods, {
        expandGroup: function (jq, groupIndex) {
            return jq.each(function () {
                var view = $.data(this, 'datagrid').dc.view;
                if (groupIndex != undefined) {
                    var group = view.find('div.datagrid-group[group-index="' + groupIndex + '"]');
                } else {
                    var group = view.find('div.datagrid-group');
                }
                var expander = group.find('span.datagrid-row-expander');
                if (expander.hasClass('datagrid-row-expand')) {
                    expander.removeClass('datagrid-row-expand').addClass('datagrid-row-collapse');
                    group.next('table').show();
                }
                $(this).datagrid('fixRowHeight');
            });
        },
        collapseGroup: function (jq, groupIndex) {
            return jq.each(function () {
                var view = $.data(this, 'datagrid').dc.view;
                if (groupIndex != undefined) {
                    var group = view.find('div.datagrid-group[group-index="' + groupIndex + '"]');
                } else {
                    var group = view.find('div.datagrid-group');
                }
                var expander = group.find('span.datagrid-row-expander');
                if (expander.hasClass('datagrid-row-collapse')) {
                    expander.removeClass('datagrid-row-collapse').addClass('datagrid-row-expand');
                    group.next('table').hide();
                }
                $(this).datagrid('fixRowHeight');
            });
        }
    });
    // end of group view definition

    $.fn.propertygrid.defaults = $.extend({}, $.fn.datagrid.defaults, {
        singleSelect: true,
        remoteSort: false,
        fitColumns: true,
        loadMsg: '',
        frozenColumns: [[
            {field: 'f', width: 16, resizable: false}
        ]],
        columns: [[
            {field: 'name', title: 'Name', width: 100, sortable: true},
            {field: 'value', title: 'Value', width: 100, resizable: false}
        ]],

        showGroup: false,
        groupField: 'group',
        groupFormatter: function (fvalue, rows) {
            return fvalue
        }
    });
})(jQuery);
