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

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

	onSendData: function(o_config, o_data) {

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

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

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

		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);

							if (o_inputData.cmd) {

								i_controller.onPCO(o_inputData);
								i_controller.doKeyEvent("ENTER");
							}
						}
					});
				}
			});
		}
	},

	onWheel: function(i_event) {

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

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

		var a_metaFields = o_inputData.metaFields || [];

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

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

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

	onDblClick: function(i_event) {

		var i_controller = this;
		var i_view = i_controller.getView();
		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();

		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.show();
		}

		i_view.setCurrentPosition(o_position);
		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_viewLocal = i_view.getLocalXY();
		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: IceCap.util.Handler.getX(o_position.col),
				y: IceCap.util.Handler.getY(o_position.lin),
				width: IceCap.util.Handler.getColSize(),
				height: 1
			});

			var b_intersect = false;

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

				var o_bound = i_field.el.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(true, 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;

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

		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;

			Ext.Array.each(a_fields, function(i_field) {
				if (i_field.lin === n_next && i_field.col === n_col) {
					b_found = true;
					n_tabIndex = i_field.getTabIndex();
					i_field.focus(true, 10);
					return false;
				}
			});
		}

		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;
				}
			}

			Ext.Array.each(a_fields, function(i_field) {
				if (i_field.getTabIndex() === n_tabIndex) {
					i_field.focus(true, 10);
					return false;
				}
			});
		}

		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;
			}
		}

		Ext.Array.each(a_fields, function(i_field) {
			if (i_field.getTabIndex() === n_tabIndex) {
				i_field.focus(true, 10);
				return false;
			}
		});

		i_view.setCurrentTabIndex(n_tabIndex);
	},

	doKeyEvent: function(s_value, i_event) {

		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.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()) {

				var s_id = "ses2.win." + i_currentField.emuId;

				o_data = Ext.apply(o_data, {
					csrCol: o_position.col > 1 ? o_position.col : i_currentField.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);
	},

	doRequire: function(a_require, f_callback) {

		f_callback = f_callback || Ext.emptyFn;

		var 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:
				i_view.fireEvent("onAddWebContainer", o_inputData);
				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();
	}
});
