/*
/*
 * Copyright (c) OutWit Technologies 2007-2020
 * All rights reserved.
 */

/**
 * @fileOverview UI-related hub operations
 * @author vn/dmp/pr
 */

/* jshint esversion: 6 */
/* jshint -W014 */
/* jshint -W084 */
/* jshint -W103 */
/* jshint -W107 */
/* jshint -W008 */
/* jshint -W004 */
/* jshint -W069*/
/* jshint -W083*/
/* use moz */


// XXX MOVE ME
function $(anID) {
	return document.getElementById(anID);
}

/**
 * Base static class to control the hub.
 *
 * @class
 * @static
 * @name outwitHub.UIControls
 */
outwitHub.UIControls = {};


/**
 * Load UIControls
 *
 * @function
 */
outwitHub.UIControls.load = function() {

	this.extractorManager = widgets.page.extractorManager;

	this.updateInfoBox = function() {
		try {
			if (document.getElementById("version-box") && /\bversion\b/i.test(ow.app.kernel.prefs.getString("app.info.display"))) {
				document.getElementById("version-box").value = ("Version: " + ow.app.kernel.version).replace(/\.99+\.99+$/, " [debug]").replace(/(\d+\.\d+)(?=(?: \[|$))/, "$1 " + ow.app.module.uck.getLevelName() /*ow.app.module.uck.editionName()*/ );
			} else {
				document.getElementById("version-box").hidden = true;
			}
			if (document.getElementById("profile-box") && /\bprofile\b/i.test(ow.app.kernel.prefs.getString("app.info.display"))) {
				document.getElementById("profile-box").value = ("Profile: " + ow.io.places.get("profile").leafName.replace(/^[^\.]+\./, "")) + " [" + (ow.app.kernel.prefs.getInt("ui.userProfile") + "]");
			} else {
				document.getElementById("profile-box").hidden = true;
			}
			if (document.getElementById("machine-box") && ow.automation.exploded() && /\bmachine\b/i.test(ow.app.kernel.prefs.getString("app.info.display"))) {
				document.getElementById("machine-box").value = ("Machine: " + ow.app.kernel.prefs.getString("machineName"));
			} else {
				document.getElementById("machine-box").hidden = true;
			}
			if (document.getElementById("start-box") && /\bstart\b/i.test(ow.app.kernel.prefs.getString("app.info.display")) && widgets.page.browserPilot.lastExplorationStart) {
				document.getElementById("start-box").value = ("Start: " + ow.util.date.toShortLocaleString(new Date(widgets.page.browserPilot.lastExplorationStart)));
				document.getElementById("start-box").hidden = false;
			} else {
				document.getElementById("start-box").hidden = true;
			}
			if (document.getElementById("end-box") && /\bend\b/i.test(ow.app.kernel.prefs.getString("app.info.display")) && widgets.page.browserPilot.lastExplorationEnd) {
				document.getElementById("end-box").value = ("End: " + ow.util.date.toShortLocaleString(new Date(widgets.page.browserPilot.lastExplorationEnd)));
				document.getElementById("end-box").hidden = false;
			} else {
				document.getElementById("end-box").hidden = true;
			}
			var tableLength;
			if (document.getElementById("objectNet-box") && /\bobjectNet\b/i.test(ow.app.kernel.prefs.getString("app.info.display")) && (tableLength = outwitKit.objectNet.getNextID(true, true))) {
				document.getElementById("objectNet-box").value = ("objectNet DB: " + (tableLength - 1) + " - RAM: " + (outwitKit.objectNet.ramObjectNet ? outwitKit.objectNet.ramObjectNet.length - 1 : 0));
				document.getElementById("objectNet-box").hidden = false;
			} else {
				document.getElementById("objectNet-box").hidden = true;
			}
		} catch (e) {
			ow.log.error("Error updating app-info-box." + e + " -- " + e.stack);
		}
	};



	var extractorViews = document.getElementsByClassName("extractorView");
	for (var i = 0, view; i < extractorViews.length; ++i) {
		view = extractorViews[i];
		try {
			view.init();
			//"columnsModified", "rowCountChanged", "columnCountChanged", "cellChanged", "rowChanged", "dataChanged"
			view.addEventListener("focus", function(event) {
				outwitHub.UIControls.sendToDetail(event.target);
			}, true);
			view.addEventListener("select", function(event) {
				outwitHub.UIControls.onViewSelect(event);
			}, true);
			view.addEventListener("keypress", function(event) {
				outwitHub.UIControls.onViewKeyPress(event);
			}, true);
			view.addEventListener("rowCountChanged", function(event) {
				outwitHub.resendEndProcessMessage(event.target.getAttribute("viewName"));
			}, true);
			if (view.bottomPanel) {
				view.bottomPanel.addEventListener("modified", (function(view) {
					return function(event) {
						outwitHub.UIControls.menuTree.updateTreeView(view);
					};
				})(view), true);
				view.bottomPanel.addEventListener("buttonstatechanged", (function(view) {
					return function(event) {
						outwitHub.UIControls.menuTree.updateTreeView(view);
					};
				})(view), true);
			}
			if (view.optionsPanel) {
				view.optionsPanel.addEventListener("modified", (function(view) {
					return function(event) {
						outwitHub.resendEndProcessMessage(view);
					};
				})(view.getAttribute("viewName")), true);
			}
			this.updateInfoBox();
		} catch (e) {
			ow.log.error("Error initializing view " + view.getAttribute("viewName") + " line:"+e.lineNumber, e);
		}
	}

	this.currentView = null;

	function updateMaxColumnCount(value) {
		var extractorViews = document.getElementsByClassName("extractorView");
		for (var i = 0, view; i < extractorViews.length; ++i) {
			view = extractorViews[i];
			if (view.XULDatasheet && view.XULDatasheet.getAttribute("limitColumnCount") == "true") {
				view.XULDatasheet.setAttribute("maxColumnCount", value);
			}
		}

		$("catchtree").XULDatasheet.setAttribute("maxColumnCount", value);
	}

	ow.app.kernel.prefs.addObserver("tree.maxColumnCount", updateMaxColumnCount);
	updateMaxColumnCount(ow.app.kernel.prefs.getInt("tree.maxColumnCount"));

	document.getElementById("catchtree").addEventListener("focus", function(event) {
		outwitHub.UIControls.sendToDetail(event.target);
	}, true);
	document.getElementById("catchtree").addEventListener("select", function(event) {
		outwitHub.UIControls.onCatchSelect(event);
	}, true);

	document.getElementById("outwitPage").addEventListener("focus", function(event) {
		outwitHub.UIControls.sendToDetail(document.getElementById('catchtree'));
	}, true);

	outwitHub.UIControls.logMgr.load();

	$("detailWidget").init();
	$("thesaurusWidget").init();

	outwitHub._infobarMutationObserver = new MutationObserver(function(mutations) {
		mutations.forEach(function(mutation) {
			var newValue = mutation.target.getAttribute("state");
			if (newValue == "collasped") {
				document.getElementById("showLogMenu").setAttribute("checked", "false");
			} else {
				document.getElementById("showLogMenu").setAttribute("checked", "true");
			}
		});
	});
	outwitHub._infobarMutationObserver.observe(document.getElementById("infoBar"), {
		attributes: true,
		attributeFilter: ["state"]
	});

	$("ow-menu-tree").addEventListener("select", outwitHub.UIControls.menuTree.onSelect, true);
	//$("ow-menu-tree").addEventListener("dblclick", outwitHub.UIControls.menuTree.onDblClick, true);
	//  document.getElementById("ow-menu-treechildren").addEventListener("dblclick", outwitHub.UIControls.menuTree.onDblClick, true);

	document.getElementById("urlBarScraperIcon").addEventListener("click", outwitHub.UIControls.selectScrapedView, true);

	$("ow-menu-tree").focus();

	$("slideshowWidget").init();
	outwitHub.UIControls.slideshow = new outwitKit.defaultSlideshowManager($("slideshowWidget"),
		widgets.page.extractorManager,
		function() {
			outwitHub.UIControls.onStopSlideshow();
		}, outwitHub.UIControls.catchFunction);

	outwitHub.UIControls.fullscreen = new coreKit.Fullscreen(document.getElementById("slideshowSwitcher"));

	ow.loader.importJS("chrome://outwit-modules/content/js/UIMaker.js", null, true);

	widgets.page.browser.addEventListener("wheel", function(event) {
		document.getElementById("logPanelPage").updateUI();
	}, false);

	widgets.page.browser.addEventListener("overflow", function(event) {
		document.getElementById("logPanelPage").updateUI();
	}, false);

	widgets.page.browser.addEventListener("underflow", function(event) {
		document.getElementById("logPanelPage").updateUI();
	}, false);

	try {
		var thesaurusView = outwitHub.UIControls.getWidgetForView("thesaurus");
		thesaurusView.bottomPanel.reapplyButton.addEventListener("command", function(event) {
			try {
				if (!outwitKit.macroExecutionManager.macroToBeExecuted) {
					document.getElementById("thesaurusWidget").readThesaurus();
				}
				event.stopPropagation();
			} catch (e) {
				alert("Cannot reapply thesaurus #1" + e);
			}
		}, true);
	} catch (e) {
		alert("Cannot reapply thesaurus #2" + e);
	}


	Array.prototype.forEach.call($("viewsDeck").querySelectorAll(".extractorView"), function(elt) {
		try {
			var viewName = elt.getAttribute("viewName");
			var reapply = function(event) {
				try {
					if (!outwitKit.macroExecutionManager.macroToBeExecuted) {
						var confirmationMessage = coreKit.localeService.getString("view.reApply.dialog.text", "chrome://outwit-kernel/locale/widgets/views.properties");

						if (elt.wasEdited == true && viewName == "guess" && !confirm(confirmationMessage)) return false;
						if (!outwitHub.noReapplyHack) {
							outwitHub.extractControls.reApply(viewName);
						}
					}
					event.stopPropagation();
					return true;
				} catch (e) {
					alert("Cannot reapply guess #1" + e);
					return false;
				}
			};

			elt.bottomPanel.reapplyButton.addEventListener("command", reapply, true);
			elt.bottomPanel.pageLoadPanel.anonidSelector("grabButton").addEventListener("buttoncommand", function(event) {
				outwitHub.UIControls.menuTree.updateTreeView(elt);
				if (event.target.getAttribute("buttontype") != "checkbox") {
					reapply(event);
				}
			}, true);
			elt.bottomPanel.pageLoadPanel.anonidSelector("grabButton").addEventListener("buttonstatechanged", function(event) {
				outwitHub.UIControls.menuTree.updateTreeView(elt);
			}, true);
		} catch (e) {
			alert("Cannot reapply guess #2" + e);
		}
	});


	var treeController = {
		_supportedCommands: [],
		_getNestedController: function(cmd) {
			var controller = null;
			var view = outwitHub.UIControls.menuTree.getSelectedView();
			var widget = outwitHub.UIControls.menuTree.getSelectedWidget();

			if (widget) {
				// XXX This is quite odd command management... Should better have multiple nested controllers...
				// Or simply focus the element?
				if (widget.XULDatasheet) {
					controller = widget.XULDatasheet.innerTree.controllers.getControllerForCommand(cmd);
				} else {
					if (view == "page") {
						var selectedPanel = document.getElementById("slideshowSwitcher").selectedPanel;
						if (selectedPanel.id == "outwitPage") {
							controller = selectedPanel.browser.contentWindow.controllers.getControllerForCommand(cmd);
						}
					} else if (view == "scrapers") {
						if (widget.currentEditingAutomator) {
							controller = widget.scraperEditor.scraperEditorTree.controllers.getControllerForCommand(cmd);
						}
					}
				}
				if (!controller) {
					controller = widget.controllers.getControllerForCommand(cmd);
				}
			}
			return controller;
		},
		supportsCommand: function(cmd) {
			/*
			if (this._supportedCommands.indexOf(cmd) != -1) {
			  return true;
			}
			*/
			var controller = this._getNestedController(cmd);
			if (controller) {
				return controller.supportsCommand(cmd);
			}
			return false;
		},
		isCommandEnabled: function(cmd) {
			/*      switch (cmd) {
			        case "xxx":
			          break;
			        default:*/
			var controller = this._getNestedController(cmd);
			if (controller) {
				return this._getNestedController(cmd).isCommandEnabled(cmd);
			}
			return false;
			//     }
		},
		doCommand: function(cmd) {
			/*      switch (cmd) {
			        case "xxx":
			          break;
			        default:*/
			var controller = this._getNestedController(cmd);
			if (controller) {
				return this._getNestedController(cmd).doCommand(cmd);
			}
			return null;
			//     }
		}
	};

	$("ow-menu-tree").controllers.insertControllerAt(0, treeController);

	try {
		//if (kOW_DEBUGMODE) {
		this._viewManager = ow.ui.views.DeckViewController.create($("viewsDeck"));
		if (this._viewManager.getViewController("selectors")) {
			this._selectorViewController = ow.ui.automation.SelectorViewController.create(this._viewManager.getViewController("selectors"), document.querySelector("#selectorPanel"));
			this._selectorViewController.registerViewManager(this._viewManager);
			mainKit.automatorManagerService.onLoad((function() {
				this._selectorViewController.init();
			}).bind(this));
		} else {
			ow.log.error("NOOOO " + this._viewManager.getViewController("selectors") + " " + $("selectorPanelEditor"));
		}
		//}
	} catch (e) {
		if (kOW_DEBUGMODE) ow.log.error(e + "\n" + e.stack);
	}

	function updateDisplayButtons() {
		function updateIgnoreImages() {
			var element = document.getElementById('image-button');
			element.checked = !ow.app.kernel.prefs.getBool('page.ignoreImages');
		}

		function updateIgnoreMedia() {
			var element = document.getElementById('video-button');
			element.checked = !ow.app.kernel.prefs.getBool('page.ignoreMedia');
		}

		function updateIgnorePlugins() {
			var element = document.getElementById('plugin-button');
			element.checked = !ow.app.kernel.prefs.getBool('page.ignorePlugins');
		}

		function updateDisableJavascript() {
			var element = document.getElementById('javascript-button');
			element.checked = !ow.app.kernel.prefs.getBool('page.disableJavascript');
		}


		function updateHighlightSeries() {
			//setTimeout(function(){
			var element = document.getElementById('series-button');
			if (ow.app.kernel.prefs.getBool('modules.hub.ui.page.nodeHighlighter.enabled') && ow.app.kernel.prefs.getBool('modules.hub.ui.page.highlighter.enabled')) {
				//if(widgets.page.nodeHighlighter.isActive() && widgets.page.highlighter.isActive()) {
				//ow.app.kernel.prefs.setBool('modules.hub.ui.page.nodeHighlighter.enabled',false);
				widgets.page.nodeHighlighter.switchMode(false);
			}
			element.checked = ow.app.kernel.prefs.getBool('modules.hub.ui.page.highlighter.enabled');
			//},200);
		}

		function updateHighlightNodes() {
			//setTimeout(function(){
			var element = document.getElementById('nodes-button');
			if (ow.app.kernel.prefs.getBool('modules.hub.ui.page.nodeHighlighter.enabled') && ow.app.kernel.prefs.getBool('modules.hub.ui.page.highlighter.enabled')) {
				//if(widgets.page.nodeHighlighter.isActive() && widgets.page.highlighter.isActive()) {
				//ow.app.kernel.prefs.setBool('modules.hub.ui.page.highlighter.enabled',false);
				widgets.page.highlighter.switchMode(false);
			}
			element.checked = ow.app.kernel.prefs.getBool('modules.hub.ui.page.nodeHighlighter.enabled');
			//},200);
		}

		function updateSaveToObjectNet() {
			var element = document.getElementById('objectNet-button');
			element.checked = !!ow.app.kernel.prefs.getString('contacts.saveToObjectNet');
		}

		ow.app.kernel.prefs.addObserver("page.ignoreImages", updateIgnoreImages);
		ow.app.kernel.prefs.addObserver("page.ignoreMedia", updateIgnoreMedia);
		ow.app.kernel.prefs.addObserver("page.ignorePlugins", updateIgnorePlugins);
		ow.app.kernel.prefs.addObserver("page.disableJavascript", updateDisableJavascript);
		ow.app.kernel.prefs.addObserver("modules.hub.ui.page.highlighter.enabled", updateHighlightSeries);
		ow.app.kernel.prefs.addObserver("modules.hub.ui.page.nodeHighlighter.enabled", updateHighlightNodes);
		ow.app.kernel.prefs.addObserver("contacts.saveToObjectNet", updateSaveToObjectNet);

		updateIgnoreImages();
		updateIgnoreMedia();
		updateIgnorePlugins();
		updateDisableJavascript();
		updateHighlightSeries();
		updateHighlightNodes();
		updateSaveToObjectNet();
	}

	updateDisplayButtons();
	setTimeout(function() {
		outwitHub.UIControls.resizeWindowToScreen("init");
	}, 1500);
};

outwitHub.UIControls.switchSelectorPanel = function() {
	this._selectorViewController.switchEditorMode();
};

outwitHub.UIControls.onDocLoaded = function(event) {
	if (event.document.DOMDocument && event.document.DOMDocument.head) {
		var heads = event.document.DOMDocument.head.children;
		for (var i = 0; i < heads.length; ++i) {
			if (heads[i].nodeName.toLowerCase() == "meta" &&
				heads[i].hasAttribute("name") &&
				heads[i].getAttribute("name").toLowerCase() == "outwitdisplay") {
				heads[i].getAttribute("content").split(",").forEach(function(elt) {
					switch (elt.trim().toLowerCase()) {
						case "minimizesidebar":
							$("ow-menu-tree-container").setAttribute("originalwidth", $("ow-menu-tree-container").getAttribute("width"));
							$("ow-menu-tree-container").setAttribute("width", $("ow-menu-tree-container").getAttribute("minwidth"));
							break;
						case "hidesidebar":
							break;
						case "showsidebar":
							break;

						case "hidelog":
							outwitHub.UIControls.catchMgr.saveDisplayState();
							outwitHub.UIControls.logMgr.hide();
							break;
						case "showlog":
							outwitHub.UIControls.catchMgr.saveDisplayState();
							outwitHub.UIControls.logMgr.show();
							break;

						case "hidecatch":
							outwitHub.UIControls.catchMgr.saveDisplayState();
							outwitHub.UIControls.catchMgr.hide();
							break;
						case "showcatch":
							outwitHub.UIControls.catchMgr.saveDisplayState();
							outwitHub.UIControls.catchMgr.show();
							break;

						case "fullscreen":
							break;
					}
				});
			}
		}
	}
};


/**
 * Unload UIControls
 *
 * @function
 */
outwitHub.UIControls.unload = function() {
	if ($("ow-menu-tree-container").hasAttribute("originalwidth")) {
		$("ow-menu-tree-container").setAttribute("width", $("ow-menu-tree-container").getAttribute("originalwidth"));
		$("ow-menu-tree-container").removeAttribute("originalwidth");
	}
	outwitHub.UIControls.catchMgr.restoreDisplayState();
	//  outwitHub.UIControls.logMgr.restoreDisplayState();

	$("ow-menu-tree").removeEventListener("select", outwitHub.UIControls.menuTree.onSelect, true);
	document.getElementById("urlBarScraperIcon").removeEventListener("click", outwitHub.UIControls.selectScrapedView, true);

	outwitHub._infobarMutationObserver.disconnect();
};


/**
 * Macros manager load
 */
outwitHub.UIControls.loadMacroManager = function(forceManager) {
	if (!this.loadMacroManagerFlag) {
		//document.getElementById("macrosWidget").automatorManager.initTreeManager();
		document.getElementById("macrosWidget").currentBrowserURI = ((widgets.page.currentURI) ? widgets.page.currentURI.spec : "");
		document.getElementById("macrosWidget").initMacro(forceManager);
		this.loadMacroManagerFlag = true;
		return true;
	}
	return false;
};

/**
 *
 * Function that receveives a bean an adds a line in the catch
 *
 * @function
 * @static
 * @param {nsiFile} An URI to be put in the catch
 *
 */
outwitHub.UIControls.catchFunction = function(bean) {

	var sourceURLlabel = coreKit.localeService.getString("column.sourceURL.label", "chrome://outwit-kernel/locale/containers/images.properties");
	if (/^wyciwyg:/i.test(widgets.page.currentURI.spec)) widgets.page.currentURI = outwitKit.URLHistoryService.getNsIURIFromString(widgets.page.currentURI.spec.replace(/^wyciwyg:.+?(?=https?:\/\/)/i, ""));

	coreKit.coreMessager.observe('CATCH', 1, 1, '', {
		headers: [sourceURLlabel,
			coreKit.localeService.getString("column.mediaURL.label", "chrome://outwit-kernel/locale/containers/images.properties"),
			coreKit.localeService.getString("column.filename.label", "chrome://outwit-kernel/locale/containers/images.properties")
		],
		data: [
			[widgets.page.currentURI.spec, bean.URI.spec, bean.URI.fileName]
		]
	});
};



/**
 * Listener for the browserPilot "stop" event
 */
outwitHub.UIControls.onPilotStop = function() {
	outwitHub.UIControls.slideshow.noMoreImages();
};


/**
 * Listener for the slideshow "stop" event
 */
outwitHub.UIControls.onStopSlideshow = function() {
	try {
		outwitHub.extractControls.extractors["images"]._setAndExtractorAutoRunTest("slideshow", false);
		widgets.page.browserManager.niceness = -1; // XXX arbitrary value 10
		document.getElementById("slideshowSwitcher").selectedIndex = 0;
		document.getElementById("slideshowSwitcher").selectedPanel.focus();
		outwitHub.UIControls.toggleFullscreen(false);

		if (this.browseStartedBySlideshow) {
			widgets.page.stopBrowse();
			this.browseStartedBySlideshow = false;
		}

		// XXX dirty (move these from kernel to hub (or new overlay in kernel))
		document.getElementById("slideshow-button").checked = false;
		document.getElementById("showSlideShowMenu").setAttribute("checked", "false");

		outwitHub.UIControls.slideshow.clear();

	} catch (e) {
		ow.log.error("Error stopping slideshow", e);
	}
};


/**
 * Toggles the slideshow mode
 */
outwitHub.UIControls.toggleSlideshow = function() {
	try {
		if (outwitHub.UIControls.slideshow.isRunning) {
			// added by JC.
			outwitHub.extractControls.reloadImagesAutoRunFromPref();
			widgets.page.browserPilot.removeEventListener("stop", outwitHub.UIControls.onPilotStop);
			outwitHub.UIControls.slideshow.stop();
			outwitHub.UIControls.onStopSlideshow();
		} else {
			outwitHub.UIControls.slideshow.clear();
			// XXXX FIXME: (added by JC) Ugly, needs to be enhanced
			if (!outwitHub.extractControls.extractors["images"].preDefAutoRun) {
				//outwitHub.extractControls.extractors["images"].preDefAutoRun = true;
				outwitHub.extractControls.extractors["images"]._setAndExtractorAutoRunTest("slideshow", true);
				//outwitHub.extractControls.extractors["images"].run();
				widgets.page.browserManager.reload();
				//coreKit.timerService.wait(2000);
			}
			widgets.page.browserManager.niceness = 10; // XXX arbitrary value 10
			var images = outwitHub.UIControls.getWidgetForView("images").getImagesArray();
			document.getElementById("slideshowSwitcher").selectedIndex = 1;
			outwitHub.UIControls.toggleFullscreen(true);
			widgets.page.browserPilot.addEventListener("stop", outwitHub.UIControls.onPilotStop);
			outwitHub.UIControls.slideshow.start(images, 0);

			if (!widgets.page.browserPilot.running) {

				this.browseStartedBySlideshow = true;
				widgets.page.browseFromCurrent();
			} else {
				this.browseStartedBySlideshow = false;
			}


			document.getElementById("slideshowSwitcher").selectedPanel.focus();

			// XXX dirty (move these from kernel to hub (or new overlay in kernel))
			document.getElementById("slideshow-button").checked = true;
			document.getElementById("showSlideShowMenu").setAttribute("checked", "true");
		}

	} catch (e) {
		ow.log.error("Error " + (outwitHub.UIControls.slideshow.isRunning ? "stopping" : "starting") + " slideshow", e);
	}
};


/**
 * Toggles the fullscreen mode
 */
outwitHub.UIControls.toggleFullscreen = function(force) {
	ow.log.warning("toggleFullscreen", true);
	if (/fetcher|sourcer/i.test(ow.app.module.fullId)) return;
	try {
		outwitHub.UIControls.showView("page");
		if (typeof(force) != "undefined") {
			outwitHub.UIControls.fullscreen.state = force;
		} else {
			outwitHub.UIControls.fullscreen.toggle();
		}

		document.getElementById("showFullScreenMenu").setAttribute("checked", outwitHub.UIControls.fullscreen.state.toString());

	} catch (e) {
		ow.log.error("Error toggling fullscreen", e);
	}
};


/**
 * reset window to screen size
 */
outwitHub.UIControls.resizeWindowToScreen = function(param) {
	var x, y;
	param = param || "";

	//alert("start:"+param);

	param = param.replace(/\s+/g, "");
	try {
		//alert("removed spaces:"+param);

		if (/(^$|clear|reset)/i.test(param)) {
			ow.app.kernel.prefs.reset("windowSizeX");
			ow.app.kernel.prefs.reset("windowSizeY");
			param = "";
		}
		//alert("cleared:"+param);


		//alert(param);
		//outwit:resize 1500x700
		//outwit:preference windowSizeX
		if (param && (myMatch = param.match(/^(\d+)\s*(?:x\s*(\d+))?$/i))) {
			x = myMatch[1];
			y = myMatch[2];
			param = "xy";
		} else if (/(within)/i.test(param)) {
			if (ow.app.kernel.prefs.getInt("windowSizeX")) {
				x = ow.app.kernel.prefs.getInt("windowSizeX");
				param = "xy";
			}
			if (ow.app.kernel.prefs.getInt("windowSizeY")) {
				y = ow.app.kernel.prefs.getInt("windowSizeY");
				param = "xy";
			}
			ow.app.kernel.prefs.reset("windowSizeX");
			ow.app.kernel.prefs.reset("windowSizeY");
		}

		switch (param) {

			// [2019/11/1 8:33:12.93] [ERROR] screen.width:1366, screenX:0, width:1366
			// [2019/11/1 8:33:12.93] [ERROR] screen.height:768, screenY:45, height:723

			// [2019/11/1 8:58:12.901] [ERROR] window.width:993, screen.width:1366, screenX:5, width:1361
			// [2019/11/1 8:58:12.901] [ERROR] window.height:723, screen.height:768, screenY:23, height:745

			case "xy":
				if (!x && !y) return false;
				ow.log.debug(">>> Resizing the window to " + x + ", " + y);
				if (!x) x = window.innerWidth;
				if (!y) y = window.innerHeight;
				//alert("Resizing the window to " + x + ", " + y);
				window.resizeTo(x, y);
				//alert("Resized the window to " + window.innerWidth + ", " + window.innerHeight);
				if (x >= 50) ow.app.kernel.prefs.setInt("windowSizeX", x);
				if (y >= 50) ow.app.kernel.prefs.setInt("windowSizeY", y);
				ow.log.debug(">>> ######## saved preference as " + [ow.app.kernel.prefs.getInt("windowSizeX"), ow.app.kernel.prefs.getInt("windowSizeY")]);
				//alert("Saved preference as "+[ow.app.kernel.prefs.getInt("windowSizeX"),ow.app.kernel.prefs.getInt("windowSizeY")]);
				break;

			case "within":
			case "init":
				if(param == "init" && !ow.app.kernel.prefs.getInt("windowSizeX") && !ow.app.kernel.prefs.getInt("windowSizeY")){
					break;
				}
        var screenWidth = window.screen.availWidth;
        var screenHeight = window.screen.availHeight;
        var newWidth = screenWidth;
        var newHeight = screenHeight;
        if(!/mac/.test(ow.app.sysInfo.platformType)){
          newWidth = newWidth - (window.screenX);
          newHeight = newHeight - (window.screenY);
        }
				//var mainWindow = document.getElementById('outfitMain');
				//ow.log.error(">>> mainWindow:"+[mainWindow.innerWidth,mainWindow.innerHeight]);
				ow.log.debug(">>> Resizing the window within screen");
				var width = window.innerWidth;
				//ow.log.debug("window.innerWidth:" + window.innerWidth + ", screen.width:" + screenWidth + ", screenX:" + (window.screenX) + ", width:" + (width));
				if (screenWidth < window.innerWidth) width = newWidth;
				var height = window.innerHeight;
				//ow.log.debug("window.innerHeight:" + window.innerHeight + ", screen.height:" + screenHeight + ", screenY:" + (window.screenY) + ", height:" + (height));
				if (screenHeight < window.innerHeight) height = newHeight;
				window.resizeTo(width, height);
				break;

			default:
				var width = window.screen.availWidth;
				var height = window.screen.availHeight;
				ow.log.debug(">>> Resizing the window to " + [width, height]);
				window.resizeTo(width, height);
				//ow.log.debug(">>> Resizing the window to "+[window.screen.width,window.screen.height]);
				//window.resizeTo(window.screen.width,window.screen.height);
		}
	} catch (e) {
		ow.log.error("Error resizing window:" + e);
		alert("Error resizing window:" + e);
	}
};

outwitHub.UIControls.scrapedAutoHack = false;

/**
 * Selects the scraped view. This is quite a hack.
 */
outwitHub.UIControls.selectScrapedView = function(autoMode) {
	if (autoMode) {
		outwitHub.UIControls.scrapedAutoHack = true;
		outwitHub.UIControls.scrapedAutoHackWentToScrapedBecauseOfFastScrape = true;
	}
	//outwitHub.UIControls.showView("scraped");
	if (!ow.proofing.processing && !ow.wayfinder.processing) outwitHub.UIControls.showView("scraped");
};



/**
 * Tells if a node has a property.
 *
 * @function
 * @param {DOMElement} aNode
 * @param {String} aPropertyName
 * @returns {Boolean}
 */
outwitHub.UIControls.hasProperty = function(aNode, aPropertyName) {
	var strProps = aNode.getAttribute("properties");
	// strange bug...
	if (strProps == aPropertyName) return true;

	var arrayProps = strProps.split(" ");
	return (arrayProps.indexOf(aPropertyName) != -1);
};


outwitHub.UIControls.onViewChanged = function(event) {
	if (event.target == $("viewsDeck")) {
		var panelView = event.target.selectedPanel.id.replace(/View$/, "");
		var selectedView = outwitHub.UIControls.menuTree.getSelectedView();
		ow.ui.status.show(selectedView);
		if (!(selectedView == panelView || selectedView == "source" && panelView == "scrapers")) {
			outwitHub.UIControls.menuTree.setSelectedItem(panelView);
		}
	}
};

outwitHub.UIControls.onViewKeyPress = function(event) {
	if (event.keyCode == KeyEvent.DOM_VK_RETURN) {
		document.getElementById('catchtree').appendDataSheet(event.target.JSDatasheet, event.target.preventCatchDedup && !(event.target.optionsPanel && event.target.optionsPanel.getOptionValue("hideDuplicatedRows")), true);
	}
};

/**
 * Static subclass of outwitHub.UIControls to
 * perform operations on the side pane tree
 *
 * @name outwitHub.UIControls.menuTree
 * @static
 */
outwitHub.UIControls.menuTree = {};

/**
 * Stores treecell items to get them quickly.
 */
outwitHub.UIControls.menuTree.items = {};


/**
 * Returns the view name for an event on the tree, using coordinates
 */
outwitHub.UIControls.menuTree.getViewNameForEvent = function(event) {
	try {
		var tree = $("ow-menu-tree");
		var tbo = tree.treeBoxObject;

		// get the row, col and child element at the point
		var row = {},
			col = {},
			child = {};
		tbo.getCellAt(event.clientX, event.clientY, row, col, child);

		if (row.value == -1) // prevent from anywhere click
			return "";

		var props = tree.view.getCellProperties(row.value, col.value);
		return props.split(" ")[0];
	} catch (e) {
		return null;
	}
};


/**
 * Select handler on the left menu tree
 */
outwitHub.UIControls.menuTree.onSelect = (function(event) {
	var selectedView = outwitHub.UIControls.menuTree.getSelectedView();
	if (selectedView != this.currentView) {
		outwitHub.UIControls.showView(selectedView, true);
	}
	ow.log.debug("> selected view "+selectedView);
	outwitHub.extractControls.setCurrent(selectedView, outwitHub.UIControls.scrapedAutoHack);
}).bind(outwitHub.UIControls);

/**
 * Click handler on the left menu tree
 */
outwitHub.UIControls.menuTree.onClick = function(event) {
	var view = this.getViewNameForEvent(event);
	if (view) {
		outwitHub.UIControls.menuTree.lastClicked = view;
	}
};


/*
 * XXX pr not working : the tree handles the event before these listeners... so
 * the page view is already collapsed when this event comes!
 */
outwitHub.UIControls.menuTree.onDblClick = function(event) {
	try {
		var tree = $("ow-menu-tree");
		var tbo = tree.treeBoxObject;
		var row = {},
			col = {},
			child = {};
		tbo.getCellAt(event.clientX, event.clientY, row, col, child);
		if (tree.view.isContainer(row.value) && !tree.view.isSelectable(row.value, col.value)) {
			event.preventDefault();
			event.stopPropagation();
		}
	} catch (e) {}
};

/**
 * Drag timer stuff
 */
outwitHub.UIControls.menuTree.dragTimer = null;
outwitHub.UIControls.menuTree.dragTimeout = 1500;
outwitHub.UIControls.menuTree.nextSelectedView = null;

/**
 * Dragover handler on the tree
 */
outwitHub.UIControls.menuTree.onDragOver = function(event) {
	var view = this.getViewNameForEvent(event);
	if (view && view != this.nextSelectedView) {
		if (typeof(this.dragTimer) == "number") {
			coreKit.timerService.cancelTimer(this.dragTimer);
		}
		if (this.nextSelectedView) {
			this.removeProperty(this.nextSelectedView, "dropOn");
		}
		this.nextSelectedView = view;
		this.addProperty(view, "dropOn");
		this.dragTimer = coreKit.timerService.setTimer(1500, null,
			function() {
				this.removeProperty(view, "dropOn");
				this.dragTimer = null;
				var row = outwitHub.UIControls.menuTree.getRowIndexForView(view);
				var treeview = $("ow-menu-tree").view;
				var col = $("ow-menu-tree").columns.getFirstColumn();
				if (treeview.isSelectable(row, col)) {
					outwitHub.UIControls.showView(view);
				}
				if (treeview.isContainer(row) && !treeview.isContainerOpen(row)) {
					treeview.toggleOpenState(row);
				}
			}, this);
	}
};

/**
 * Dragleave handler on the tree
 */
outwitHub.UIControls.menuTree.onDragLeave = function(event) {
	if (typeof(this.dragTimer) == "number") {
		coreKit.timerService.cancelTimer(this.dragTimer);
		this.dragTimer = null;
		if (this.nextSelectedView) {
			this.removeProperty(this.nextSelectedView, "dropOn");
		}
		this.nextSelectedView = null;
	}
};



/**
 * Simple method to check if a DOM node of the tree has the property name.
 * Instead of passing a DOM node as first argument, just give the view name
 * of the wanted item.
 *
 * @function
 * @static
 * @param {string} The name of a view to check for
 * @param {string} The name of the property to chech for
 * @return {boolean} Indicating if the property is found
 */
outwitHub.UIControls.menuTree.hasProperty = function(viewName, propertyName) {
	var node = outwitHub.UIControls.menuTree.getItemForView(viewName);
	return outwitHub.UIControls.hasProperty(node, propertyName);
};


/**
 * Add a property to the given view.
 * The property is add to the properties attribute of the target treecell.
 * Developer can style it via css.
 *
 * @function
 * @static
 * @param {string} The name of the view to alter
 * @param {string} The name of the property to add
 * @return {boolean} A result value indicating if a property has been added.
 */
outwitHub.UIControls.menuTree.addProperty = function(viewName, propertyName) {
	try {
		var node = outwitHub.UIControls.menuTree.getItemForView(viewName);
		if (node) {
			var properties = node.getAttribute("properties").split(" ");
			if (properties.indexOf(propertyName) == -1) {
				properties.push(propertyName);
				node.setAttribute("properties", properties.join(" "));
				return true;
			}
		}
	} catch (e) {
		ow.log.error("Cannot add property " + propertyName + " on " + viewName + " tree item", e);
	}

	return false;
};

/**
 * Remove a property from the given view.
 * The property is remove from the properties attribute of the target treecell.
 *
 * @function
 * @static
 * @param {string} The name of the view to alter
 * @param {string} The name of the property to remove
 * @return {boolean} A result value indicating if a property
 * has been removed.
 */
outwitHub.UIControls.menuTree.removeProperty = function(viewName, propertyName) {
	try {
		var node = outwitHub.UIControls.menuTree.getItemForView(viewName);
		if (node) {
			var properties = node.getAttribute("properties").split(" ");
			var idxProp = properties.indexOf(propertyName);
			if (idxProp != -1) {
				properties.splice(idxProp, 1);
				node.setAttribute("properties", properties.join(" "));
				return true;
			}
		}
		return false;
	} catch (e) {
		ow.log.error("Cannot remove property " + propertyName + " on " + viewName + " tree item", e);
		return false;
	}
};


/**
 * Stores the throbber state for each treecell
 */
outwitHub.UIControls.menuTree.throbberStates = {};


/**
 * Start the throbber for a given view
 *
 * @function
 * @param {String} viewName
 */
outwitHub.UIControls.menuTree.startThrobber = function(viewName) {
	try {
		if (!this.throbberStates[viewName]) {
			this.throbberStates[viewName] = {
				running: true
			};
			outwitHub.UIControls.menuTree.addProperty(viewName, "loading");
		} else if (!this.throbberStates[viewName].running) {
			this.throbberStates[viewName].running = true;
			outwitHub.UIControls.menuTree.addProperty(viewName, "loading");
		} else if (typeof(this.throbberStates[viewName].timer) == "number") {
			coreKit.timerService.cancelTimer(this.throbberStates[viewName].timer);
			this.throbberStates[viewName].timer = null;
		}
	} catch (e) {
		ow.log.error("Error stopping throbber for view " + viewName, e);
	}
};


/**
 * Stop the throbber for a given view
 *
 * @function
 * @param {String} viewName
 */
outwitHub.UIControls.menuTree.stopThrobber = function(viewName, aTimeout) {
	try {
		// Why would we stop if not started ?
		if (!this.throbberStates[viewName]) {
			return;
		}

		if (typeof(this.throbberStates[viewName].timer) == "number") {
			coreKit.timerService.cancelTimer(this.throbberStates[viewName].timer);
		}
		this.throbberStates[viewName].timer = coreKit.timerService.setTimer((aTimeout ? aTimeout : 200), null,
			function() {
				try {
					outwitHub.UIControls.menuTree.throbberStates[viewName].running = false;
					outwitHub.UIControls.menuTree.removeProperty(viewName, "loading");
				} catch (e) {
					ow.log.error("Error stopping throbber for view " + viewName, e);
				}
			}
		);
	} catch (e) {
		ow.log.error("Error stopping throbber for view " + viewName, e);
	}
};


/**
 * Get an item for a given view name
 * from the side pane menu.
 * Return null if nothing is found
 *
 * @function
 * @static
 * @param {string} The view name to search for
 * @return {node} The dom node resulting
 */
outwitHub.UIControls.menuTree.getItemForView = function(viewName) {
	var foundCell = null;
	var cell = outwitHub.UIControls.menuTree.items[viewName];
	if (cell && outwitHub.UIControls.hasProperty(cell, viewName)) {
		return cell;
	} else {
		var treecells = $("ow-menu-tree").getElementsByTagName("treecell");
		for (var i = 0, cell, props, propsArray;
			(i < treecells.length) && !foundCell; i++) {
			cell = treecells[i];
			if (outwitHub.UIControls.hasProperty(cell, viewName)) {
				foundCell = cell;
				outwitHub.UIControls.menuTree.items[viewName] = cell;
			}
		}
	}
	return foundCell;
};


/**
 * Get the currently selected item in
 * the side pane menu.
 * Return null if nothing is found.
 *
 * @function
 * @static
 * @return {node} The dom node resulting
 */
outwitHub.UIControls.menuTree.getSelectedItem = function() {
	var viewName = outwitHub.UIControls.menuTree.getSelectedView();
	if (!viewName) return null;
	return outwitHub.UIControls.menuTree.getItemForView(viewName);
};


/**
 * Get the currently selected view name
 * in the side pane menu.
 * Return '' if nothing is found.
 *
 * @function
 * @static
 * @return {string} The name if the selected view
 */
outwitHub.UIControls.menuTree.getSelectedView = function() {
	var tree = $("ow-menu-tree");
	var treeBoxObject = tree.treeBoxObject;
	var firstCol = treeBoxObject.columns.getFirstColumn();
	var row = tree.view.selection.currentIndex;

	if (row == -1) // prevent from anywhere click
		return "";

	try {
		var props = tree.view.getCellProperties(row, firstCol);
		return props.split(" ")[0];
	} catch (e) {
		return "";
	}
};


outwitHub.UIControls.menuTree.getSelectedWidget = function() {
	return outwitHub.UIControls.getWidgetForView(outwitHub.UIControls.menuTree.getSelectedView());
};



outwitHub.UIControls.menuTree.updateOnDemandMenu = function(element) {
	ow.log.error("updateOnDemandMenu " + element.getAttribute("checked"));
	var viewName = outwitHub.UIControls.menuTree.getSelectedView();
	ow.app.kernel.prefs.setBool(viewName + ".ondemandonly", element.getAttribute("checked") == "true");
};

outwitHub.UIControls.menuTree.updateIgnoreImages = function(element) {
	ow.app.kernel.prefs.setBool("page.ignoreImages", element.getAttribute("checked") == "true");
};

outwitHub.UIControls.menuTree.updateIgnoreMedia = function(element) {
	ow.app.kernel.prefs.setBool("page.ignoreMedia", element.getAttribute("checked") == "true");
};

outwitHub.UIControls.menuTree.updateIgnorePlugins = function(element) {
	ow.app.kernel.prefs.setBool("page.ignorePlugins", element.getAttribute("checked") == "true");
};

outwitHub.UIControls.menuTree.updateDisableJavascript = function(element) {
	ow.app.kernel.prefs.setBool("page.disableJavascript", element.getAttribute("checked") == "true");
};

outwitHub.UIControls.menuTree.updateDisableAll = function(element) {
	ow.app.kernel.prefs.setBool("page.ignoreImages", true);
	ow.app.kernel.prefs.setBool("page.ignoreMedia", true);
	ow.app.kernel.prefs.setBool("page.ignorePlugins", true);
	ow.app.kernel.prefs.setBool("page.disableJavascript", true);
};

outwitHub.UIControls.menuTree.updateEnableAll = function(element) {
	ow.app.kernel.prefs.setBool("page.ignoreImages", false);
	ow.app.kernel.prefs.setBool("page.ignoreMedia", false);
	ow.app.kernel.prefs.setBool("page.ignorePlugins", false);
	ow.app.kernel.prefs.setBool("page.disableJavascript", false);
};


/**
 * Update context menu
 * in the side pane menu.
 *
 * @function
 * @static
 */
outwitHub.UIControls.menuTree.updateContextMenu = function(element) {
	var viewName = outwitHub.UIControls.menuTree.getSelectedView();
	var view = outwitHub.UIControls.getWidgetForView(viewName);
	if (view.bottomPanel && !view.bottomPanel.isDefault) {
		element.firstChild.setAttribute('disabled', 'false');
	} else {
		element.firstChild.setAttribute('disabled', 'true');
	}

	var onDemandMenu = document.getElementById("menutreePopup_onDemand");
	if (viewName == "images") {
		onDemandMenu.removeAttribute("hidden");
		if (ow.app.kernel.prefs.getBool(viewName + ".ondemandonly")) {
			onDemandMenu.setAttribute("checked", "true");
		}
	} else {
		onDemandMenu.setAttribute("hidden", "true");
	}

	var ignoreImagesMenu = document.getElementById("menutreePopup_ignoreImages");
	var ignoreMediaMenu = document.getElementById("menutreePopup_ignoreMedia");
	var ignorePluginsMenu = document.getElementById("menutreePopup_ignorePlugins");
	var disableJavascriptMenu = document.getElementById("menutreePopup_disableJavascript");
	var disableAllMenu = document.getElementById("menutreePopup_disableAll");
	var enableAllMenu = document.getElementById("menutreePopup_enableAll");
	if (viewName == "page") {
		ignoreImagesMenu.removeAttribute("hidden");
		ignoreMediaMenu.removeAttribute("hidden");
		ignorePluginsMenu.removeAttribute("hidden");
		disableJavascriptMenu.removeAttribute("hidden");
		disableAllMenu.removeAttribute("hidden");
		enableAllMenu.removeAttribute("hidden");
		if (ow.app.kernel.prefs.getBool("page.ignoreImages")) {
			ignoreImagesMenu.setAttribute("checked", "true");
		} else {
			ignoreImagesMenu.removeAttribute("checked");
		}
		if (ow.app.kernel.prefs.getBool("page.ignoreMedia")) {
			ignoreMediaMenu.setAttribute("checked", "true");
		} else {
			ignoreMediaMenu.removeAttribute("checked");
		}
		if (ow.app.kernel.prefs.getBool("page.ignorePlugins")) {
			ignorePluginsMenu.setAttribute("checked", "true");
		} else {
			ignorePluginsMenu.removeAttribute("checked");
		}
		if (ow.app.kernel.prefs.getBool("page.disableJavascript")) {
			disableJavascriptMenu.setAttribute("checked", "true");
		} else {
			disableJavascriptMenu.removeAttribute("checked");
		}
	} else {
		ignoreImagesMenu.setAttribute("hidden", "true");
		ignoreMediaMenu.setAttribute("hidden", "true");
		ignorePluginsMenu.setAttribute("hidden", "true");
		disableJavascriptMenu.setAttribute("hidden", "true");
		disableAllMenu.setAttribute("hidden", "true");
		enableAllMenu.setAttribute("hidden", "true");
	}
};

/**
 * Update context menu
 * in the side pane menu.
 *
 * @function
 * @static
 */
outwitHub.UIControls.menuTree.updateTreeView = function(element) {
	var viewName;
	try {
		viewName = element.getAttribute("viewName");
		var view = outwitHub.UIControls.getWidgetForView(viewName);

		if (view.bottomPanel && !view.bottomPanel.isDefault) {
			outwitHub.UIControls.menuTree.addProperty(viewName, 'notdefault');
		} else {
			outwitHub.UIControls.menuTree.removeProperty(viewName, 'notdefault');
		}

		if (view.bottomPanel && view.bottomPanel.pageLoadPanel) {
			outwitHub.extractControls.extractors[viewName].autoCatch = view.pageLoadPanel.autoCatch;
		}

		if (view.bottomPanel && view.bottomPanel.pageLoadPanel.downloadPanel) {
			outwitHub.extractControls.extractors[viewName].download = view.bottomPanel.pageLoadPanel.downloadPanel.downloadValue;
		}

		if (view.bottomPanel && view.bottomPanel.pageLoadPanel.exportPanel) {
			outwitHub.extractControls.extractors[viewName]['export'] = view.bottomPanel.pageLoadPanel.exportPanel.exportValue;
		}

		if (view.bottomPanel && view.bottomPanel.pageLoadPanel) {
			outwitHub.extractControls.extractors[viewName].notEmpty = !view.bottomPanel.pageLoadPanel.autoEmpty;
			//ow.log.debug("UPDATETREE " + viewName + " " + view.bottomPanel.pageLoadPanel.autoGrab, true);
			outwitHub.extractControls.extractors[viewName].autoGrab = view.bottomPanel.pageLoadPanel.autoGrab;
		}

		if (view.bottomPanel && view.bottomPanel.optionsPanel) {
			var options = view.bottomPanel.optionsPanel.options;
			var optionModified = false;
			for (var optionName in options) {
				var newValue = view.bottomPanel.optionsPanel.getOptionValue(optionName);
				if (options[optionName].type == "option" && outwitHub.UIControls.extractorManager.getOptionValue(viewName, optionName) != newValue) {
					if (outwitHub.UIControls.extractorManager.getOptionValue(viewName, optionName) != undefined) {
						optionModified = true;
					}
					outwitHub.UIControls.extractorManager.setOptionValue(viewName, optionName, newValue);
				}
			}

		}
	} catch (e) {
		ow.log.debug("Error updating menu " + viewName, e);
	}
};


/**
 * Reset all views
 * in the side pane menu.
 *
 * @function
 * @static
 */
outwitHub.UIControls.menuTree.resetAllViews = function() {

	outwitHub.noReapplyHack = true;
	for (var extractor in outwitHub.extractControls.extractors) {

		try {
			//it will throw errors for sure
			var widget = outwitHub.UIControls.getWidgetForView(outwitHub.extractControls.extractors[extractor].viewName);
			if (widget && widget.bottomPanel) {
				widget.bottomPanel.resetToDefault();
			}
		} catch (error) {
			//some view are not trees ( like source, scraper, macros)
			if (kOW_DEBUGMODE) ow.log.warning("Trying to clear data - not trees.\nIn the extractor:" + extractor, error);
		}
	}
	outwitHub.noReapplyHack = false;
};

/**
 * Reset selected view
 * in the side pane menu.
 *
 * @function
 * @static
 */
outwitHub.UIControls.menuTree.resetSelectedView = function() {

	var viewName = outwitHub.UIControls.menuTree.getSelectedView();
	var view = outwitHub.UIControls.getWidgetForView(viewName);

	if (view.bottomPanel) {
		view.bottomPanel.resetToDefault();
		outwitHub.UIControls.menuTree.removeProperty(viewName, "notdefault");
	}
};


/**
 * Gets the row index in menu tree, given a view name
 */
outwitHub.UIControls.menuTree.getRowIndexForView = function(viewName) {
	var tree = $("ow-menu-tree");
	var treeBoxObject = tree.treeBoxObject;
	var firstCol = treeBoxObject.columns.getFirstColumn();

	var found = null;
	for (var i = 0; i < tree.view.rowCount && found == null; ++i) {
		try {
			var props = tree.view.getCellProperties(i, firstCol);
			props = props.split(" ");
			if (props.indexOf(viewName) != -1) {
				found = i;
			}
		} catch (e) {}
	}
	return found;
};


/**
 * Select an item in the side pane corresponding
 * to the viewName arguments
 *
 * @param {string} The name of the view to select:w
 * @return {int} Index of the new selected item or -1
 */
outwitHub.UIControls.menuTree.setSelectedItem = function(viewName) {
	var rowIndex = this.getRowIndexForView(viewName);
	$("ow-menu-tree").view.selection.select(rowIndex);
};


/**
 * Gets the view (element in deck) given a view name
 */
outwitHub.UIControls.getView = function(viewName) {
	return document.getElementById(viewName + "View");
};


/**
 * Gets the widget for a given view
 *
 * @function
 * @param {String} viewName
 * @returns {XULElement}
 */
outwitHub.UIControls.getWidgetForView = function(viewName, multiple) {
	var views = document.getElementsByAttribute("viewName", viewName);
	if (!multiple && !views[0]) {
		return null;
	}
	return (multiple ? views : views[0]);
};

/*
 * Saves catch and infobar positions
 */
outwitHub.UIControls.savePositions = function(aViewName, currentView) {
	try {
		//ow.log.error("savePositions " + aViewName + " " + currentView);
		ow.log.notice("Saving UI settings.");
		var isPage = (currentView === "page");
		var isFullScreenEditor = (["scrapers", "macros", "jobs"].indexOf(currentView) !== -1);
		var isAutomator = (["selectors", "projects", "scrapers", "macros", "jobs", "queries", "scripts", "thesaurus", "debug"].indexOf(currentView) !== -1);
		var currentPanel = (isPage ? $("pageView") : $("viewsDeck").selectedPanel);
		if (!/fetcher|sourcer/i.test(ow.app.module.fullId)) {
			try {
				// saving current catch/infobar positions for this view
				if ($("catch-splitter").getAttribute("state") == "collapsed" && $("catch-splitter").getAttribute("substate") == "after") {
					currentPanel.setAttribute("catchPosition", "after");
				} else {
					currentPanel.setAttribute("catchPosition", $("catchContainer").getAttribute("height"));
				}
			} catch (e) {
				ow.log.error("Error saving position \n" + e + "\n" + e.stack);
			}
		}

		//ow.log.error("isPage:"+isPage + " "+ (isPage ? $("viewsDeck") : $("pageView")).boxObject.height);

		if ($("infoBar").getAttribute("state") == "collapsed" && $("infoBar").getAttribute("substate") == "before") {
			currentPanel.setAttribute("infoBarPosition", "before");
			//alert("setting to before");
		} else {
			currentPanel.setAttribute("infoBarPosition", (isPage ? $("viewsDeck") : $("pageView")).boxObject.height);
		}

		// Saves the catch and infobar positions, but not for automator that have a full screen editor
		if (!isFullScreenEditor) {
			try {
				this.lastViewCatchPosition = currentPanel.getAttribute("catchPosition");
				this.lastViewInfoBarPosition = currentPanel.getAttribute("infoBarPosition");
				// XXXX WHAT IS SAVED HERE IS LOST FOR AUTOMATORS (QUERIES, PROJECTS, ETC.) and reset to "before" at next run
				//alert("saved this.lastViewInfoBarPosition = "+this.lastViewInfoBarPosition);
			} catch (e) {
				ow.log.error("Error saving position \n" + e + "\n" + e.stack);
			}
		}
	} catch (e) {
		ow.log.error("Error saving position \n" + e + "\n" + e.stack);
	}
};

/*
 * Sets catch and infobar positions or a view
 */
outwitHub.UIControls.updatePositions = function(aViewName, panel, currentView) {
	var logPanel = document.getElementById("logPanel");
	var logPanelPage = document.getElementById("logPanelPage");
	var logPanelPageSplitter = document.getElementById("logPanelPageSplitter");
	var viewContainer = document.getElementById("viewContainer");
	var infoBar = document.getElementById("infoBar");
	var catchSplitter = document.getElementById("catch-splitter");
	var catchContainer = document.getElementById("catchContainer");

	var fromPage = (currentView && (currentView === "page")) || false;
	var fromAutomator = (currentView && (["selectors", "projects", "scrapers", "macros", "jobs", "queries", "scripts", "thesaurus", "debug"].indexOf(currentView) !== -1)) || false;
	var fromFullScreenEditor = (currentView && (["scrapers", "macros", "jobs"].indexOf(currentView) !== -1)) || false;
	var toPage = (aViewName === "page");
	var toFullScreenEditor = (["scrapers", "macros", "jobs"].indexOf(aViewName) !== -1);
	//var toAutomator = (["selectors", "projects", "scrapers", "macros", "jobs", "queries", "scripts", "thesaurus", "debug"].indexOf(aViewName) !== -1);
	var catchPos, infoBarPos;

	var totalHeight = $("pageView").getAttribute("height") && $("viewsDeck").getAttribute("height") ? Number($("pageView").getAttribute("height")) + Number($("viewsDeck").getAttribute("height")) + 15 : 0;
	if (toFullScreenEditor && !/fetcher|sourcer/i.test(ow.app.module.fullId)) {
		//  alert(1);
		// restoring automator's saved positions
		catchPos = panel.getAttribute("catchPosition");
		infoBarPos = panel.getAttribute("infoBarPosition");
	} else {
		//  alert(2);
		// restoring either lastViewPosition, or panel attribute
		infoBarPos = (typeof(this.lastViewInfoBarPosition) != "undefined" ? this.lastViewInfoBarPosition : panel.getAttribute("infoBarPosition"));
		//alert("restored infoBarPos = "+infoBarPos);
		if (fromFullScreenEditor || !currentView) {
			//alert("2b");
			catchPos = (typeof(this.lastViewCatchPosition) != "undefined" ? this.lastViewCatchPosition : panel.getAttribute("catchPosition"));
		}
	}
	if (/fetcher|sourcer/i.test(ow.app.module.fullId)) {
		catchPos = "after";
	}

	//alert(catchPos+"\n"+(new Error).stack);

	//ow.log.error("updatePosition  aViewName=" + aViewName + "  currentView=" + currentView + "  catchPos=" + catchPos + "  infoBarPos= " + infoBarPos, true);
	// if a catch position is defined, restore it
	if (catchPos) {
		if (catchPos === "after") {
			//alert(3);
			catchSplitter.setAttribute("state", "collapsed");
			catchSplitter.setAttribute("substate", "after");
		} else if (catchPos) {
			//alert(4);
			catchSplitter.setAttribute("state", "open");
			catchContainer.setAttribute("height", catchPos);
		}
	}

	// If an infoBarPos is defined, set it
	if (toPage) {
		//  alert(5);
		//alert(totalHeight);

		if (infoBarPos && totalHeight && infoBarPos > totalHeight / 2) infoBarPos = Math.min($("pageView").getAttribute("height"), $("viewsDeck").getAttribute("height"));
		else if (infoBarPos) infoBarPos = Math.min(infoBarPos, 150);

		$("pageView").removeAttribute("height");
		$("pageView").setAttribute("flex", "1");
		$("viewsDeck").setAttribute("height", infoBarPos || infoBarPos === 0 ? infoBarPos : 150);
	} else {
		// XXX hack for sourcer module, BAD
		if (/fetcher|sourcer/i.test(ow.app.module.fullId) && !infoBarPos) {
			//alert(6);
			$("viewsDeck").removeAttribute("height");
			$("viewsDeck").setAttribute("flex", "1");
			$("pageView").removeAttribute("flex");
			$("pageView").setAttribute("height", $("viewContainer").clientHeight * 3 / 5);
		} else {
			//alert(7);
			$("viewsDeck").removeAttribute("height");
			$("viewsDeck").setAttribute("flex", "1");
			//XXXX JC: not sure what is going on here. How can infoBarPos be "before" ? please check
			//alert([infoBarPos,toFullScreenEditor, (toFullScreenEditor ? 0 : 150)]);
			if (infoBarPos == "before") infoBarPos = 0;
			$("pageView").setAttribute("height", infoBarPos || (toFullScreenEditor ? 0 : (aViewName == "scrapers" ? 300 : 150)));
		}
	}

	if (toPage) {
		// alert(8);
		logPanelPage.classList.add("invisible");
		logPanelPageSplitter.setAttribute("hidden", "true");

		$("pageView").setAttribute("flex", "1");
		$("viewsDeck").removeAttribute("flex");

		$("pageView").style.minHeight = "100px";

		$("viewsDeck").selectedIndex = 0;
		$("viewsDeck").style.minHeight = "0px";
		viewContainer.style.MozBoxDirection = "reverse";
	} else {
		// alert(9);
		logPanelPage.classList.remove("invisible");
		logPanelPageSplitter.removeAttribute("hidden");
		viewContainer.style.MozBoxDirection = "normal";

		$("viewsDeck").setAttribute("flex", "1");
		$("pageView").removeAttribute("flex");

		$("pageView").style.minHeight = "0px";
		$("viewsDeck").selectedPanel = panel;
		$("viewsDeck").style.minHeight = (aViewName == "scrapers" ? "300" : "150") + "px";
		logPanelPage.updateUI();
	}

	if (catchSplitter.getAttribute("state") === "collapsed" &&
		catchSplitter.getAttribute("substate") === "before") {
		// alert(10);
		catchSplitter.setAttribute("state", "open");
		catchSplitter.removeAttribute("substate");
		catchContainer.setAttribute("height", "160");
	}

	if (toPage) {
		if ($("pageView").boxObject.height === 0) {
			// alert(11);
			$("pageView").removeAttribute("height");
			$("pageView").setAttribute("flex", "1");
			$("viewsDeck").height = 150;
			$("pageView").removeAttribute("flex");
		}
	} else if ($("viewsDeck").boxObject.height === 0) {
		// alert(12);
		$("viewsDeck").removeAttribute("height");
		$("viewsDeck").setAttribute("flex", "1");
		$("pageView").height = (aViewName == "scrapers" ? 300 : 150);
		$("viewsDeck").removeAttribute("flex");
	}
};

outwitHub.UIControls.switchViewMode = function() {
	outwitHub.UIControls.menuTree.getSelectedWidget().switchViewMode();
};

/**
 * Select a view
 *
 * @function
 * @static
 * @param {string} Name of the view to select
 */
outwitHub.UIControls.showView = function(aViewName, dontSelectMenuTree) {

	// XXX Making sure there is no way to change the view in sourcer
	if (ow.app.module.fullId == "modules.sourcer") aViewName = "emails";

	if ((/(selectors|posts|wayfinder|video|audio|proofing)/i.test(aViewName) && !(kOW_DEBUGMODE || ow.app.module.uck.uk())) ||
		(aViewName == "projects" && !(kOW_DEBUGMODE || ow.app.module.uck.ok())) ||
		(aViewName == "thesaurus" && !(kOW_DEBUGMODE || ow.app.module.uck.ek()))
	) {
		return false;
	}

	//  if (aViewName == this.currentView) return false;

	try {

		var previousView = this.currentView;

		outwitHub.UIControls.clearDetail();
		var isSource = false;
		var sourceWidget = outwitHub.UIControls.getWidgetForView("source");
		var sourceDocument = sourceWidget.currentSource && sourceWidget.currentSource.sourceDocument ? sourceWidget.currentSource.sourceDocument : {};
		if (aViewName == "source") {
			isSource = true;
			document.getElementById("scraperEditorSplitter").setAttribute("state", "collapsed");
			document.getElementById("scraperEditorSplitter").setAttribute("disabled", "true");
			document.getElementById("scrapersSourceWidget").sourceSwitcher = ow.app.module.uck.ok();
			//XXXXX JC: Added on 01/25/2015, modified 01/14/2016
			if (!(sourceDocument.body && sourceDocument.body.textContent) || previousView != "scrapers") document.getElementById("scrapersSourceWidget").reloadSource();
		} else if (aViewName == "scrapers") {
			document.getElementById("scraperEditorSplitter").setAttribute("state", "open");
			document.getElementById("scraperEditorSplitter").removeAttribute("disabled");
			document.getElementById("scrapersSourceWidget").sourceSwitcher = false;
			//XXXXX JC: Added on 01/25/2015, modified 01/14/2016
			if (!(sourceDocument.body && sourceDocument.body.textContent) || !/scraped|source/i.test(previousView)) document.getElementById("scrapersSourceWidget").reloadSource();
		} else if (aViewName == "history") {
			$('historyWidget').updateCompleteData();
		}


		// XXX hum hum (mac bug)
		if (this.currentView == "queries") {
			$("queriesWidget").saveEditor();
		}

		var panel = outwitHub.UIControls.getView(isSource ? "scrapers" : aViewName);

		if (panel) {

			this.currentView = aViewName;

			document.getElementById("infoBar").clean();
			if (!dontSelectMenuTree) {
				outwitHub.UIControls.menuTree.setSelectedItem(aViewName);
			} else {
				outwitHub.extractControls.setCurrent(aViewName, outwitHub.UIControls.scrapedAutoHack);
			}

			if (previousView) {
				outwitHub.UIControls.savePositions(aViewName, previousView);
			}
			outwitHub.UIControls.updatePositions(aViewName, panel, previousView);



			if (outwitHub.UIControls.scrapedAutoHack) {
				document.getElementById("infoBar").resetIdleMessage(outwitHub.UIControls.menuTree.getSelectedView());
			}

			document.getElementById("infoBar").currentComponent = outwitHub.UIControls.menuTree.getSelectedView();
			outwitHub.UIControls.scrapedAutoHack = false;
			if (aViewName == "emails") {
				document.getElementById("showHighlightButtonMenuitem").removeAttribute("disabled");
				widgets.page.highlighter.switchButtonMode(ow.app.module.prefs.get("ui.page.highlighter.showButton"));
			} else {
				widgets.page.highlighter.switchButtonMode(false, true);
				document.getElementById("showHighlightButtonMenuitem").setAttribute("disabled", "true");
			}

			widgets.page.highlighter.stop();
			if (ow.app.module.prefs.get("ui.page.highlighter.enabled")) {
				widgets.page.highlighter.start();
			}

			widgets.page.nodeHighlighter.stop();
			if (ow.app.module.prefs.get("ui.page.nodeHighlighter.enabled")) {
				widgets.page.nodeHighlighter.start();
			}


			$("ow-menu-tree").setAttribute("selectedView", aViewName);

			if (outwitHub.UIControls.menuTree.hasProperty(aViewName, "disabled") && aViewName != "jobs" && aViewName != "macros") {
				coreKit.observerService.observe(new coreKit.message("registration", coreKit.message.TYPE_NOTICE, "disabled.feature", 0, {
					view: aViewName,
					feature: coreKit.localeService.getString("proFeature." + aViewName, "chrome://outwit-modules/locale/localize.properties")
				}));
			} else if (outwitHub.UIControls.getWidgetForView(aViewName).limited) {
				coreKit.observerService.observe(new coreKit.message("registration", coreKit.message.TYPE_NOTICE, "limited.view", 0, {
					view: aViewName,
					viewName: coreKit.localeService.getString('views.' + aViewName + 'View', 'chrome://outwit-modules/locale/localize.properties'),
					viewItems: coreKit.localeService.getString("views." + aViewName + ".items", "chrome://outwit-modules/locale/localize.properties"),
					maxCount: outwitHub.extractControls.extractors[aViewName].maxCountLightVersion
				}));
			}

			var catchSplitter = document.getElementById("catch-splitter");

			/** This is used to show the catch if the user went to macro view and didnt change the catch **/
			if (this.splitterStateSavedInMacro) {

				//the user didnt change the catch while he was in the macro
				if (catchSplitter.getAttribute("state") == "collapsed") {
					catchSplitter.setAttribute("state", this.splitterStateSavedInMacro.state);
					catchSplitter.setAttribute("substate", this.splitterStateSavedInMacro.substate);
					document.getElementById("catchContainer").setAttribute("height", this.splitterStateSavedInMacro.height);
				} else {
					//if the user changed the macro, we wont hide it again
					this.userWantsToSeeCatchInMacro = true;
				}
				this.splitterStateSavedInMacro = null;
			}

			switch (aViewName) {
				case "words":
					// XXX perhaps this should be in extractControls ?
					if (!outwitKit.wordNet.isBuiltExtended) {
						outwitHub.UIControls.menuTree.startThrobber(aViewName);
						ow.log.debug("Running outwitKit.wordNet.buildExtended()");
						outwitKit.wordNet.buildExtended("");
						ow.log.debug("Ended outwitKit.wordNet.buildExtended()");
					}
					break;

				case "scraped":

					var extractor = outwitHub.extractControls.extractorManager.getInstanceForLocation("scraped", "fastScrape", true);
					if (extractor && !(extractor.isRunning)) {
						var listOfpossibleAutomators = ow.automation.util.getAutomatorsByTypeForURL(widgets.page.currentURI.spec, "scraper");
						if (listOfpossibleAutomators.length <= 0) {

							listOfpossibleAutomators = ow.automation.util.getAutomatorsByTypeForURL(widgets.page.currentURI.spec, "scraper", true);
							if (listOfpossibleAutomators.length <= 0) {
								outwitHub.UIControls.getWidgetForView('scraped').noScraperNotification(null, false);
							} else {
								outwitHub.UIControls.getWidgetForView('scraped').noScraperNotification(null, true);
							}
						}
					}
					break;

				case "thesaurus":
					document.getElementById("thesaurusWidget").readThesaurus();
					break;
				case "selectors":
					$("pageView").setAttribute("height", $("viewContainer").clientHeight * 3 / 5);
					catchSplitter.setAttribute("substate", "after");
					catchSplitter.setAttribute("state", "collapsed");
					break;

				case "macros":
					//if we hide the cathc and the user open it in the macro view, we wont hide it again
					if (!this.userWantsToSeeCatchInMacro) {
						this.splitterStateSavedInMacro = {
							state: catchSplitter.getAttribute("state"),
							substate: catchSplitter.getAttribute("substate"),
							height: document.getElementById("catchContainer").getAttribute("height")
						};
						catchSplitter.setAttribute("substate", "after");
						catchSplitter.setAttribute("state", "collapsed");
					}
					break;

				case "page":
					outwitHub.UIControls.sendToDetail(document.getElementById("catchtree"));
					break;

			}

			if (aViewName != "page") {
				var widget = outwitHub.UIControls.getWidgetForView(aViewName);
				outwitHub.UIControls.sendToDetail(widget);
			}

		}
		this._viewManager.setCurrentView(aViewName);
		try {
			ow.log.debug("selecting " + aViewName + " tab.");
			document.querySelector('#tablist>tabs').selectedItem = document.querySelector("#" + aViewName + 'Tab');
		} catch (e) {
			ow.log.debug("Error selecting " + aViewName + " tab: ", e);
		}

	} catch (e) {
		if (kOW_DEBUGMODE) ow.log.error("Error selecting " + aViewName + " view in line "+e.lineNumber, e);
	}
};


outwitHub.UIControls.onViewSelect = function(event) {
	try {
		if (outwitHub.UIControls.menuTree.getSelectedView() == event.target.getAttribute("viewName")) {
			outwitHub.UIControls.sendToDetail(event.target);
		}
	} catch (e) {}
};

outwitHub.UIControls.onCatchSelect = function(event) {
	if (outwitHub.UIControls.menuTree.getSelectedView() == "page" || document.commandDispatcher.focusedElement == document.getElementById("catchtree").XULDatasheet) {
		outwitHub.UIControls.sendToDetail(event.target);
	}
};

outwitHub.UIControls.sendToDetail = function(target) {
	var datasheet = target.JSDatasheet;
	if (datasheet && datasheet.getLength() && datasheet.getSelection().getCurrentIndex() != null) {
		var headers = datasheet.getColumns().toLabelsArray(true);
		var data = datasheet.getRow(datasheet.getSelection().getCurrentIndex(), true);
		coreKit.coreMessager.observe('Detail', 1, 1, '', [headers, data]);
	} else {
		outwitHub.UIControls.clearDetail();
	}
};

outwitHub.UIControls.clearDetail = function() {
	coreKit.coreMessager.observe('Detail', 1, 1, '', null);
};


/**
 * Infobar management
 */
outwitHub.UIControls.infoMgr = {};

outwitHub.UIControls.infoMgr.toggle = function() {
	if (outwitHub.UIControls.infoMgr.isHidden()) {
		outwitHub.UIControls.infoMgr.show();
		outwitHub.UIControls.infoMgrLog.show();
		document.getElementById("showInfoMenu").setAttribute("checked", "true");
	} else {
		outwitHub.UIControls.infoMgr.hide();
		outwitHub.UIControls.infoMgrLog.hide();
		document.getElementById("showInfoMenu").setAttribute("checked", "false");
	}
};

outwitHub.UIControls.infoMgr.isHidden = function() {
	var val = document.getElementById("infoBar").getAttribute("hidden");
	if (val == "true")
		return true;
	else
		return false;
};

outwitHub.UIControls.infoMgr.show = function() {
	document.getElementById("infoBar").removeAttribute("hidden");
};

outwitHub.UIControls.infoMgr.hide = function() {
	document.getElementById("infoBar").setAttribute("hidden", "true");
};

outwitHub.UIControls.infoMgrLog = {};

outwitHub.UIControls.infoMgrLog.show = function() {
	document.getElementById("logPanel").setAttribute("collapsed", "false");
};

outwitHub.UIControls.infoMgrLog.hide = function() {
	document.getElementById("logPanel").setAttribute("collapsed", "true");
};

/*
 * Log Panel Management
 */

outwitHub.UIControls.logMgr = {

	load: function() {
		this.logPanel = document.getElementById("logPanel");
		this.logPanelPage = document.getElementById("logPanelPage");
		this.logPanelPageSplitter = document.getElementById("logPanelPageSplitter");
		this.menuItem = document.getElementById("showLogMenu");
		this.opened = (this.menuItem && this.menuItem.getAttribute("checked") === "true");
	},

	opened: null,

	toggle: function() {
		this[this.opened ? "hide" : "show"]();
	},

	show: function(aHeight) {
		this.logPanelPageSplitter.setAttribute("state", "open");
		this.logPanelPageSplitter.removeAttribute("substate");
		if (aHeight) {
			this.logPanelPage.setAttribute("width", aHeight);
		}

		var height;
		if (this.logPanel.hasAttribute("originalheight")) {
			height = this.logPanel.getAttribute("originalHeight");
		} else {
			height = (aHeight ? aHeight.toString() : "150");
		}
		this.logPanel.setAttribute("infoBarPosition", height);
		if (outwitHub.UIControls.currentView === "page") {
			$("viewsDeck").setAttribute("height", height);
		} else if (!parseInt($("pageView").getAttribute("height"))) {
			$("viewsDeck").removeAttribute("height");
			$("viewsDeck").setAttribute("flex", "1");
			$("pageView").setAttribute("height", height);
		}

		this.opened = true;
		this.menuItem.setAttribute("checked", "true");
	},

	hide: function() {
		this.logPanel.setAttribute("originalHeight", this.logPanel.getAttribute("height"));
		this.logPanel.setAttribute("infoBarPosition", "0");
		if (outwitHub.UIControls.currentView === "page") {
			$("viewsDeck").setAttribute("height", "0");
		}
		this.logPanelPageSplitter.setAttribute("state", "collapsed");
		this.logPanelPageSplitter.setAttribute("substate", "after");
		this.opened = false;
		this.menuItem.removeAttribute("checked");
	}
};



/**
 * Catch manager API, for managing catch apparitions
 *
 * @class
 * @static
 */
outwitHub.UIControls.catchMgr = {

	/**
	 * Shortcut to the catch splitter
	 *
	 * @static
	 */
	splitter: document.getElementById("catch-splitter"),


	/**
	 * Check if the catch is hidden
	 *
	 * @static
	 * @function
	 * @return {Boolean}
	 */
	isHidden: function() {
		if (!outwitHub.UIControls.catchMgr.splitter) {
			outwitHub.UIControls.catchMgr.splitter = document.getElementById("catch-splitter");
		}
		var splitter = outwitHub.UIControls.catchMgr.splitter;
		return splitter.getAttribute("state") == "collapsed" &&
			splitter.getAttribute("substate") == "after";
	},


	/**
	 * Check if the catch is maximized
	 *
	 * @static
	 * @function
	 * @return {Boolean}
	 */
	isMaximized: function() {
		var splitter = outwitHub.UIControls.catchMgr.splitter;
		return splitter.getAttribute("state") == "collapsed" &&
			splitter.getAttribute("substate") == "before";
	},


	/**
	 * Check if the catch WAS maximized (before it has been hidden for example)
	 *
	 * @static
	 * @function
	 * @return {Boolean}
	 */
	wasMaximized: function() {
		var splitter = outwitHub.UIControls.catchMgr.splitter;
		return splitter.getAttribute("oldsubstate") == "before";
	},

	saveDisplayState: function() {
		var splitter = outwitHub.UIControls.catchMgr.splitter;
		splitter.setAttribute("originalstate", splitter.getAttribute("state"));
		splitter.setAttribute("originalsubstate", splitter.getAttribute("substate"));
		splitter.setAttribute("originaloldsubstate", splitter.getAttribute("oldsubstate"));
	},

	restoreDisplayState: function() {
		var splitter = outwitHub.UIControls.catchMgr.splitter;
		if (splitter.hasAttribute("originalstate")) {
			splitter.setAttribute("state", splitter.getAttribute("originalstate"));
			splitter.removeAttribute("originalstate");
			splitter.setAttribute("substate", splitter.getAttribute("originalsubstate"));
			splitter.removeAttribute("originalsubstate");
			splitter.setAttribute("oldsubstate", splitter.getAttribute("originaloldsubstate"));
			splitter.removeAttribute("originaloldsubstate");
		}
	},

	/**
	 * Show the catch.
	 *
	 * @static
	 * @function
	 */
	show: function() {
		if (/fetcher|sourcer/i.test(ow.app.module.name)) return false;
		var splitter = outwitHub.UIControls.catchMgr.splitter;
		// if it was maximized, restore it
		if (outwitHub.UIControls.catchMgr.wasMaximized()) {
			splitter.setAttribute("state", "open");
			splitter.setAttribute("substate", "before");
			splitter.setAttribute("state", "collapsed");
		}
		// else just open it
		else {
			splitter.setAttribute("substate", "");
			splitter.setAttribute("state", "open");
		}
	},


	/**
	 * Hide the catch.
	 *
	 * @static
	 * @function
	 */
	hide: function() {
		var splitter = outwitHub.UIControls.catchMgr.splitter;
		// if it is maximized, remember it
		if (outwitHub.UIControls.catchMgr.isMaximized()) {
			splitter.setAttribute("oldsubstate", "before");
			splitter.setAttribute("state", "open");
		} else {
			splitter.setAttribute("oldsubstate", "");
		}
		// and hide it
		splitter.setAttribute("substate", "after");
		splitter.setAttribute("state", "collapsed");
	},


	/**
	 * Toggle the catch hidden/displayed and change menu checkbox.
	 *
	 * @static
	 * @function
	 */
	toggle: function() {
		var splitter = outwitHub.UIControls.catchMgr.splitter;
		if (outwitHub.UIControls.catchMgr.isHidden()) {
			outwitHub.UIControls.catchMgr.show();
			document.getElementById("showCatchMenu").setAttribute("checked", "true");
		} else {
			outwitHub.UIControls.catchMgr.hide();
			document.getElementById("showCatchMenu").setAttribute("checked", "false");
		}
	}
};
