Ext.define("IceCap.controller.Main", {
	extend: "Ext.app.ViewController",

	alias: "controller.icecap.view.main",

	listen: {
		global: {
			beforelogout: {
				fn: function() {

					var i_controller = this;
					i_controller.onBeforeLogout();
				}
			}
		}
	},

	onAfterRender: function(i_panel) {

		var i_self = i_panel;

		i_self.addKeyEvents();

		var i_content = i_self.getContent();
		var i_main = i_self.getMain();

		var o_inputData = i_self.getInputData() || {};

		if (o_inputData.window) {
			i_self.doCreateFromData(o_inputData);
		}

		if (i_content) {

			var a_fields = i_content.query("field[focusable]");

			var i_found = Ext.Array.findBy(a_fields, function (i_field) {
				return i_field.getTabIndex() == i_self.getNeedFocus();
			});

			if (i_found) {
				i_found.focus(false, 10);
			}
			else {
				i_self.setCurrentPosition({
					col: o_inputData.csrCol,
					lin: o_inputData.csrLin
				});

				i_main.focus(true, 10);
			}
		}
	},

	onSendData: function(o_config, o_data) {

		var i_controller = this;
		var o_saved = Ext.clone(o_config);
		var i_view = i_controller.getView();
		var s_session = i_view.getSessionValue();

		var o_options = i_view.getOptions();

		o_data = Ext.apply(o_data, {
			i18nLearning: false
		});

		Ext.apply(o_config, {
			session: s_session,
		});

		Ext.apply(o_config, o_options);

		if (!i_view.getWorking()) {
			i_view.setWorking(true);
			i_view.doTimer();
			IceCap.util.Handler.getData(o_config, o_data, function(o_inputData) {

				if (o_inputData.statusUpdate) {

					i_view.setWorking(false);
					i_view.updateMessage(o_inputData);
					if (o_inputData.status > -1) {
						i_view.doCreateFromData(o_inputData);
					}
					i_controller.onSendData(o_saved, o_data);
				}
				else {

					i_view.setLoading(false);
					i_view.cancelTimer();

					var f_callback = i_view.getResponseCallBack() || Ext.emptyFn;

					if (f_callback != Ext.emptyFn) {

						f_callback(o_inputData);
					}

					var o_plugin = o_inputData.plugin || Ext.apply({}, {
						require: []
					});

					var a_require = o_plugin.require || [];
					var s_run = o_plugin.run || "";

					i_controller.doRequire(a_require, function() {

						if (s_run) {
							eval(s_run);
						}

						if (o_inputData.close) {
							i_view.close();
						}
						else {

							i_view.setWorking(false);
							i_view.doCreateFromData(o_inputData);

							i_view.fireEvent("stateupdate", i_view);
						}
					});
				}
			});
		}
	},

	onWheel: function(i_event) {

		var i_controller = this;
		var i_view = i_controller.getView();

		var b_hasGrid = i_view.query("gridpanel").length > 0;
		var b_mappanel = i_view.query("icecap-gmappanel").length > 0;

		var n_delta = i_event.getWheelDelta();
		var s_event = "";

		if (n_delta > 0) {
			s_event = "ROLLDOWN";
		}
		else {
			s_event = "ROLLUP";
		}

		if (!b_hasGrid && !b_mappanel && !i_event.ctrlKey){
			i_controller.doKeyEvent(s_event);
		}
	},

	onDblClick: function(i_event) {

		var i_controller = this;
		var i_view = i_controller.getView();
		var o_inputData = i_view.getInputData();
		var i_cursor = i_view.getCursor();

		var b_fireEvent = i_view.getEnterOnDblClick();

		if (b_fireEvent) {

			var i_body = i_view.body;
			var a_local = i_body.getOffsetsTo(window);

			var a_metaFields = o_inputData.metaFields || [];

			var o_click = Ext.apply({
				x: i_event.pageX - a_local[0],
				y: i_event.pageY - a_local[1]
			});

			var o_position = IceCap.util.Handler.toColAndLine(o_click);

			var i_currentField = i_view.getCurrentField();

			if (i_currentField) {
				o_position = Ext.apply(o_position, {
					lin: i_currentField.lin,
					col: i_currentField.col
				});
				if (i_currentField.inputEl && i_currentField.getValue()) {
					o_position = IceCap.util.Handler.toColAndLine(o_click);
				}
			}
			else {

				i_cursor.moveCursor(o_position);
				i_cursor[a_metaFields.length === 0 ? "show" : "hide" ]();
			}

			i_view.setCurrentPosition(o_position);

			if (a_metaFields.length === 0) {
				i_controller.doKeyEvent("ENTER");
			}
		}
	},

	onClick: function(i_event) {

		var i_controller = this;
		var i_view = i_controller.getView();
		var o_inputData = i_view.getInputData();
		var i_cursor = i_view.getCursor();

		var i_body = i_view.body;
		var a_local = i_body.getOffsetsTo(window);

		var o_click = Ext.apply({
			x: i_event.pageX - a_local[0],
			y: i_event.pageY - a_local[1]
		});

		var o_position = IceCap.util.Handler.toColAndLine(o_click);

		var i_currentField = i_view.getCurrentField();

		var a_metaFields = o_inputData.metaFields || [];

		if (i_currentField) {
			o_position = Ext.apply(o_position, {
				lin: i_currentField.lin,
				col: i_currentField.col
			});
			if (i_currentField.inputEl && i_currentField.getValue()) {
				o_position = IceCap.util.Handler.toColAndLine(o_click);
			}
		}
		else {

			var a_inputs = i_view.query("field[focusable]");

			var o_box = Ext.apply({
				x: o_click.x,
				y: o_click.y,
				width: IceCap.util.Handler.getColSize(),
				height: 2
			});

			var b_intersect = false;

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

				var i_element = i_field.getEl();

				if (i_element) {
					var o_bound = i_element.dom.getBoundingClientRect();

					var o_rect = Ext.apply({}, {
						x: i_field.getLocalX(),
						y: i_field.getLocalY(),
						width: o_bound.width,
						height: o_bound.height
					});

					if (!Ext.draw.Draw.isBBoxIntersect(o_box, o_rect)) {
						b_intersect = true;
						i_field.focus(false, 10);
						return false;
					}
				}
			});

			if (!b_intersect) {
				i_cursor.moveCursor(o_position);

				i_cursor[a_metaFields.length === 0 ? "show" : "hide" ]();
			}
		}

		i_view.setCurrentPosition(o_position);
	},

	doArrowKeys: function(n_direction) {

		var i_controller = this;
		var i_view = i_controller.getView();
		var a_fields = i_view.query("[focusable]");
		var n_tabIndex = i_view.getCurrentTabIndex();
		var n_lastTabIndex = i_view.getLastTabIndex();
		var n_part = n_direction ? 1 : -1;

		var i_lastFocus;
		var i_nextFocus;

		i_lastFocus = Ext.Array.findBy(a_fields, function (i_field) {
			return i_field.getTabIndex() == n_tabIndex;
		});

		var b_found = false;

		if (i_lastFocus) {

			var n_lin = i_lastFocus.lin;
			var n_col = i_lastFocus.col;
			var n_next = n_lin + n_part;

			i_nextFocus = Ext.Array.findBy(a_fields, function(i_field) {
				return i_field.lin === n_next && i_field.col === n_col;
			});

			if (i_nextFocus) {
				b_found = true;
				n_tabIndex = i_nextFocus.getTabIndex();
				i_nextFocus.focus(false, 10);
			}
		}

		if (!b_found) {

			n_tabIndex = i_view.getCurrentTabIndex() + n_part;

			if (n_direction) {
				if (n_tabIndex > n_lastTabIndex) {
					n_tabIndex = 1;
				}
			}
			else {
				if (n_tabIndex < 1) {
					n_tabIndex = n_lastTabIndex;
				}
			}

			i_nextFocus = Ext.Array.findBy(a_fields, function (i_field) {
				return i_field.getTabIndex() == n_tabIndex;
			});

			if (i_nextFocus) {
				i_nextFocus.focus(false, 10);
			}
		}

		i_view.setCurrentTabIndex(n_tabIndex);
	},

	doTabKey: function(n_direction) {

		var i_controller = this;
		var i_view = i_controller.getView();
		var a_fields = i_view.query("[focusable]");
		var n_tabIndex = i_view.getCurrentTabIndex();
		var n_lastTabIndex = i_view.getLastTabIndex();
		var n_part = n_direction ? 1 : -1;

		n_tabIndex = i_view.getCurrentTabIndex() + n_part;

		if (n_direction) {
			if (n_tabIndex > n_lastTabIndex) {
				n_tabIndex = 1;
			}
		}
		else {
			if (n_tabIndex < 1) {
				n_tabIndex = n_lastTabIndex;
			}
		}

		var i_found =Ext.Array.findBy(a_fields, function(i_field) {
			return i_field.getTabIndex() == n_tabIndex;
		});

		if (i_found) {
			i_found.focus(false, 10);
		}

		i_view.setCurrentTabIndex(n_tabIndex);
	},

	doKeyEvent: function(s_value) {

		var i_controller = this;
		var i_view = i_controller.getView();

		var i_currentField = i_view.getCurrentField();
		var o_position = i_view.getCurrentPosition();

		var o_data = {
			key: s_value
		};

		var i_content = i_view.getContent();
		var i_form = i_content.getForm();
		var i_collectionField = i_form.getFields();
		var o_values = {};

		Ext.Array.each(i_collectionField.items, function(i_field) {
			if (i_field.isDirty()) {
				var value = i_field.getSubmitValue ? i_field.getSubmitValue() : i_field.getValue();
				o_values[i_field.itemId || i_field.initialConfig.id || i_field.name] = value;
			}
		});

		Ext.Object.each(o_values, function(s_key, value) {
			var s_id = "ses2.win." + s_key;
			o_data[s_id] = value;
		});

		if (i_currentField) {

			o_data = Ext.apply(o_data, {
				csrLin: i_currentField.lin,
				csrCol: i_currentField.col
			});

			if (i_currentField.inputEl && i_currentField.getValue()) {
				o_data = Ext.apply(o_data, {
					csrCol: o_position.col
				});
			}
		}
		else {

			o_data = Ext.apply(o_data, {
				csrLin: o_position.lin,
				csrCol: o_position.col
			});
		}

		var f_callback = i_view.getRequestCallBack() || Ext.emptyFn;

		if (f_callback != Ext.emptyFn) {

			f_callback(o_data);
		}

		i_controller.onSendData({
			func: ""
		}, o_data);
	},

	doFKey: function(s_value) {

		var i_controller = this;

		i_controller.doKeyEvent(s_value);
	},

	doRequire: function(a_require, f_callback) {

		f_callback = f_callback || Ext.emptyFn;

		a_require = a_require || [];

		if (a_require.length > 0) {

			var a_external = Ext.Array.filter(Ext.Array.map(a_require, function(s_value) {
				if (s_value.indexOf("/") > -1) {
					return s_value;
				}
			}), function(value) {
				return value;
			});

			var a_internal = Ext.Array.filter(Ext.Array.map(a_require, function(s_value) {
				if (s_value.indexOf("/") < 0) {
					return s_value;
				}
			}), function(value) {
				return value;
			});

			if (a_external.length > 0) {
				Ext.Loader.loadScriptsSync(a_external);
			}

			if (a_internal.length > 0) {
				Ext.syncRequire(a_internal);
			}
		}

		f_callback();
	},

	onPCO: function(o_inputData) {

		var i_controller = this;
		var i_view = i_controller.getView();
		var i_keyMap = i_view.getKeyMap();

		switch (o_inputData.cmdAct) {

			case 0:
				window.open(o_inputData.cmd, o_inputData.cmdTitle, "");
				break;
			case 1:
				var i_window = Ext.widget("window", {
					title: o_inputData.cmdTitle,
					layout: "fit",
					collapsible: true,
					items: [
						{
							xtype: "icecap-webcontainer",
							src: o_inputData.cmd
						}
					],
					width: window.outerWidth * 0.9,
					height: window.outerHeight * 0.9
				});

				i_window.show();
				break;
			default:

				i_keyMap.disable();

				var i_store = Ext.create('Ext.data.Store', {
					proxy: {
						type: 'jsonp',
						timeout: "86400000",
						url: o_inputData.cmd,
						nocache: false,
						callback: function(o_result) {
							i_keyMap.enable();
						},
						listeners: {
							exception: {
								fn: function(i_proxy, i_request, i_operation) {
									i_controller.onPCOError(i_operation.error, function() {
										i_keyMap.enable();
										i_view.findFocus();
									});
								}
							}
						}
					}
				});

				i_store.load();
				break;
		}
	},

	onPCOError: function(s_error, f_callback) {

		f_callback = f_callback || Ext.emptyFn;

		var i_template = new Ext.XTemplate(
			"<div class=\"iceCap-msg\">",
				"<h3>{header}</h3>",
				"<ul>",
					"<li>{message}</li>",
				"</ul>",
			"</div>"
		);

		var i_window = Ext.widget("window", {
			title: "PCO Error",
			width: 800,
			modal: true,
			closable: false,
			html: i_template.apply({
				header: "Error",
				message: s_error
			}),
			bodyPadding: 5,
			buttons: [{
				text: "Ok",
				tabIndex: 1,
				focusable: true,
				listeners: {
					afterrender: {
						fn: function(i_button) {
							setTimeout(function() {
								i_button.focus(false, 10);
							});
						}
					}
				},
				handler: function() {
					i_window.close();
					f_callback();
				}
			}]
		});

		i_window.show();
	},

	onDestroy: function(i_panel) {

		var s_session = i_panel.getSessionValue();

		IceCap.util.Handler.removeSession(s_session);

		Ext.Ajax.request({
			method: "POST",
			url: IceCap.util.Handler.getPath({
				session: s_session,
				func: "",
				close: "on"

			})
		});
	},

	onBeforeDestroy: function() {

		var i_controller = this;
		var i_view = i_controller.getView();

		var i_window = i_view.up("window");

		if (i_window) {
			i_window.close();
		}
	},

	onActivated: function() {

		var i_controller = this;
		var i_view = i_controller.getView();
		var i_content = i_view.getContent();
		var i_main = i_view.getMain();

		var o_currentPosition = i_view.getCurrentPosition();

		var a_inputs = i_view.query("field[focusable]");

		var o_box = Ext.apply({
			x: IceCap.util.Handler.getX(o_currentPosition.col),
			y: IceCap.util.Handler.getY(o_currentPosition.lin),
			width: IceCap.util.Handler.getColSize(),
			height: 2
		});

		var b_intersect = false;

		var o_inputData = i_view.getInputData() || {
			metaFields: []
		};

		var a_metaFields = o_inputData.metaFields || [];

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

			var i_element = i_field.getEl();

			if (i_element) {
				var o_bound = i_element.dom.getBoundingClientRect();

				var o_rect = Ext.apply({}, {
					x: i_field.getLocalX(),
					y: i_field.getLocalY(),
					width: o_bound.width,
					height: o_bound.height
				});

				if (!Ext.draw.Draw.isBBoxIntersect(o_box, o_rect)) {
					b_intersect = true;
					i_field.focus(false, 10);
					return false;
				}
			}
		});

		if (!b_intersect) {
			var i_cursor = i_view.getCursor();

			if (i_cursor) {

				i_cursor.moveCursor(o_currentPosition);

				i_cursor[a_metaFields.length === 0 ? "show" : "hide" ]();
			}

			if (i_main) {
				setTimeout(function() {
					i_main.focus(true, 10);
				}, 10);
			}
		}
	},

	onApplicationClose: function() {

		var i_controller = this;
		var i_view = i_controller.getView();

		i_view.close();
	},

	onBeforeLogout: function() {

		var i_controller = this;
		var i_view = i_controller.getView();

		i_view.close();
	}
});
