Ext.define("IceCap.ux.grid.editor.Main", {

	extend: "Ext.grid.Panel",

	alias: [
		"widget.iceCapEditorGrid",
		"widget.iceCapGrid"
	],

	requires: [
		"IceCap.ux.grid.editor.Controller"
	],

	config: {
		gridConfig: null,
		toolbar: null,
		pagingToolbar: null,
		keys: [],
		extraToolbarButtons: [],
		rowMenu: null,
		defaultOption: "ENTER",
		needFocus: false,
		focusTo: 0,
		theme: ""
	},

	flex: 1,

	listeners: {
		afterrender: {
			fn: function(i_panel) {

				var i_self = this;
				var i_store = i_self.getStore();
				var i_view = i_self.getView();
				var a_records = i_store.getRange()

				Ext.suspendLayouts();

				i_self.getView().setHeight(a_records.length * IceCap.util.Handler.getLineHeight());

				Ext.resumeLayouts(true);

				i_self.setTabIndex(i_self.initialConfig.tabIndex || -1);

				var i_navigationModel = i_self.getNavigationModel();
				var i_keyNav = i_navigationModel.keyNav;

				if (Ext.isArray(i_keyNav)) {
					i_keyNav = i_keyNav[0];
				}
				
				var i_map = i_keyNav.map;

				var i_tabBinding = Ext.Array.findBy(i_map.bindings, function(i_binding) {
					return i_binding.key == Ext.event.Event.TAB;
				});

				i_map.removeBinding(i_tabBinding);

				var i_enterBinding = Ext.Array.findBy(i_map.bindings, function(i_binding) {
					return i_binding.key == Ext.event.Event.ENTER;
				});

				i_map.removeBinding(i_enterBinding);

				i_keyNav.defaultEventAction = "";
				i_map.ignoreInputFields = false;

				i_map.addBinding({
					ctrl: false,
					shift: false,
					alt: false,
					key: Ext.event.Event.TAB,
					handler: function(n_key, i_event) {

						var i_selectionModel = i_self.getSelectionModel();
						var i_current = i_selectionModel.getCurrentPosition();

						var i_store = i_self.getStore();

						if (i_current.rowIdx != (i_store.getTotalCount() - 1)) {
							i_event.stopEvent();
						}

						i_self.getSelectionModel().selectNext(false);
					}
				});

				i_map.addBinding({
					ctrl: false,
					shift: true,
					alt: false,
					key: Ext.event.Event.TAB,
					handler: function(n_key, i_event) {

						var i_selectionModel = i_self.getSelectionModel();
						var i_current = i_selectionModel.getCurrentPosition();

						if (i_current.rowIdx > 0) {
							i_event.stopEvent();
						}
						i_selectionModel.selectPrevious(false);
					}
				});

				i_map.addBinding({
					key: Ext.event.Event.ENTER,
					handler: function(n_key, i_event) {

						var i_selectionModel = i_self.getSelectionModel();
						var i_current = i_selectionModel.getCurrentPosition();

						i_event.stopEvent();

						if (i_current) {

							var i_record = i_current.record;

							var s_id = i_record.getId().split("g.").pop();

							var s_defaultOption = i_self.getDefaultOption();

							var o_data = {
								field: s_id,
								option: s_defaultOption,
								col: Ext.Number.from(i_record.get("col"), 0),
								lin: Ext.Number.from(i_record.get("lin"), 0)
							};

							i_self.fireEvent("fieldoption", [o_data]);
						}
					}
				});

				if (i_self.getNeedFocus()) {

					var i_view = i_self.getView();
					i_view.select(i_self.getFocusTo() - 1);
				}
			}
		},
		itemcontextmenu: {
			fn: function(i_view, i_record, i_html, n_index, i_event) {

				var i_self = this;

				i_event.stopEvent();

				var a_position = i_event.getXY();

				var i_menu = i_self.getRowMenu();

				i_menu.showAt(a_position);
			}
		},
		itemdblclick: {
			fn: function (i_view, i_record, i_item, n_index, i_event, o_options) {

				var i_self = this;

				i_event.stopEvent();

				var s_id = i_record.getId().split("g.").pop();

				var s_defaultOption = i_self.getDefaultOption();

				var o_data = {
					field: s_id,
					option: s_defaultOption,
					col: Ext.Number.from(i_record.get("col"), 0),
					lin: Ext.Number.from(i_record.get("lin"), 0)
				};

				i_self.fireEvent("fieldoption", [o_data]);
			}
		},
		select: {
			fn: function(i_selectionModel, i_record) {

				var i_self = this;
				var o_gridConfig = i_self.getGridConfig();
				var i_columnManager = i_self.getColumnManager();

				if (o_gridConfig.showOption) {

					var i_column = i_columnManager.getHeaderByDataIndex(o_gridConfig.optionDataIndex);

					if (i_column) {
						var i_textfield = i_column.getWidget(i_record);
						i_textfield.focus(10, true);
					}
				}
			}
		}
	},

	initComponent: function() {

		var i_self = this;

		var o_viewConfig = {
			focus: function () {

				var i_self = this;
				i_self.callOverridden(arguments);

				var i_selectionModel = i_self.getSelectionModel();
				var i_current = i_selectionModel.getCurrentPosition();

				if (!i_current) {
					i_self.select(0, false);
				}
				else {
					var i_record = i_current.record;

					i_selectionModel.deselectAll(false);
					i_self.select(i_record);
				}
			},
			getRowClass: function () {
				var i_view = this;
				var i_grid = i_view.grid;
				return "iceCap-row-" + i_grid.getTheme();
			},
			cls: "iceCap-row-" + i_self.getTheme()
		};

		Ext.apply(i_self, {
			viewConfig: o_viewConfig
		});

		var i_store = i_self.createStore();
		var a_columns = i_self.createColumns();

		var o_config = i_self.getGridConfig();

		var i_selectionModel = Ext.create("Ext.selection.RowModel", {
			mode: "MULTI"
		});

		Ext.apply(i_self, {
			store: i_store,
			columns: a_columns,
			enableColumnMove: o_config.enableColumnMove || false,
			selModel: i_selectionModel
		});

		i_self.callParent(arguments);

		if (o_config.showToolbar) {
			i_self.createToolbar();
		}

		i_self.addDocked(i_self.createPagingToolbar());

		i_self.createRowMenu();
	},

	createStore: function() {

		var i_self = this;

		var o_config = i_self.getGridConfig();

		var o_store = o_config.store;
		var o_meta = o_store.metaData;

		var i_store = Ext.create("Ext.data.Store", {
			fields: o_meta.fields,
			autoload: false,
			proxy: {
				type: "memory",
				reader: {
					type: "json"
				}
			},
			data: o_store.rows
		});

		return i_store;
	},

	createColumns: function() {

		var i_self = this;

		var o_config = i_self.getGridConfig();

		var a_return = [];

		var a_columns = o_config.header || [];

		var a_quick = o_config.quickOption || [];

		Ext.Array.each(a_columns, function(o_config, n_index) {

			var o_column = Ext.clone(o_config);

			if (Ext.isFunction(o_column.renderer) &&
					o_column.renderer == (window.renderOptionField ||
					o_column.renderer == window.renderField)
				) {

				var o_option = Ext.Array.findBy(a_quick, function(o_values) {
					return o_values.dataIndex == o_column.dataIndex;
				}) || {};

				Ext.apply(o_column, {
					xtype: "widgetcolumn",
					widget: {
						xtype: "iField",
						metaData: {
							len: o_option.len || 10,
							ffw: o_option.ffw,
							fieldStyle: {
								"text-align": "right"
							}
						},
						listeners: {
							fieldfocus: {
								fn: function(i_field) {

									var i_store = i_self.getStore();

									var i_widgetRecord = i_field.getWidgetRecord();

									var n_index = i_store.find(i_widgetRecord.idProperty, i_widgetRecord.get(i_widgetRecord.idProperty));

									if (n_index > -1) {
										var i_view = i_self.view;
										i_view.select(i_widgetRecord);
									}
								}
							},
							specialKey: {
								fn: function(i_field, i_event) {

									var i_store = i_self.getStore();

									var a_range = i_store.getRange();

									var a_options = [];

									var i_column = i_field.getWidgetColumn();

									Ext.Array.each(a_range, function(i_record) {

										var s_id = i_record.getId().split("g.").pop();

										var i_widget = i_column.getWidget(i_record);

										if (i_widget.getValue()) {

											var o_data = {
												field: s_id,
												option: i_widget.getValue(),
												col: Ext.Number.from(i_record.get("col"), 0),
												lin: Ext.Number.from(i_record.get("lin"), 0)
											};

											a_options.push(o_data);
										}
									});

									i_self.fireEvent("fieldoption", a_options);
								}
							}
						}
					}
				});

				delete o_column.renderer;
			}
			else {
				o_column.renderer = function (value, i_meta, i_record, n_row, n_col) {

					var atr = i_record.get("atr" + (n_col + 1));
					i_meta.tdCls = ["iceCap-output", atr || 20, i_self.getTheme()].filter(Boolean).join("-");

					return value;
				};
			}

			o_column.width = o_column.width || null;
			o_column.flex = o_column.width ? null : 1;

			a_return.push(o_column);
		});

		return a_return;
	},

	createToolbar: function() {

		var i_self = this;

		var o_config = i_self.getGridConfig();

		var a_bottom = Ext.Array.from(o_config.bottomKeys);

		var a_keys = i_self.getKeys();

		var a_extraButtons = o_config.extraToolbarButtons || [];

		var a_omited = Ext.Array.filter(a_bottom, function(o_key) {
			return o_key.key;
		});

		var a_filtered = Ext.Array.filter(a_keys, function(o_key) {

			var i_found = Ext.Array.findBy(a_omited, function(o_filtered) {
				return o_key.id == o_filtered.key;
			});

			return !i_found;
		});

		var a_buttons = i_self.createButtons(a_filtered);

		if (a_extraButtons.length > 0) {

			a_extra = Ext.Array.filter(a_extraButtons, function(o_key) {

				var i_found = Ext.Array.findBy(a_omited, function(o_filtered) {
					return o_key.id == o_filtered.key;
				});

				return !i_found;
			});

			var a_return = i_self.createButtons(a_extra);

			a_buttons = a_buttons.concat(a_return);
		}

		if (a_buttons.length > 0) {
			var i_toolbar = Ext.widget("toolbar", {
				dock: "top",
				items: a_buttons
			});

			i_self.setToolbar(i_toolbar);

			i_self.addDocked(i_toolbar);
		}
	},

	createPagingToolbar: function() {

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

		var i_toolbar = Ext.widget("toolbar", {
			dock: "bottom",
			items: [
				{
					xtype: "button",
					iconCls: "icecap-icon-page-prev",
					handler: function() {

						i_self.fireEvent("key", "ROLLDOWN");
					}
				},
				'->',
				{
					xtype: "button",
					iconCls: "icecap-icon-page-next",
					handler: function() {

						i_self.fireEvent("key", "ROLLUP");
					}
				}
			]
		});

		i_self.setPagingToolbar(i_toolbar);

		return i_toolbar;
	},

	createRowMenu: function() {

		var i_self = this;
		var o_config = i_self.getGridConfig();

		var a_items = [];

		var s_options = o_config.defaultOption || "";

		var a_defaultsOptions = s_options.split(",");

		var n_position = 99;

		var s_defaultOption = "";

		Ext.Array.each(o_config.menu, function(o_item) {

			var i_item = Ext.widget("menuitem", {
				text: o_item.text + " ( " + o_item.id + " )",
				option: o_item.id,
				breakout: o_item.breakout || false,
				icon: "/system/snapOnIcon.aspx.png?keyword=" + escape(o_item.text) + "&default=folder.png&insertRoot=true",
				handler: function(i_menuitem) {

					var a_selected = i_self.getSelection();

					var f_breakout = eval(i_menuitem.breakout);

					if (!i_menuitem.breakout) {

						var a_options = [];

						Ext.Array.each(a_selected, function(i_record) {

							var s_id = i_record.getId().split("g.").pop();

							var o_data = {
								field: s_id,
								option: i_menuitem.option,
								col: Ext.Number.from(i_record.get("col"), 0),
								lin: Ext.Number.from(i_record.get("lin"), 0)
							};

							a_options.push(o_data);
						});

						i_self.fireEvent("fieldoption", a_options);
					}
					else {
						if (Ext.isFunction(f_breakout)) {

							Ext.Array.each(a_selected, function(i_record) {
								f_breakout(i_record.getData());
							});
						}
					}
				}
			});

			var n_index = a_defaultsOptions.indexOf(o_item.id);

			if (n_index > -1) {
				if (n_index < n_position) {
					n_position = n_index;
					s_defaultOption = o_item.id;
				}
			}

			a_items.push(i_item);
		});

		var i_found = Ext.Array.findBy(a_items, function(i_item) {
			return i_item.option == s_defaultOption;
		});

		if (i_found) {
			i_found.text = "<strong>" + i_found.text + "</strong>";
		}

		var i_menu = Ext.widget("menu", {
			items: a_items
		});

		i_self.setRowMenu(i_menu);
		i_self.setDefaultOption(s_defaultOption);
	},

	createButtons: function(a_config) {

		var i_self = this;

		var a_buttons = [];

		Ext.Array.each(a_config, function(o_config) {

			var o_key = {
				xtype: "button",
				key: o_config.id ? o_config.id : o_config.key,
				text: o_config.text,
				icon: "/system/snapOnIcon.aspx.png?keyword=" + escape(o_config.text) + "&default=folder.png&insertRoot=true",
				iconCls: o_config.iconCls,
				handler: function(i_button) {
					i_self.fireEvent("key", i_button.key);
				}
			};

			a_buttons.push(o_key);
		});

		return a_buttons;
	}

}, function() {

	Ext.apply(window, {
		onRowRightClick: Ext.emptyFn,
		renderField: function (val, meta, rec, row, col) {
			var atr = rec.data["atr" + (col + 1)],
			io = rec.data["io" + (col + 1)];

			if (io != "b" && io != "i") {
				return val;
			}

			var html = "<div id=\"" + Ext.id() + "." + rec.id + ".c" + (col + 1) + "\"";
			return html + "></div>";
		},
		renderOptionField: function(value, i_meta, i_record, n_row, n_col) {

			var s_attr = i_record.get("atr" + (n_col + 1));
			var s_html = "";

			s_html = "<div id=\"win-opt-" + n_row + "\""  ;

			if (!Ext.isEmpty(s_attr)) {
				s_html += " class=\"iceCap-output-" + s_attr + "\"";
			}

			s_html += "></div>";

			return s_html;
		},
		renderQuickKeyField: function(val, meta, rec, row, col) {
			var atr = rec.data['atr' + (col + 1)],
			html;

			if (rec.id.indexOf('q.') > -1) {
				html = '<div id=' + Ext.id() + '.qCol.' + col + '"';
				if (!Ext.isEmpty(atr)) {
					html += ' class="iceCap-output-' + atr + '"';
				}

				html += '></div>';
			}
			else if (!Ext.isEmpty(atr)) {
				html = '<div class="iceCap-output-' + atr + '">' + val + '</div>';
			}
			else {
				html = val;
			}
			return html;
		}
	});
});
