Ext.define("IceCap.view.Emulator", {

	xtype: "icecap-emulator",

	extend: "Ext.panel.Panel",

	layout: "fit",

	stateful: true,

	stateId: "icecap-emulator",

	requires: [
		"IceCap.component.TabCloseMenu",
		"IceCap.controller.Emulator",
	],

	config: {
		tabArea: null,
		toolBar: null,
		theme: "",
		scale: 14,
		options: {}
	},

	controller: "icecap.controller.emulator",

	stateEvents: [
		"add",
		"remove",
		"tabchange",
		"stateupdate"
	],

	initComponent: function() {

		var i_self = this;

		i_self.callParent(arguments);
		i_self.add(i_self.createTabArea());

		i_self.mon(IceCap.app, "stateReady", function() {

			var i_controller = i_self.getController();

			var o_state = Ext.state.Manager.get("icecap-emulator") || {
				tabs: []
			};

			if (o_state.tabs.length === 0) {
				i_controller.onNewSession();
			}
		});

		i_self.mon(IceCap.app, "toTab", function (i_item, b_active) {

			Ext.suspendLayouts();

			i_item.setResizeMode(1);

			var i_tabpanel = i_self.getTabArea();

			var i_window = i_item.getActiveWindow();

			var i_active = i_tabpanel.add(i_item);

			Ext.resumeLayouts(true);

			if (b_active) {
				i_window.show();
				i_window.center();
			}

			i_tabpanel.setActiveItem(i_active);

			i_active.tab.on({
				dblclick: {
					element: "el",
					fn: function (i_event) {
						IceCap.util.Handler.toWindow(i_active);
					}
				}
			});
		});

		i_self.mon(IceCap.app, "organizewindows", function () {
			i_self.doOrganizeWindows();
		});

		i_self.mon(IceCap.app, "resizewindows", function () {
			i_self.onResizeAndOrganize();
		});

		i_self.mon(IceCap.app, "tabstowindow", function () {
			i_self.onTabToWindows();
		});

		i_self.mon(IceCap.app, "windowstotab", function () {
			i_self.onWindowsToTab();
		});

		i_self.mon(IceCap.app, "resetwindows", function () {
			i_self.onResetWindows();
		});

		i_self.mon(IceCap.app, "compare", function (i_tab, i_compare) {
			
			IceCap.util.Handler.toWindow([i_tab, i_compare], true);
			i_self.onResizeAndOrganize(true);
		});
	},

	createTabArea: function() {

		var i_self = this;

		var i_controller = i_self.getController();

		var i_tabpanel = Ext.widget("tabpanel", {
			layout: "fit",
			plugins:[
				{
					ptype: "icecap-tabclosemenu",
					showCloseAll: true,
					showCloseOthers: true,
					listeners: {
						beforemenu: {
							fn: function (i_menu, i_item) {

								var i_panel = i_item;

								var a_tabs = i_tabpanel.items.getRange();

								var i_toWindow = i_menu.child("#towindow");

								var i_compare = i_menu.child("#compare");

								var a_items = [];

								if (i_toWindow) {
									i_menu.remove(i_toWindow);
								}

								if (i_compare) {
									i_menu.remove(i_compare);
								}

								i_toWindow = Ext.widget("menuitem", {
									text: "To Window",
									itemId: "towindow",
									handler: function (i_button) {
										IceCap.util.Handler.toWindow(i_panel);
									}
								});

								a_items.push(i_toWindow);

								i_compare = Ext.widget("menuitem", {
									xtype: "menuitem",
									itemId: "compare",
									text: "Compare",
									scope: i_self,
									menu: {
										listeners: {
											beforeshow: {
												fn: function(i_menu) {
					
													i_menu.removeAll(true);

													var i_tabpanel = i_self.getTabArea();
					
													var a_tabs = i_tabpanel.items.getRange();
					
													var a_items = [];
					
													Ext.Array.each(a_tabs, function(i_tab) {
					
					
														if (i_tab != i_item) {
					
															var s_title = i_tab.title;
					
															var o_item = {
																xtype: "menuitem",
																text: s_title,
																tab: i_tab,
																handler: function () {
																	IceCap.app.fireEvent("compare", i_item, i_tab);
																}
															};
					
															a_items.push(o_item);
														}
													});
					
													i_menu.add(a_items);
												}
											}
										}
									}
								});

								a_items.push(i_compare);

								i_compare[a_tabs.length > 1 ? "enable": "disable"]();

								if (a_items.length > 0) {
									i_menu.add(a_items);
								}
							}
						}
					}
				}
			],
			tabBar: {
                items: [
					{
                    	xtype: "button",
						text: "+ New session",
						margin: "0px 0px 0px 10px",
						ui: "icecap-tab-new",
						height: 40,
						handler: function() {
							i_controller.onNewSession();
						}
					},
					{
						xtype: "tbfill"
					},
					{
						xtype: "button",
						iconCls: "pf-options",
						ui: "icecap-tab-new",
						margin: "0px 0px 0px 10px",
						height: 40,
						arrowVisible: false,
						menu: {
							listeners: {
								beforeshow: {
									fn: function(i_menu) {

										var b_hasTabs = i_self.getTabArea().items.getRange().length > 0;

										var a_windows = IceCap.util.Handler.getWindows();
	
										var i_organize = i_menu.child("#pf-organize");
										var i_fit = i_menu.child("#pf-fit");
										var i_windows = i_menu.child("#pf-windows");
										var i_tabs = i_menu.child("#pf-tabs");
										var i_desktop = i_menu.child("#pf-reset");
	
										if (i_organize) {
											i_organize[a_windows.length ? "enable": "disable"]();
										}
	
										if (i_fit) {
											i_fit[a_windows.length ? "enable" : "disable"]();
										}
	
										if (i_windows) {
											i_windows[b_hasTabs ? "enable" : "disable"]();
										}
	
										if (i_tabs) {
											i_tabs[a_windows.length ? "enable" : "disable"]();
										}
	
										if (i_desktop) {
											i_desktop[a_windows.length ? "enable" : "disable"]();
										}
									}
								}
							},
							items: [
								{
									xtype: "menuitem",
									itemId: "pf-organize",
									text: "Organize",
									iconCls: "pf-elements3",
									handler: function () {
			
										IceCap.app.fireEvent("organizewindows");
									}
								},
								{
									xtype: "menuitem",
									itemId: "pf-fit",
									text: "Fit",
									iconCls: "pf-elements4",
									handler: function () {
			
										IceCap.app.fireEvent("resizewindows");
									}
								},
								{
									xtype: "menuitem",
									itemId: "pf-windows",
									text: "Windows",
									iconCls: "pf-elements",
									handler: function () {
			
										IceCap.app.fireEvent("tabstowindow");
									}
								},
								{
									xtype: "menuitem",
									itemId: "pf-tabs",
									text: "Tabs",
									iconCls: "pf-minus",
									handler: function () {
			
										IceCap.app.fireEvent("windowstotab");
									}
								},
								{
									xtype: "menuitem",
									itemId: "pf-reset",
									text: "Reset",
									iconCls: "pf-gearwheel",
									handler: function () {
			
										IceCap.app.fireEvent("resetwindows");
									}
								}
							]
						}
					}
				]
			},
			bodyStyle: {
				"padding-top": "10px"
			},
			listeners: {
				afterrender: {
					fn: "onAfterRender"
				},
				add: {
					fn: "onStateNotify"
				},
				remove: {
					fn: "onStateNotify"
				},
				tabchange: {
					fn: "onStateNotify"
				}
			}
		});

		i_self.setTabArea(i_tabpanel);

		return i_tabpanel;
	},

	getState: function() {

		var i_self = this;

		var i_tabpanel = i_self.getTabArea();

		var o_state = {
			tabs: [],
			activeTabIndex: -1
		};

		var a_items = i_tabpanel.items.getRange();

		Ext.Array.each(a_items, function(i_panel) {

			var o_data = {};

			if (i_panel) {
				Ext.apply(o_data, i_panel.getState());
			}

			o_state.tabs.push(o_data);
		});

		if (a_items.length > 0) {
			o_state.activeTabIndex = i_tabpanel.items.indexOf(i_tabpanel.getActiveTab());
		}

		return o_state;
	},

	applyState: function(o_state) {

		var i_self = this;

		var i_tabpanel = i_self.getTabArea();

		Ext.applyIf(o_state, {
			tabs: [],
			activeTabIndex: -1
		});

		var a_items = [];

		if (o_state.tabs.length > 0) {

			Ext.Array.each(o_state.tabs, function(o_config) {

				var o_panel = Ext.apply({
					title: "Icecap",
					closable: true,
					theme: i_self.getTheme(),
					scale: i_self.getScale(),
					enterOnDblClick: false
				}, o_config.appConfig);

				var i_icecapPanel = Ext.widget("icecap-panel", o_panel);

				a_items.push(i_icecapPanel);
			});

			var a_added = Ext.Array.from(i_tabpanel.add(a_items));

			Ext.Array.each(a_added, function(i_active) {
				
				i_active.tab.on({
					dblclick: {
						element: "el",
						fn: function (i_event) {
							IceCap.util.Handler.toWindow(i_active);
						}
					}
				});
			});

			i_tabpanel.setActiveTab(o_state.activeTabIndex);
		}
	},

	doOrganizeWindows: function () {

		var i_self = this;

		var i_tabpanel = i_self.getTabArea();
		var i_contentTarget = i_tabpanel.getContentTarget();

		var i_region = i_contentTarget.getRegion(false, true);

		var n_x = 10;
		var n_y = i_region.top + 10;
		var n_count = 1;
		var o_rows = {};
		var n_index = 0;
		var n_heigthes = 0;
		var n_padding = 10;

		var a_windows = IceCap.util.Handler.getWindows();

		Ext.Array.each(a_windows, function (i_window) {

			var o_windowSize = i_window.getSize();

			var o_box = Ext.Object.merge({}, {
				x: n_x,
				y: n_y
			}, o_windowSize);

			var a_rows = o_rows[n_count] || [];

			if ((n_x + o_box.width) > i_region.width) {
				n_heigthes = 0;
				n_index = 0;
				n_x = n_count % 2 ? 40 : 10;
				n_count++;

				a_rows = [];
			}

			a_rows.push({
				box: o_box,
				el: i_window.getEl()
			});

			o_rows[n_count] = a_rows;

			if (n_count > 1) {

				var a_saved = o_rows[n_count - 1];

				if (n_index < a_saved.length) {

					var o_index = a_saved[n_index];
					var b_intersected = false;
					var o_intersected;

					var o_saved = o_index.box;

					n_y = o_saved.y + o_saved.height + n_padding;
					o_box.y = n_y;
					o_box.x = n_x;

					Ext.Array.each(a_saved, function (o_entry) {

						var o_value = o_entry.box;

						// THIS WILL BE FALSE IF WE INTERSECT

						var n_maxX = Math.max(o_box.x, o_value.x);
						var n_maxY = Math.max(o_box.y, o_value.y);

						var n_minWidth = Math.min(o_box.x + o_box.width, o_value.x + o_value.width);
						var n_minHeight = Math.min(o_box.y + o_box.height, o_value.y + o_value.height);

						if (n_minWidth >= n_maxX && n_minHeight >= n_maxY) {
							b_intersected = true;
							o_intersected = o_value;
						}
					});

					if (b_intersected) {
						n_y = o_intersected.y + o_intersected.height + n_padding;
						o_box.y = n_y;
					}
				}
			}

			n_index++;

			i_window.setPosition(n_x, n_y, true);

			n_x += o_windowSize.width + n_padding;
		});
	},

	onResizeAndOrganize: function(b_comparing) {

		var i_self = this;

		var i_tabpanel = i_self.getTabArea();
		var i_contentTarget = i_tabpanel.getContentTarget();

		var i_region = i_contentTarget.getRegion(false, true);

		var a_windows = IceCap.util.Handler.getWindows();
		
		if (b_comparing) {
			a_windows = Ext.Array.filter(a_windows, function(i_window) {
				return i_window.comparing;
			});
		}

		var n_windows = a_windows.length;

		if (n_windows > 0) {

			var n_padding = 10;

			var n_rows = n_windows > 2 ? 2 : 1;
			var n_cols = n_windows > 2 ? Math.ceil(n_windows / 2) : n_windows;

			var n_calcWidth = (i_region.width - n_padding) - (n_padding * n_cols);
			var n_calcHeight = (i_region.height - n_padding) - (n_padding * n_rows);

			var n_count = 0;

			var o_size = {
				width: Math.ceil(n_calcWidth / n_cols),
				height: Math.ceil(n_calcHeight / n_rows)
			};

			var n_x = i_region.left + n_padding;
			var n_y = i_region.top + n_padding;

			Ext.suspendLayouts();

			Ext.Array.each(a_windows, function(i_window) {
				i_window.setSize(o_size.width, o_size.height);
			});
			
			Ext.resumeLayouts(true);

			Ext.Array.each(a_windows, function(i_window) {

				if (n_windows <= 2) {
					i_window.setPosition(n_x, n_y, true);

					n_x += o_size.width + n_padding;
				}
				else {
					if (n_count < n_cols) {

						i_window.setPosition(n_x, n_y, true);
	
						n_x += o_size.width + n_padding;
						n_count++;
					} 
					else {
	
						n_count = 0;
	
						n_x = i_region.left + n_padding;
						n_y += o_size.height + n_padding;
	
						i_window.setPosition(n_x, n_y, true);
	
						n_x += o_size.width + n_padding;
	
					}
				}
			});
		}
	},

	onResetWindows: function() {

		var i_self = this;

		var a_windows = IceCap.util.Handler.getWindows();

		Ext.Array.each(a_windows, function(i_window) {

			var i_panel = i_window.query("icecap-panel")[0];

			i_window.setWidth(null);
			i_window.setHeight(null);

			i_panel.redrawFull();
		});

		i_self.doOrganizeWindows();
	},

	onTabToWindows: function() {

		var i_self = this;

		var i_tabpanel = i_self.getTabArea();

		var a_items = i_tabpanel.items.getRange();

		Ext.Array.each(a_items, function(i_item) {
			IceCap.util.Handler.toWindow(i_item);
		});

	},

	onWindowsToTab: function() {

		var a_windows = IceCap.util.Handler.getWindows();

		var a_clone = Ext.Array.clone(a_windows);

		Ext.Array.each(a_clone, function(i_window) {

			var i_panel = i_window.down("panel");

			if (i_panel) {

				i_panel.setTitle(i_window.getTitle());

				var i_active = i_panel.getActiveWindow();

				var b_active = false;

				if (i_active && i_active.isVisible()) {
					i_active.hide();
					b_active = true;
				}

				IceCap.app.fireEvent("toTab", i_panel, b_active);
				
				i_window.close();
			}
		});
	}
	
});
