Ext.define("Portfolio.dynapp.view.Grid", {

	extend: "Ext.grid.Panel",

	alias: "widget.dynapp.gridpanel",

	options: {},

	controller: "dynapp.gridpanel",

	listeners: {
		itemdblclick: {
			fn: "onEdit"
		},
		itemcontextmenu: {
			fn: "onItemMenu"
		},
		afterrender: {
			fn: "onAfterRender"
		},
		sortChange: {
			fn: "onSortChange"
		}
	},

	viewConfig: {
		variableRowHeight: true
	},

	alternateClassName: [
		"Ext.dynapp.view.Grid"
	],

	requires: [
		"Portfolio.dynapp.view.Toolbar",
		"Portfolio.dynapp.controller.Grid",
		"Portfolio.dynapp.view.Detail",
		"Ext.ux.form.field.Search"
	],

	initComponent: function() {

		var i_self = this;
		var s_uid = "";
		var o_options = i_self.options;
		i_self.addConfig();
		i_self.callParent(arguments);
		i_self.addDocked(i_self.createToolbars());
		var i_store = i_self.getStore();
		i_store.load();
		return i_self;
	},

	addConfig: function() {

		var i_self = this;
		i_self.store = i_self.createStore(i_self.fields);
		Ext.apply(i_self, {
			columns: i_self.createColumns(i_self.fields)
		});
	},

	createStore: function(a_fields) {

		var i_self = this;
		var o_options = i_self.options;
		var i_model;

		if (Ext.ClassManager.isCreated(Portfolio.dynapp.util.Service.getModelName(o_options))) {
			Ext.undefine(Portfolio.dynapp.util.Service.getModelName(o_options));
			delete Ext.data.Model.schema.entities[Portfolio.dynapp.util.Service.getModelName(o_options)];
		}
		var o_plugin = o_options.properties.plugin;
		if (o_plugin.convertor) {
			Ext.Array.each(a_fields, function(i_field) {
				if (o_plugin.convertor[i_field.name]) {
					i_field.convertor = function(value) {
						o_plugin.convertor[this.name].call(this, value);
					};
				}
			});
		}
		i_model = Ext.define(Portfolio.dynapp.util.Service.getModelName(o_options), {
			extend: "Ext.data.Model",
			fields: a_fields,
			idProperty: i_self.idProperty,
			proxy: {
				url: Portfolio.dynapp.util.Service.getPath(o_options),
				type: "ajax",
				paramsAsJson: true,
				$configStrict: false,
				reader: {
					$configStrict: false,
					type: "json",
					rootProperty: "rows",
					totalProperty: "totalRows",
					getData: function(o_result) {

						var s_idProp = this.getModel().idProperty;
						var a_records = o_result.rows;
						Ext.Array.each(a_records, function(o_record) {
							if (!o_record[s_idProp]) {
								o_record[s_idProp] = ip2.unique();
							}
						});
						return o_result;
					}
				},
				getMethod: function(request) {
					return "POST";
				}
			}
		});
		var i_store = Ext.create("Ext.data.BufferedStore", {
			model: i_model,
			remoteSort: true,
			autoSync: false,
			pageSize: 100
		});
		i_store.on({
			beforeload: {
				fn: function(store) {

					var i_proxy = store.getProxy();
					if (i_proxy.url != Portfolio.dynapp.util.Service.getPath(i_self.options)) {
						i_proxy.setUrl(Portfolio.dynapp.util.Service.getPath(i_self.options));
					}
					var i_grid = i_self;
					var i_toolbar = i_grid.getFilterBar();
					var o_extraParams = i_proxy.getExtraParams();
					var o_sorters = store.getSorters();

					if (o_sorters.getCount() == 0) {
						delete o_extraParams.where;
						delete o_extraParams.sort;
					}
					delete o_extraParams.columns;

					Ext.apply(o_extraParams, {
						action: "searchRow"
					});

					var a_sort = [];
					var s_sort = "";

					if (i_toolbar) {
						var a_filters = i_toolbar.getFilters();

						o_sorters.loading = true;
						ip2.each(a_filters, function(i_filter) {
							var o_sort = i_filter.getSortInfo();
							var b_found = false;
							ip2.each(o_sorters.items, function(i_sorter) {
								if (i_sorter.getProperty() == o_sort) {
									b_found = true;
								}
							});
							if (!b_found) {
								o_sorters.add(o_sort);
							}
						});

						o_sorters.loading = false;
					}

					ip2.each(o_sorters.items, function(o_sort) {
						var s_sorter = o_sort.getProperty() + " " + o_sort.getDirection();
						a_sort.push(s_sorter);
					});

					s_sort = a_sort.join(", ");
					o_extraParams.sort = s_sort;
				}
			}
		});

		var i_model = i_store.getModel();
		var a_modelFields = i_model.getFields();

		Ext.Array.each(a_modelFields, function(i_field) {
			Ext.Array.each(a_fields, function(o_field) {
				if (o_field.name == i_field.name) {
					i_field.plugin = o_field.plugin || "";
					i_field.protected = o_field.protected || false;
				}
			});
		});

		return i_store;
	},

	createColumns: function(a_fields) {

		var i_self = this;
		var s_id = i_self.store.getModel().idProperty;
		var o_options = i_self.options;
		o_options.properties.plugin.fields = o_options.properties.plugin.fields || {};
		var a_fields = a_fields;
		var b_allowMenu = ip2.isAccessible("app.dynapp.functions.columns.menu");
		var b_draggable = ip2.isAccessible("app.dynapp.functions.columns.arrange");

		var a_columns = [];

		Ext.Array.each(a_fields, function(i_field) {

			if (i_field.name != s_id) {
				var s_type = i_field.datatype;
				var s_headerValue = i_field.title || i_field.text || i_field.header || i_field.name || "";
				var s_header = ip2.i18n(s_headerValue);
				switch (s_type) {
					case "dec":
						s_type = "decimal";
						break;
					case "int":
						s_type = "integer";
						break;
				}
				var o_column = {
					dataIndex: i_field.name,
					text: s_header,
					flex: 1,
					hidden: i_field.hidden,
					datatype: s_type,
					len: i_field.size,
					dec: i_field.prec || 0,
					properties: i_field
				};
				switch (i_field.datatype) {
					case "decimal":
					case "dec":
					case "float":
						o_column.prec = i_field.prec || 0;
						o_column.align = "right";
						o_column.xtype = "numbercolumn";
						break;
					case "int":
					case "integer":
						o_column.align = "right";
						break;
					case "date":
						o_column.align = "center";
						o_column.renderer = function(value, i_cellValues) {
							if (value) {
								var i_date;
								var s_format = Ext.util.Format.dateFormat;
								var i_column = i_cellValues.column;
								var o_properties = i_column.properties || {};

								if (o_properties.fmt) {
									s_format = o_properties.fmt;
								}
								var f_renderer = Ext.util.Format.dateRenderer(s_format);

								if (value instanceof Date) {
									i_date = value;
								}
								else {
									i_date = new Date(value);
								}
								value = f_renderer(i_date);
							}
							return value;
						};
						break;
					case "time":
						o_column.align = "center";
						o_column.renderer = function(value, i_cellValues) {
							if (value) {

								var i_date = new Date();
								var s_dateformat = Ext.util.Format.dateFormat;
								var s_timeformat = "H:i:s";
								var i_column = i_cellValues.column;
								var o_properties = i_column.properties || {};

								var n_year = i_date.getFullYear();
								var n_month = i_date.getMonth() + 1;
								var n_day = i_date.getDate();

								var a_split = value.split(".");

								a_split = Ext.Array.map(a_split, function(s_value) {
									var s_return = s_value;
									var n_value = parseInt(s_value);
									if (n_value) {
										if (n_value < 10 && s_value.length < 2) {
											s_return = "0" + s_value;
										}
									}
									else {
										if (!isNaN(n_value)) {
											if (s_value.length < 2) {
												s_return = "0" + s_value;
											}
										}
										else {
											s_return = "00";
										}
									}
									return s_return;
								});
								value = a_split.join(".");

								if (a_split.length < 3) {
									value = value + ".00";
								}

								var s_date = n_year + "-" + n_month + "-" + n_day;
								var s_value = s_date + "-" + value + ".000000";
								i_date = Ext.Date.parse(s_value, "Y-n-d-H.i.s.u");

								if (o_properties.fmt) {
									s_timeformat = o_properties.fmt;
								}

								var f_renderer = Ext.util.Format.dateRenderer(s_timeformat);
								var value = f_renderer(i_date);
							}
							return value;
						};
						break;
					case "timestamp":
						o_column.align = "center";
						o_column.renderer = function(value) {
							if (value) {
								var i_date;
								if (value instanceof Date) {
									i_date = value;
								}
								else {
									var a_split = value.split("-");
									if (a_split[1].length == 2) {
										i_date = Ext.Date.parse(value, ip2.date2dbDate.parseFormat);
									}
									else {
										i_date = Ext.Date.parse(value, "Y-n-d-H.i.s.u");
									}
								}
								value = Ext.util.Format.date(i_date, Ext.util.Format.dateFormat + " H:i");
							}
							return value;
						};
						break;
					default:
						o_column.renderer = function(value) {
							if (Ext.isObject(value)) {
								value = JSON.stringify(value);
								value = Ext.htmlEncode(value);
							}
							return value;
						};
						break;
				}
				if (o_options.properties.plugin.fields[i_field.name]) {
					var o_field = o_options.properties.plugin.fields[i_field.name];
					if (o_field.xtype) {
						var i_pluginField = Ext.widget(o_field.xtype, o_field);
						if (i_pluginField.renderer) {
							o_column.renderer = function(value) {
								return i_pluginField.renderer(value) || value;
							};
						}
					}
					if (o_field.renderer) {
						o_column.renderer = o_field.renderer;
					}
				}
				try {
					if (i_field.plugin) {
						var o_columnPlugin;
						try {
							eval("o_columnPlugin = " + i_field.plugin);
						}
						catch (err) {
							console.log("eval error check plugin if its valid");
							o_columnPlugin = {};
						}

						if (o_columnPlugin.xtype) {
							var i_pluginField = Ext.widget(o_columnPlugin.xtype, o_columnPlugin);
							if (i_pluginField.renderer) {
								o_column.renderer = function(value) {
									return i_pluginField.renderer(value) || value;
								};
							}
						}
						else if (o_columnPlugin.renderer) {
							o_column.renderer = function(value) {
								return o_columnPlugin.renderer(value) || value;
							};
						}
					}
				}
				catch (err) {}

				Ext.apply({
					menuDisabled: !b_allowMenu,
					draggable: b_draggable
				});
				a_columns.push(o_column);
			}
		});
		return a_columns;
	},

	createToolbars: function() {

		var a_return = [];

		var i_self = this;
		var i_store = i_self.getStore();
		var o_sorters = i_store.getSorters();

		var a_items = i_self.createActionItems();

		var i_toolbar = Ext.widget("toolbar", {
			dock: "top",
			itemId: "actionbar",
			items: a_items,
			removeAdd: function() {

				var i_bar = this;
				var btnAdd = i_bar.items.get("btn-add");
				if (btnAdd) {
					i_bar.remove(btnAdd, true);
					var i_removed = i_bar.items.removeAt(1);
					i_removed.destroy();
				}
			}
		});

		var i_filterbar = Ext.widget("dynapp.toolbar", {
			dock: "top",
			allowMenu: false,
			itemId: "filterbar",
			grid: i_self
		});

		a_return.push(i_toolbar);
		a_return.push(i_filterbar);

		i_self._actionbar = i_toolbar;
		i_self._filterbar = i_filterbar;

		return a_return;
	},

	createActionItems: function() {

		var i_self = this;
		var o_options = i_self.options;
		var i_store = i_self.getStore();
		var o_sorters = i_store.getSorters();

		var a_items = [{
			xtype: "themedbutton",
			iconCls: "refresh",
			handler: function() {
				var i_store = this.up("gridpanel").getStore();
				i_store.clearAndLoad({
					callback: function() {
						i_store.fireEvent("sort", i_store, o_sorters.getRange());
					}
				});
			}
		}];

		a_items.push("-");

		if (ip2.isAccessible("app.dynapp.data.create") ||
			ip2.isAccessible("app.dynapp.data.schema." + o_options.library + ".create") ||
			ip2.isAccessible("app.dynapp.data.schema." + o_options.library + ".table." + o_options.file + ".create")
			) {
			a_items.push({
				xtype: "button",
				text: ip2.i18n({
					en: "Add",
					da: "Tilføj"
				}),
				iconCls: "pf-add",
				handler: "onAdd",
				itemId: "btn-add"
			});
			a_items.push("-");
		}

		a_items.push({
			xtype: "searchfield",
			store: i_store,
			width: 250,
			isFormField: false
		});

		return a_items;
	},

	getFilterBar: function() {

		var i_self = this;
		return i_self._filterbar;
	},

	getActionBar: function() {

		var i_self = this;
		return i_self._actionbar;
	},

	createColumnMenu: function(i_column) {

		var i_self = this;
		var o_options = i_self.options;
		var a_buttons = [];
		var i_controller = i_self.getController();

		if (ip2.isAccessible("app.dynapp.functions.columns.create")) {
			var i_add = Ext.widget("menuitem", {
				itemId: "bntAddColumn",
				iconCls: "pf-add",
				text: ip2.i18n({
					en: "Add",
					da: "Tilføj"
				}),
				handler: function (item) {
					var i_editor = Ext.widget("dynapp.ui.column.editor", {
						title: ip2.i18n({
							en: "New column:",
							da: "Ny kolonne:"
						}),
						action: "new",
						position: "after",
						dataIndex: i_column.dataIndex,
						options: i_self.options || {},
						width: 600,
						height: 450,
						grid: i_self
					});
					i_editor.show();
				}
			});
			a_buttons.push(i_add);
		}

		if (ip2.isAccessible("app.dynapp.functions.columns.update")) {
			var i_edit = Ext.widget("menuitem", {
				itemId: "bntEditColumn",
				iconCls: "pf-edit",
				text: ip2.i18n({
					en: "Edit",
					da: "Rediger"
				}),
				handler: function (item) {

					var i_store = i_self.getStore();
					var i_model = i_column.ownerCt.grid.store.getModel();
					var i_field = i_model.getField(i_column.dataIndex);
					var o_config = Ext.apply({}, i_column.initialConfig);
					o_config.text = i_field.header || i_field.name;

					var i_editor = Ext.widget("dynapp.ui.column.editor", {
						title: ip2.i18n({
							en: "Edit:",
							da: "Rediger:"
						}) + " " + i_column.text,
						action: "edit",
						position: "after",
						dataIndex: i_column.dataIndex,
						options: i_self.options || {},
						meta: o_config,
						width: 600,
						height: 450,
						grid: i_self
					});
					i_editor.show();
				}
			});
			a_buttons.push(i_edit);
		}

		if (ip2.isAccessible("app.dynapp.functions.columns.delete")) {
			var i_delete = Ext.widget("menuitem", {
				itemId: "bntDeleteColumn",
				iconCls: "pf-delete",
				text: ip2.i18n({
					da: "Slet",
					en: "Delete"
				}),
				handler: function (item) {

					ip2.messageBox({
						icon: Ext.MessageBox.WARNING,
						title: ip2.i18n({
							da: "Slet..?",
							en: "Delete..?"
						}),
						closable: true,
						message: ip2.i18n({
							da: "Vil du slette denne række?",
							en: "Do you want to delete this record?"
						}),
						message: ip2.i18n({
							da: "Vil du slette kolonnen " + i_column.text + " ..?",
							en: "Do you want to delete the column " + i_column.text + " ..?"
						}),
						yesFn: function () {
							var o_data = {
								action: "deleteColumn",
								name: i_column.dataIndex
							};
							var s_msg = ip2.i18n({
								da: "Sletter...",
								en: "Deleting..."
							});
							i_self.setLoading(s_msg);
							Ext.Ajax.request({
								url: Portfolio.dynapp.util.Service.getPath(o_options),
								method: "POST",
								jsonData: o_data,
								success: function (response, request) {
									i_self.setLoading(false);
									var result = JSON.parse(response.responseText);
									if (result.success != undefined && !result.success) {
										ip2.messageBox({
											icon: Ext.MessageBox.ERROR,
											title: ip2.i18n({
												da: "Fejl",
												en: "Error"
											}),
											closable: true,
											message: result.message,
											yesText: ip2.i18n({
												da: "OK",
												en: "OK"
											})
										});
									}
									else {
										Portfolio.dynapp.util.Service.getMeta(i_self.options, function(o_meta) {
											var i_grid = i_self;
											i_self.options.properties = o_meta.properties;
											i_grid.doApply(i_self.options, o_meta.fields);
										});
									}
								}
							});
						},
						yesText: ip2.i18n({
							da: "Ja",
							en: "Yes"
						}),
						noText: ip2.i18n({
							da: "Nej",
							en: "No"
						})
					});
				}
			});

			a_buttons.push(i_delete);
		}

		return a_buttons;
	},

	doApply: function(o_options, a_fields) {

		var i_self = this;
		var i_store = i_self.getStore();
		var i_model = i_store.getModel();
		var s_name = i_model.getName();
		if (!a_fields) {
			a_fields = i_model.getFields();
		}

		var i_newStore = i_self.createStore(a_fields);
		var a_columns = i_self.createColumns(a_fields);

		i_self.reconfigure(i_newStore, a_columns);
		i_self.fields = a_fields;
		i_newStore.load();
	}
});
