Ext.ns('Nexts.module');

Nexts.module.SliduModule = Ext.extend(Nexts.module.WindowModule, {

	mtype: 'grid',
	
	addText			: 'Add',
	addTooltip		: 'Add record',
	copyText		: 'Copy',
	copyTooltip		: 'Copy record and paste it to the form',
	editText		: 'Edit',
	editTooltip		: 'Edit record',
	deleteText		: 'Delete',
	cancelText		: 'Cancel',
	deleteTooltip	: 'Delete selected records',
	deleteConfirmTitle: 'Confirm Delete',
	deleteConfirmMsgText: 'Are you sure you want to delete these {0} records?',
	
	defaultListConfig: {
		url: '.',
		start: 0,
		limit: 20
	},
	
	defaultStoreConfig: {
		root: 'dl',
		totalProperty: 'p.t',
	    paramNames : {
	        start : 'p.s',
	        limit : 'p.l',
	        sort : 's.c',
	        dir : 's.d'
	    },
		remoteSort: true
	},
	
	defaultSearchConfig: {
		position: 'top',
		align: 'right'
	},

	defaultFiltersConfig: {
		paramPrefix: 'q.fs.'
	},
	
	defaultExpanderConfig: {
	},
	
	defaultGridConfig: {
		stateful: true,
		stripeRows: true,
		loadMask: true,
		viewConfig: {
			forceFit: false
		}
	},
	
	defaultFormConfig: {
		header: false,
		border: false,
		width: 400,
		frame: true,
		bodyStyle: 'padding: 5px',
		clayout: 'column',
		clayoutConfig: {
			columns: 1
		},
		labelAlign: 'right',
		trackResetOnLoad: true,
		paramName: 'd'
	},
	
	defaultFormCtConfig: {
		region: 'east',
		stateful: true,
		border: false,
		frame: true,
		header: true,
		iconCls: 'ne-icon-form',
		animCollapse: false,
		collapsed: true,
		collapsible: true,
		titleCollapse: true,
 		floatable: false,
 		split: true,
		useSplitTips: true,
		width: 415,
		autoScroll: true
	},

	initConfig: function() {
		Nexts.module.SliduModule.superclass.initConfig.call(this);
		
		this.modeConfig = this.modeConfig || {};
		this.listConfig = Ext.applyIf(this.listConfig || {}, this.defaultListConfig);
		this.searchConfig = Ext.applyIf(this.searchConfig || {}, this.defaultSearchConfig);
		this.filtersConfig = Ext.applyIf(this.filtersConfig || {}, this.defaultFiltersConfig);
		this.storeConfig = Ext.applyIf(this.storeConfig || {}, this.defaultStoreConfig);
		this.expanderConfig = Ext.applyIf(this.expanderConfig || {}, this.defaultExpanderConfig);
		this.gridConfig = Ext.applyIf(this.gridConfig || {}, this.defaultGridConfig);
		this.formConfig = Ext.applyIf(this.formConfig || {}, this.defaultFormConfig);
		this.formCtConfig = Ext.applyIf(this.formCtConfig || {}, this.defaultFormCtConfig);

		Ext.applyIf(this.storeConfig, {
			url: this.listConfig.url
		});
		if (this.listConfig.sort) {
			Ext.applyIf(this.storeConfig, {
				sortInfo: {
					field: this.listConfig.sort,
					direction: this.listConfig.dir || 'ASC'
				}
			});
		}
		
		this.storeConfig.fields = [];
		this.columnConfig = [];
		this.filtersConfig.filters = [];
		this.expanderConfig.fields = {};
		this.formConfig.fields = {};
		
		for (var k in this.fieldsConfig) {
			var f = this.fieldsConfig[k];
			
			if (typeof f.label == 'undefined') {
				f.label = this.getText('fieldLabel.' + k, k);
			}

			// form config
			this.formConfig.fields[k] = {
				type: f.type,
				label: f.label,
				tooltip: f.tooltip,
				editor: f.editor
			};

			// store fields config
			var sfc = {
				name: k,
				type: f.type,
				dateFormat: f.dateFormat
			};
			if (sfc.type == 'date') {
				sfc.convert = Nexts.data.JavaDateConvert;
			}
			if (f.type == 'file' || f.type == 'image') {
				sfc.type = 'string';
				this.formConfig.fileUpload = true;
			}
			this.storeConfig.fields.push(sfc);
			
			// column config
			if (f.list !== false) {
				var cc = {
					dataIndex: k,
					header: f.label
				};
				if (typeof f.list == 'object') {
					Ext.apply(cc, f.list);
				}

				// delete config
				if (f.deleteFlag) {
					this.deletedColumn = new Nexts.grid.RowDeleted(cc);
				}
				else if (f.type == 'date') {
					if (!cc.renderer) {
						cc.renderer = Ext.util.Format.dateRenderer(f.dateFormat || 'Y-m-d');
					}
				}
				else if (f.type == 'boolean') {
					cc = new Nexts.grid.BooleanColumn(cc);
				}
				
				//combo
				if (f.editor && f.editor.xtype == 'combo') {
					cc.renderer = Ext.util.Format.comboRenderer(f.editor);
				}
				this.columnConfig.push(cc);

				// filters config
				if (f.filter !== false) {
					var fc = {
						dataIndex: k
					};
					if (typeof(f.filter) == 'object') {
						Ext.apply(fc, f.filter);
					}
					if (!fc.type) {
						switch (f.type) {
						case 'int':
						case 'float':
							fc.type = 'numeric';
							break;
						case 'boolean':
						case 'date':
						case 'string':
							fc.type = f.type;
							break;
						default:
							fc.type = 'string';
							break;
						}
					}
					this.filtersConfig.filters.push(fc);
				}
			}
			
			// expander config
			this.expanderConfig.fields[k] = {
				label: f.label,
				renderer: f.viewer,
				hidden: f.viewer === false
			};
		}
	},
	
	createChild: function() {
		this.createGrid();
		this.createForm();

		var items = [ this.grid ];
		if (this.modeConfig.canUpdate !== false ||
			this.modeConfig.canInsert !== false ||
			this.modeConfig.canDelete !== false) {
			this.formCt = new Ext.Panel(Ext.applyIf({
				id: this.id + '.formCt',
				iconCls: this.form.iconCls || this.formCtConfig.iconCls,
				title: this.form.title,
				items: [ this.form ],
				floatable: false
			}, this.formCtConfig));
			
			this.form.on({
				titlechange: function(f, t) {
					this.formCt.setTitle(t);
				},
				recorddeleted: this.onRecordDeleted,
				recorddeletefailed: this.onRecordDeleteFailed,
				scope: this
			});
			
			items.push(this.formCt);
		}

		this.panel = new Ext.Panel({
			id: this.id + '.ct',
			stateful: true,
			border: false,
			layout: 'border',
			items: items
		});
		
		return this.panel;
	},
	
	createGrid: function() {
		this.store = new Ext.data.JsonStore(this.storeConfig);

		var filters = new Nexts.grid.GridFilters(this.filtersConfig);
		
//		var search = new Nexts.plugins.GridSearch(this.searchConfig);
		
		var expander = new Nexts.grid.RowExpander(this.expanderConfig);
		
		var actioner = null;
		if (this.modeConfig.canUpdate !== false) {
			actioner = new Nexts.grid.RowActioner({
				actions: [{
					 iconCls: 'ne-icon-pencil',
					 qtip: this.editTooltip,
					 handler: this.onEditRecord,
					 scope: this
				}]
			});
		}

		var sm = null;
		if (this.modeConfig.canInsert !== false
			|| this.modeConfig.canUpdate !== false
			|| this.modeConfig.canDelete !== false) {
			sm = new Ext.grid.CheckboxSelectionModel();
		}

		var cm = [ expander ];
		if (actioner) {
			cm.push(actioner);
		}
		if (sm) {
			cm.push(sm);
		}
		
		var cm = new Ext.grid.ColumnModel({
			columns: cm.concat(this.columnConfig),
			defaults: {
				sortable: true
			}
		});
		
		var tbar = [];
		if (this.modeConfig.canInsert !== false) {
			this.addButton = new Ext.Toolbar.Button({
				text: this.addText,
				tooltip: this.addTooltip,
				iconCls: 'ne-icon-add',
				handler: this.onAddRecord,
				scope: this
			});
			tbar.push(this.addButton);
		}
		if (this.modeConfig.canInsert !== false 
			|| this.modeConfig.canUpdate !== false) {
			this.copyButton = new Ext.Toolbar.Button({
				text: this.copyText,
				tooltip: this.copyTooltip,
				iconCls: 'ne-icon-copy',
				handler: this.onCopyRecord,
				scope: this
			});
			if (tbar.length > 0) {
				tbar.push(' ');
			}
			tbar.push(this.copyButton);
		}
		if (this.modeConfig.canDelete !== false) {
			this.deleteButton = new Ext.Toolbar.Button({
				text: this.deleteText,
				tooltip: this.deleteTooltip,
				iconCls: 'ne-icon-delete',
				handler: this.onDeleteRecord,
				scope: this
			});
			if (tbar.length > 0) {
				tbar.push(' ');
			}
			tbar.push(this.deleteButton);
		}
		
		var ps = [ filters, expander ];
		if (this.deletedColumn) {
			ps.push(this.deletedColumn);
		}
		if (actioner) {
			ps.push(actioner);
		}

		var gcfg = Ext.applyIf({
			id: this.id + '.grid',
			region: 'center',
			cm: cm,
			store: this.store,
			tbar: tbar,
			plugins: ps,
			bbar: new Nexts.PagingToolbar({
				store: this.store,
				displayInfo: true,
				pageSize: this.listConfig.limit
			}),
			listeners: {
				render: {
					fn: function() {
						var ps = {};
						ps[this.storeConfig.paramNames.start] = this.listConfig.start;
						ps[this.storeConfig.paramNames.limit] = this.listConfig.limit;
						this.store.load({
							params: ps
						});
					},
					scope: this,
					delay: 200
				}
			}
		}, this.gridConfig);
		
		if (sm) {
			gcfg.sm = new Ext.grid.CheckboxSelectionModel();
		}
		this.grid = new Ext.grid.GridPanel(gcfg);
	},

	createForm: function() {
		this.form = new (this.formClass || Nexts.grid.RecordForm)(Ext.applyIf({
			id: this.id + '.form',
			header: false,
			grid: this.grid,
			modeConfig: this.modeConfig,
			record: this.newRecord()
		}, this.formConfig));
	},
	
	onCloseModule: function(m) {
		delete this.panel;
		delete this.grid;
		delete this.store;
		delete this.form;
		delete this.formCt;
		delete this.deleting;
		delete this.cancelDelete;
		Nexts.module.SliduModule.superclass.onCloseModule.apply(this, arguments);
	},

	newRecord: function() {
		var r = new this.store.recordType({});
		r.initData();
		return r;
	},

	onAddRecord: function() {
		if (!this.deleting) {
			this.formCt.expand();
			this.form.setInsertRecord(this.newRecord());
		}
	},

	onEditRecord: function(grid, record, row, col, action) {
		if (!this.deleting) {
			this.formCt.expand();
			this.form.setUpdateRecord(record);
		}
	},

	onCopyRecord: function() {
		if (!this.deleting) {
			this.formCt.expand();
			var r = this.grid.getSelectionModel().getSelected();
			this.form.copyDataFromRecord(r, this.copyFilters);
		}
	},
		
	onDeleteRecord: function() {
		if (this.cancelDelete) {
		}
		else if (this.deleting) {
			this.cancelDelete = true;
		}
		else {
			var rs = this.grid.getSelectionModel().getSelections();
			if (rs && rs.length == 1) {
				this.formCt.expand();
				this.form.setUpdateRecord(rs[0]);
				this.form.onDeleteRecord();
			}
			else if (rs && rs.length > 1) {
				var s = this.deleteConfirmMsgText.format(rs.length);
				Ext.Msg.confirm(this.deleteConfirmTitle, s, function(btn) {
					if (btn == 'yes') {
						this.grid.getSelectionModel().lock();
						this.addButton.disable();
						this.copyButton.disable();
						this.deleteButton.setText(this.cancelText);
						this.deleting = true;
		
						this.formCt.expand();
						this.form.setUpdateRecord(rs[0]);
						this.form.deleteRecord();
					}
				}, this);
			}
		}
	},
	
	endDelete: function() {
		this.grid.getSelectionModel().unlock();
		this.addButton.enable();
		this.copyButton.enable();
		this.deleteButton.setText(this.deleteText);
		delete this.deleting;
		delete this.cancelDelete;
	},
	
	onRecordDeleted: function(form, record) {
		if (this.deleting) {
			if (this.cancelDelete) {
				this.endDelete();
			}
			else {
				var rs = this.grid.getSelectionModel().getSelections();
				if (rs && rs.length > 0) {
					this.formCt.expand();
					this.form.setUpdateRecord(rs[0]);
					this.form.deleteRecord.defer(20, this.form);
				}
				else {
					this.endDelete();
				}
			}
		}
	},
	
	onRecordDeleteFailed: function(form, record) {
		if (this.deleting) {
			this.endDelete();
		}
	}
});

