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

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


/**
 * @fileOverview Main javascript file for the hub
 * @author dmp, vn, pr
 */


/**
 * Global namespace for OutWit Hub
 *
 * @static
 * @name outwitHub
 */
var outwitHub = {};

// XXX put that in mainKit

outwitHub.onLoad = function(event) {
	if (window.owLoaded) {
		//Components.utils.reportError("owLoaded");
		outwitHub.load(event);
	} else {
		//Components.utils.reportError("NOT owLoaded, setting load callback");
		window.owOnLoad = outwitHub.load.bind(outwitHub);
	}
};

/**
 * Onload stuff
 *
 * @function
 */
outwitHub.load = function(event) {


	try {
		ow.app.load();

		outwitHub.setObserve();

		ow.app.onShutdown((function(event) {
			// storing UI positions
			outwitHub.UIControls.savePositions(null, outwitHub.UIControls.currentView);
			// Sanoff
			if (widgets.wizardManager) widgets.wizardManager.unload();
			try {
				coreKit.SelectionManager.active = false;
			} catch (e) {}

			function nextAfterCatchSave() {
				outwitHub.UIControls.unload();
				outwitHub.extractControls.unload();

				//ow.app.kernel.prefs.setString("browser.lastPage", widgets.page.currentURI.spec);
				widgets.page.unload();

				coreKit.timerService.cancelAllTimers();
				mainKit.shutdown();
				event.callback();
			}

			if (ow.app.module.fullId != "modules.sourcer") {
				var catchTree = document.getElementById('catchtree');
				catchTree.saveAsCatch(false, catchTree.NOT_BACKUP, null, nextAfterCatchSave);
			} else {
				nextAfterCatchSave();
			}
		}).bind(this));

		ow.app.onUnload((function(event) {
			ow.log.notice("Unloading outfit");

			//var currentView = outwitHub.UIControls.menuTree.getSelectedView();

			var done = 0;
			var automatorViews = Array.prototype.slice.call(document.querySelectorAll(".automatorManagerView"));

			function next() {
				if (++done == automatorViews.length) {
					//outwitHub.UIControls.showView(currentView);
					try {
						outwitHub.UIControls.getWidgetForView("macros").askSaveChanges();
					} catch (e) {
						if (kOW_DEBUGMODE) ow.log.error(e);
					}
					event.callback(true);
				}
			}

			if (outwitHub.UIControls._selectorViewController) {
				outwitHub.UIControls._selectorViewController.destroy();
			}


			// Saving currently editing automators
			automatorViews.forEach(function(automatorManagerView, index, viewList) {
				if (automatorManagerView && automatorManagerView.getEditor) {
					var type = automatorManagerView.getAttribute("automatorType");
					if (type != "macro") {
						ow.log.notice("Closing " + type + " editor");
						var editor = automatorManagerView.getEditor();
						//ow.log.error(editor ? editor + " -- " + editor.isEditing() + " -- " + editor.hasModifications() + " -- " + (editor._editingAutomator ? editor._editingAutomator.data : "N/A") + " -- " + (editor._originalEditingAutomator ? editor._originalEditingAutomator.data : "N/A") + " -- " + editor.saveAutomator + " -- " + (editor._editingAutomator == editor._originalEditingAutomator) : "no editor");
						if (editor && editor.isEditing() && editor.hasModifications()) {
							//outwitHub.UIControls.showView(automatorManagerView.getAttribute("viewName"));
							// XXX this is only for scrapers, and will be for macros. queris are autosaving, and jobs are
							// auto-notsaving... (will be fix later)
							if (editor.saveAutomator) {
								editor.saveAutomator(true, next);
								return;
							}
						}
					}
				}
				next();
			});
		}).bind(this));
	} catch (e) {
		ow.log.error("Error loading application " + e + "\n\n" + e.stack, e);
	}

	// initialization of the mainKit
	// @todo see what it does
	try {
		//Components.utils.reportError("MAINKIT.INIT CALL");
		mainKit.init();
	} catch (e) {
		ow.log.fatal("Error initializing kernel.\n" + e.fileName + ":" + e.lineNumber + "\n" + e.stack, e);
		window.close();
	}


	document.getElementById('catchtree').init();
	Array.prototype.forEach.call(document.getElementsByClassName("hider"), function(hider) {
		hider.init();
	});

	document.getElementById("search-container").setAttribute("hidden", ow.app.kernel.prefs.getBool("hideSearch"));

	try {
		widgets.page.load(
			ow.app.kernel.prefs.getInt("browse.maxPageProcessTime"),
			ow.app.kernel.prefs.getInt("browse.tempo.min"),
			ow.app.kernel.prefs.getInt("browse.tempo.max"),
			ow.app.kernel.prefs.getBool("browse.tempo.sameDomainOnly")
		);
	} catch (e) {
		ow.log.error(e + " - " + e.stack);
		ow.log.fatal("Error initializing page widget", e);
		window.close();
	}

	if (ow.app.module.fullId != "modules.sourcer") {
		try {
			document.getElementById('catchtree').load();
		} catch (e) {
			ow.log.fatal("Error initializing catch", e);
			window.close();
		}
	}

	try {
		outwitHub.UIControls.load();
	} catch (e) {
		//alert("Error initializing hub controls: "+ e.stack);
		ow.log.fatal("Error initializing hub controls: " + e + " - " + e.stack);
		window.close();
	}

	try {
		outwitHub.extractControls.load();
	} catch (e) {
		ow.log.fatal("Error initializing hub extractors", e);
		window.close();
	}

	try {
		// Overlay splitter hack
		// XXX 21: it is strange that we can't do with that...
		// Any suggestions?
		//
		var currentNode = document.getElementById("catch-splitter");
		if (currentNode) {
			var tabPanelBefore = currentNode.previousSibling;
			var tabPanelAfter = currentNode.nextSibling;
			tabPanelBefore.setAttribute("height", 400);
			tabPanelAfter.setAttribute("height", 150);
		}
		if (document.getElementById("showCatchMenu")) {
			document.getElementById("showCatchMenu").setAttribute("checked", !outwitHub.UIControls.catchMgr.isHidden());
		}
		coreKit.observerService.subscribe({
			observe: function(aMessage) {

				function openNext(urls) {
					var url;
					while ((url = urls.shift())) {
						url = url.URI.spec;
						outwitHub.openUrlWin.gBrowser.addTab(url);
					}
				}

				var vars = aMessage.getVariableDictionary();
				switch (aMessage.getEvent()) {
					case "openWindow":
						var referer = (vars["refererURI"] ? outwitKit.URLHistoryService.getNsIURIFromString(vars["refererURI"]) : null);
						var urls = (vars["URIList"] ? vars["URIList"] : [vars["URI"]]);
						if (urls && urls.length) {
							var win;
							try {
								if (outwitHub.openUrlWin && !outwitHub.openUrlWin.closed) {
									win = outwitHub.openUrlWin;
								}
							} catch (e) {}

							if (!win) {
								var url = urls.shift().URI.spec;
								outwitHub.openUrlWin = win = window.open(url, "", "");
								outwitHub.openUrlWin = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
									.getInterface(Components.interfaces.nsIWebNavigation)
									.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
									.rootTreeItem
									.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
									.getInterface(Components.interfaces.nsIDOMWindow);
								openNext(urls);
							} else {
								openNext(urls);
							}
						}
						break;

					case "open":
						var list = vars["URIList"] || [vars["URI"]];
						if (list.length == 1 && list[0].URI) {
							widgets.page.go(list[0].URI.spec);
						} else {
							widgets.page.browse(null, list, false);
						}
						break;
					case "browse":
						var list = vars["URIList"] || [vars["URI"]];
						widgets.page.browse(null, list, true);
						break;
					case "dig":
						var list = vars["URIList"] || [vars["URI"]];
						widgets.page.dig(null, list, false, 1, null, null, "domain");
						break;
				}
			}
		}, "URL");

		coreKit.observerService.subscribe({
			observe: function(aMessage) {
				if (aMessage.getEvent() != "apply") return;
				var vars = aMessage.getVariableDictionary();
				outwitHub.extractControls.applyMacro(vars["URIList"], vars["automatorId"], vars["contextualData"]);
			}
		}, "applyMacro");

		coreKit.observerService.subscribe({
			observe: function(aMessage) {
				if (aMessage.getEvent() != "apply") return;
				var vars = aMessage.getVariableDictionary();
				if (ow.app.kernel.prefs.getInt("fastScrape.tempo.max") >= 3000) {
					outwitKit.panelDialogService.showDialog(
						"fastScrapeHighTempo",
						function(anID, aButton) {
							if (aButton == "ok") {
								outwitHub.extractControls.fastScrape(vars["URIList"], vars["automatorId"], vars["contextualData"], vars["options"]);
							} else if (aButton == "openPrefs") {
								widgets.menu.openPrefPane("TimeSettings");
							}
						},
						true,
						"center", {
							"class": "dialog-panel-simple",
							"titleBar": {
								label: "",
								closeButton: true
							},
							template: {
								type: "html",
								data: outwitKit.panelDialogService.getSimpleDialogTemplate("warning", coreKit.localeService.getString("fastScrapeHighTempo.label", "chrome://outwit-kernel/locale/widgets/scraper/manager.properties"))
							},

							buttons: {
								"ok": {
									type: "ok",
									labelId: "ok"
								},
								//                  "ok": { type: "ok",  labelId: coreKit.localeService.getString("fastScrapeTempoOK.label", "chrome://outwit-kernel/locale/widgets/scraper/manager.properties") },
								"openPrefs": {
									labelId: "preferences",
									dontClose: true
								},
								"dontRemind": {
									type: "dontRemind",
									labelId: coreKit.localeService.getString("dontAskMe.label", "chrome://outwit-kernel/locale/common.properties")
								}
							},
							dontRemind: {
								type: "simple",
								"default": "ok"
							}
						}
					);

				} else {
					outwitHub.extractControls.fastScrape(vars["URIList"], vars["automatorId"], vars["contextualData"], vars["options"]);
				}
			}
		}, "fastScrape");

		coreKit.observerService.subscribe({
			observe: function(aMessage) {
				if (aMessage.getEvent() != "apply") return;
				var vars = aMessage.getVariableDictionary();
				outwitHub.extractControls.scrapeStrings(vars["stringsToScrape"], vars["automatorId"], vars["options"]);
			}
		}, "scrapeStrings");

		var supportedCommands = ["cmd_fastScrape", "cmd_scrapeStrings", "cmd_applyMacro"];
		var controller = {
			supportsCommand: function(cmd) {
				return supportedCommands.indexOf(cmd) != -1;
			},

			isCommandEnabled: function(cmd) {
				switch (cmd) {
					case "cmd_fastScrape":
					case "cmd_scrapeStrings":
					case "cmd_applyMacro":
						return true;
				}
				return false;
			},

			doCommand: function(cmd) {
				return this._commandExec[cmd].call(this);
			},

			_commandExec: {
				"cmd_fastScrape": function() {
					widgets.page.fastScrape();
				},
				"cmd_applyMacro": function() {
					widgets.page.applyMacro();
				}

			}
		};

		coreKit.observerService.subscribe({
			observe: function(aMessage) {
				if (aMessage.getEvent() != "apply") return;

				var vars = aMessage.getVariableDictionary();
				if (ow.app.kernel.prefs.getInt("fastScrape.tempo.max") >= 2000) {
					outwitKit.panelDialogService.showDialog(
						"fastScrapeHighTempo",
						function(anID, aButton) {
							if (aButton == "ok") {
								outwitHub.extractControls.fastContacts(vars["URIList"], vars["options"]);
							} else if (aButton == "openPrefs") {
								widgets.menu.openPrefPane("TimeSettings");
							}
						},
						true,
						"center", {
							"class": "dialog-panel-simple",
							"titleBar": {
								label: "",
								closeButton: true
							},
							template: {
								type: "html",
								data: outwitKit.panelDialogService.getSimpleDialogTemplate("warning", coreKit.localeService.getString("fastScrapeHighTempo.label", "chrome://outwit-kernel/locale/widgets/scraper/manager.properties"))
							},
							buttons: {
								"ok": {
									type: "ok",
									labelId: "ok"
								},
								"openPrefs": {
									labelId: "preferences",
									dontClose: true
								},
								"dontRemind": {
									type: "dontRemind"
								}
							},
							dontRemind: {
								type: "simple",
								"default": "ok"
							}
						}
					);

				} else {
					outwitHub.extractControls.fastContacts(vars["URIList"], vars["options"]);
				}
			}
		}, "fastContacts");

		window.controllers.appendController(controller);

		mainKit.loadURI = outwitHub.loadURI;

		// XXX hum, could do better than a timeout?
		coreKit.timerService.setTimer(10000, null, function() {
			if (kOW_DEBUGMODE) {
				try {
					document.loadOverlay("chrome://outwit-modules-debug/content/debugOverlay.xul");
				} catch (e) {
					ow.log.error("Error loading debug overlay: " + e + "\n");
					alert("Error loading debug overlay: " + e + "\n");
				}
			}

		});

		document.getElementById("cmd_help").setAttribute("oncommand", "openHelp(outwitHub.UIControls.menuTree.lastClicked)");


		var updateJobMenuitem = function() {
			if (outwitKit.jobExecutionManager.isJobScheduled()) {
				outwitHub.UIControls.menuTree.addProperty("jobs", "bold");
			} else {
				outwitHub.UIControls.menuTree.removeProperty("jobs", "bold");
			}
		};

		outwitKit.jobExecutionManager.addListener({
			onScheduled: function() {
				updateJobMenuitem();
				widgets.page.updateCommands(["widgetPage:StopAll"]);
			},
			onSchedule: function() {
				updateJobMenuitem();
				widgets.page.updateCommands(["widgetPage:StopAll"]);
			},
			onPrerun: function() {
				updateJobMenuitem();
				widgets.page.updateCommands(["widgetPage:StopAll"]);
			},
			onRun: function() {
				updateJobMenuitem();
				widgets.page.updateCommands(["widgetPage:StopAll"]);
			},
			onEnd: function() {
				updateJobMenuitem();
				widgets.page.updateCommands(["widgetPage:StopAll"]);
			},
			onCancel: function() {
				updateJobMenuitem();
				widgets.page.updateCommands(["widgetPage:StopAll"]);
			},
			onStack: function() {
				updateJobMenuitem();
				widgets.page.updateCommands(["widgetPage:StopAll"]);
			}
		});


		// register the callback to run a macro
		outwitKit.jobExecutionManager.registerAutomatorType("macro", function(anAutomatorMasterId, anAutomatorVersion, aEndCallback) {
			return {
				start: function() {
					outwitKit.macroExecutionManager.runMacroFromMasterIdAndVersion(anAutomatorMasterId, anAutomatorVersion, aEndCallback);
				},
				abort: function() {
					widgets.page.stopAll(null, true, true);
				}
			};
		});

		outwitKit.exportManager.load();

		window.__defineGetter__("gWindow", function() {
			return window
				.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
				.getInterface(Components.interfaces.nsIWebNavigation)
				.QueryInterface(Components.interfaces.nsIDocShellTreeItem).rootTreeItem
				.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
				.getInterface(Components.interfaces.nsIDOMWindow);
		});

		window.__defineGetter__("gBrowser", function() {
			return widgets.page.browser;
		});

		coreKit.SelectionManager.active = true;

		//if (kOW_DEBUGMODE) {
		document.getElementById("logPanel").maxCount = 1000;
		document.getElementById("logPanelPage").maxCount = 500;
		//}

		// Sanoff
		if (widgets.wizardManager) widgets.wizardManager.load();

		coreKit.timerService.setTimer(3000, null, function() {
			outwitHub.UIMaker.load();
			// Sanoff
			if (widgets.wizardManager && mainKit.isFirstRun) {
				widgets.wizardManager.showWizard(coreKit.outwitURLs.get("tutorials"), false, null, null, true);
			}
		});

		outwitKit.jobExecutionManager.load();

		var afterPaint = function(event) {
			window.removeEventListener("MozAfterPaint", afterPaint, true);

			// XXX Why afterpaint?
			mainKit.automatorManagerService.onLoad(function() {


				// XXX HACK to prevent scrollbar blinking
				var scraperView = document.getElementById("scrapersWidget");
				scraperView.setViewMode("editor");
				scraperView.setViewMode("manager");


				var clArgs = ow.app.commandLine.args.automators;
				// XXX TODO make a processManager and merge with automator execution above.
				if (clArgs && clArgs.length) {
					var runNextArg = function runNextArg() {
						//ow.log.notice("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ runNextArg " + clArgs.length +"\n"+JSON.stringify(clArgs) +"\n\n"+(new Error).stack + "\n");
						//ow.log.notice("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ runNextArg " + clArgs.length + "\n" + clArgs + "\n\n" + (new Error()).stack + "\n");
						if (clArgs.length) {
							var arg = clArgs.shift();
							// correcting arg.type Why?
							// XXX Fixed in commandLine.jsm !
							//var tester = typeof(arg.value) == "string"?arg.value:(arg.value && arg.value.spec?arg.value.spec:"");
							//if(/^outwit:/i.test(tester) && /&&/.test(tester)) arg.type = "macroUrl";
							switch (arg.type) {
								case "url":
									// XXX Fixed in commandLine.jsm !
									//arg.value = arg.value && arg.value.spec ? arg.value.spec : arg.value;
									//ow.log.notice("XXXXXXXXXXXXXXXXXXX EXECUTION URL " + arg.value + "\n\n" + (new Error()).stack + "\n");
									widgets.page.loadURI(arg.value);
									// XXX ??? how? runNextArg();
									break;
								case "macroUrl":
									// XXX Fixed in commandLine.jsm !
									//arg.value = arg.value && arg.value.spec ? arg.value.spec : arg.value;
									//ow.log.notice("XXXXXXXXXXXXXXXXXXX EXECUTION MACROURL " + arg.value + "\n\n" + (new Error()).stack + "\n");
									outwitKit.macroExecutionManager.runMacroFromUrl(arg.value, runNextArg, true);
									break;
								case "macroId":
									//ow.log.notice("XXXXXXXXXXXXXXXXXXX EXECUTION MACROID " + arg.value + "\n\n" + (new Error()).stack + "\n");
									outwitKit.macroExecutionManager.runMacroFromId(arg.value, runNextArg, true);
									break;
								case "jobId":
									mainKit.automatorManagerService.onLoad(function() {
										outwitKit.jobExecutionManager.addListener({
											onEnd: function(aData) {
												outwitKit.jobExecutionManager.removeListener(this);
												runNextArg();
											},
											onCancel: function(aData) {
												outwitKit.jobExecutionManager.removeListener(this);
												runNextArg();
											}
										});
										//ow.log.notice("XXXXXXXXXXXXXXXXXXX EXECUTION JOB " + arg.value + "\n\n" + (new Error()).stack + "\n");
										//widgets.page.stopAll();
										outwitKit.jobExecutionManager.run(arg.value);
									});
									break;
							}
						} else {
							try {
								ow.log.notice("XXXXXXXXXXXXXXXXX QUITAFTER");
								if (ow.app.commandLine.args.quitAfter) {
									ow.app.quit();
								}
							} catch (e) {
								alert(e);
							}
						}
					};

					mainKit.automatorManagerService.onLoad(runNextArg);
				} else {
					outwitKit.jobExecutionManager.reloadAll(ow.app.kernel.prefs.getBool("jobs.startup.runMissed"));
				}
			});

			// XXX WHY ONLY IN SOURCER ??? WHY AFTERPAINT?
			if (ow.app.module.fullId != "modules.sourcer") {
				mainKit.monitoringService.addEventListener("wake", function() {
					coreKit.observerService.observe(new coreKit.message("jobs", coreKit.message.TYPE_NOTICE, "wake.reload", 6, {}));
					outwitKit.jobExecutionManager.reloadAll(true);
				});
			}

			if (!ow.app.commandLine.args.automators.length) {
				coreKit.timerService.setTimer(100, 0, function() {
					var restoreViewPref = outwitHub.forceView || ow.app.module.prefs.getString("startupView");
					if (!restoreViewPref) restoreViewPref = "page";
					switch (restoreViewPref) {
						case "latest":
							var viewName = $("ow-menu-tree").getAttribute("selectedView");
							outwitHub.UIControls.showView((viewName != "debug" ? viewName : "page"), null, true);
							break;
						case "debug":
							outwitHub.UIControls.showView("page", null, true);
							break;
						default:
							outwitHub.UIControls.showView(restoreViewPref, null, true);
							break;
					}
				});
			}
		};
		window.addEventListener("MozAfterPaint", afterPaint, true);


	} catch (e) {
		ow.log.error("Error loading OutWit Hub, line:" + e.lineNumber, e);
		window.close();
	}

	outwitHub.extractorObserver = {
		_handlers: {
			"scraper": function(aData) {
				var scraper = aData.automators[0];
				//alert([String(scraper.checked),scraper.active]);
				//alert((new Error).stack);
				var rating = ow.automation.util.rateAutomatorForURL(scraper, widgets.page.currentURI.spec);
				if (!scraper.active) {
					rating = ow.automation.util.rateAutomatorForURL(scraper, widgets.page.currentURI.spec, true);
					//get the message from locale
					var pString = coreKit.localeService.getString("useDisabledAutomator", "chrome://outwit-kernel/locale/widgets/scraper/manager.properties");
					pString = pString.replace(/#automatorName#/gi, scraper.name);
					//if user want to use this disabled scraper
					if (confirm(pString)) {
						//alert("1:"+rating);
						// XXXX JC: did not manage to activate the automator from here. Just asked if user wants to use it anyway. Should add a way to activate it.
						//var theWidget = outwitHub.UIControls.getWidgetForView("scrapers");
						//var listOfActiveAutomators = theWidget.getJSAutomatorManager().getActives();
						//alert(JSON.stringify(listOfActiveAutomators));
						//alert(theWidget.limitAutomatorCount);
						//              if (theWidget.limitAutomatorCount && listOfActiveAutomators.length > 0){
						//                if(!theWidget.shownLicenseWarningMessage){
						//                  theWidget.shownLicenseWarningMessage = true;
						//                  coreKit.appService.licenseWarning(coreKit.localeService.getString("scraperActiveLimitRestriction", "chrome://outwit-kernel/locale/register.properties"));
						//                }
						//                theWidget.setActiveAutomator(null,"false");
						//              }
						if (scraper.url && rating < 0.5) {
							//alert("2:"+rating);
							// XXX TODO confirm and force
							var pString = coreKit.localeService.getString("scraperNotApplicableToUrl", "chrome://outwit-kernel/locale/widgets/scraper/manager.properties");
							var pString2 = coreKit.localeService.getString("expectedUrl", "chrome://outwit-kernel/locale/widgets/scraper/manager.properties");
							pString = pString.replace(/#automatorName#/gi, scraper.name);
							//alert(pString+":\n"+widgets.page.currentURI.spec+"\n#r="+rating);
							alert(pString + "\n\n" + pString2 + "\n" + scraper.url);
							return;
						}
						//alert("3:"+rating);
						outwitHub.UIControls.getWidgetForView("scraped").pageChange();
						outwitHub.extractControls.extractors["scraped"].run({
							scraper: scraper
						});
						outwitHub.UIControls.showView("scraped");
					} else {
						//alert("0:"+rating);
						return;
					}
				} else if (scraper.url && rating < 0.5) {
					//alert("4:"+rating);
					// XXX TODO confirm and force
					var pString = coreKit.localeService.getString("scraperNotApplicableToUrl", "chrome://outwit-kernel/locale/widgets/scraper/manager.properties");
					var pString2 = coreKit.localeService.getString("expectedUrl", "chrome://outwit-kernel/locale/widgets/scraper/manager.properties");
					pString = pString.replace(/#automatorName#/gi, scraper.name);
					//alert(pString+":\n"+widgets.page.currentURI.spec+"\nr="+rating);
					alert(pString + "\n\n" + pString2 + "\n" + scraper.url);
					return;
				} else {
					//alert("5:"+rating);
					try {
						outwitHub.UIControls.getWidgetForView("scraped").pageChange();
					} catch (e) {
						ow.log.error("Strange error... No pageChange() in scraped view, got it once.", e);
					}
					outwitHub.extractControls.extractors["scraped"].run({
						scraper: scraper
					});
					outwitHub.UIControls.showView("scraped");
				}
			},
			"macro": function(aData) {
				// XXX TODO multiple, see job
				if (!outwitKit.macroExecutionManager.isRunningMacro()) {
					outwitKit.macroExecutionManager.runMacroFromId(aData.automators[0].id);
				}
			},
			"directory": function(aData) {

			},
			"job": function(aData) {
				outwitKit.jobExecutionManager.run(aData.automators[0]);
			}
		},
		observe: function(aMessage) {
			var type = aMessage.getComponent();
			if (aMessage.getEvent() == "execute") {
				try {
					var data = aMessage.getVariableDictionary();
					var ind = 0;
					var next = (function(prevAuto) {
						if (prevAuto) {
							data.automators[ind - 1] = prevAuto;
						}
						if (ind == data.automators.length) {
							this._handlers[type].call(null, data);
						} else {
							var auto = data.automators[ind];
							if (auto.isDypto() && !auto._decData) {
								++ind;
								var automatorManager = mainKit.automatorManagerService.getTypedManager(auto.type);
								var helper = ow.ui.automation.ManagerHelper.create(automatorManager);
								helper.decryptAutomator(auto, false, next);
							} else {
								++ind;
								next();
							}
						}
					}).bind(this);
					next();
				} catch (e) {
					ow.log.error("408140613", "Error executiong automators", e);
					//alert("#408140614: "+e);
				}
			}
		}
	};

	mainKit.automatorManagerService.onLoad((function() {

		Array.prototype.forEach.call(document.querySelectorAll(".automatorManagerView"), function(automatorManagerView) {
			var type;
			if (automatorManagerView && automatorManagerView.init) {
				type = automatorManagerView.getAttribute("automatorType");
				if (type != "selector") {
					var JSAutomatorManager = mainKit.automatorManagerService.getTypedManager(type);
					automatorManagerView.init(JSAutomatorManager);
					// JSAutomatorManager.load();
				}
				coreKit.observerService.subscribe(outwitHub.extractorObserver, type);
			}
		});

		Array.prototype.forEach.call(document.querySelectorAll("automatorMenupopup, .automatorMenupopup"), function(automatorMenupopup) {
			var type;
			try {
				ow.log.debug("loading menupopup " + automatorMenupopup + " " + automatorMenupopup.getAttribute("standalone"));
				if (ow.util.js.parseBool(automatorMenupopup.getAttribute("standalone"))) {
					type = automatorMenupopup.getAutomatorType();
					var JSAutomatorManager = mainKit.automatorManagerService.getTypedManager(type);
					ow.log.debug("init menupopup " + automatorMenupopup + " " + type);
					automatorMenupopup.init(JSAutomatorManager);
				}

				coreKit.observerService.subscribe(outwitHub.extractorObserver, type);
			} catch (e) {
				ow.log.debug("automatorMenupopup:" + e + " - " + e.stack);
			}
		});

		outwitHub.UIControls.loadMacroManager(true);
	}).bind(this));

};

outwitHub.loadURI = function(aURI, aRefererURI, switchToBrowser, postData, canBeMatrix) {

	// XXX all this should bette be in page widget...

	//this is a code to test if the URL to be loaded is a matrix.
	// in this case, we just load the first URL of the matrix
	if ((canBeMatrix) && (ow.data.generation.isAMatrix(aURI))) {
		var listOfUrls = ow.data.generation.generateSeries(aURI);
		aURI = listOfUrls[0];
	}

	if (outwitKit.macroExecutionManager.isRunningMacro() || outwitKit.jobExecutionManager.isJobRunning()) {

		// Prompt to ask for saving
		var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
			.getService(Components.interfaces.nsIPromptService);

		var check = {
			value: false
		}; // default the checkbox to false

		var flags = prompts.BUTTON_POS_0 * prompts.BUTTON_TITLE_NO +
			prompts.BUTTON_POS_1 * prompts.BUTTON_TITLE_YES;
		// This value of flags will create 3 buttons. The first will be "Save", the
		// second will be the value of aButtonTitle1, and the third will be "Cancel"

		var pString = coreKit.localeService.getString("stopProcessAndRun", 'chrome://outwit-modules/locale/localize.properties').replace("#ProductFullName#", ow.app.module.name);

		var button = prompts.confirmEx(null, "", pString, flags, "", "", "", null, check);

		if (button != "1") {
			return;
		}
		widgets.page.stopAll(null, true);
		// The checkbox will be hidden, and button will contain the index of the button pressed,
		// 0, 1, or 2.
	}


	widgets.page.loadURI(aURI, aRefererURI, postData);
	if (switchToBrowser) {
		outwitHub.UIControls.showView("page");
	}

};

/**
 * Set whitch components the infoBar and the logPainel will observe.
 *
 * @function
 */
outwitHub.setObserve = function() {
	var iBar = document.getElementById('infoBar');
	var lPanel = document.getElementById('logPanel');
	var lPanelPage = document.getElementById('logPanelPage');

	lPanel.init();
	lPanelPage.init();

	coreKit.observerService.subscribe(iBar, '*');
	coreKit.observerService.subscribe(lPanel, '*');
	coreKit.observerService.subscribe(lPanelPage, '*');
};

/**
 * Send a message on extractor datasheet updates
 *
 * @function
 */
outwitHub.resendEndProcessMessage = function(anExtractorName) {
	var widget = outwitHub.UIControls.getWidgetForView(anExtractorName);
	var extractor = outwitHub.extractControls.extractors[anExtractorName];
	var countFound;
	var now = Date.now();

	if (!widget) {
		ow.log.error("Can't send process message, no widget " + anExtractorName, new Error());
		return;
	}
	if (widget.XULDatasheet) {
		countFound = widget.XULDatasheet.rowCount;
	}

	//[9:59:57.442] [DEBUG] Up page modified : NULL
	//                               ow_oK_BrowserManager_upPageURI_setter()@BrowserManager.js:102
	//[9:59:57.446] [DEBUG] 25) INIT---INIT---INIT---INIT---INIT---INIT---INIT---INIT---INIT
	//                               outwitKit.browserAutoPilot()@browserAutoPilot.js:196
	//[9:59:57.509] [DEBUG] outwitHub.resendEndProcessMessage false false 0 0 undefined
	//                               outwitHub.resendEndProcessMessage()@main.js:790
	//[9:59:57.513] [DEBUG] outwitHub.resendEndProcessMessage false false 0 0 undefined
	//                               outwitHub.resendEndProcessMessage()@main.js:790
	//[9:59:57.558] [WARNING] Error updating menu images
	//[9:59:57.560] [DEBUG] outwitHub.resendEndProcessMessage false false 0 0 undefined
	//                               outwitHub.resendEndProcessMessage()@main.js:790
	//[9:59:57.561] [WARNING] Error updating menu images
	//[9:59:57.563] [DEBUG] outwitHub.resendEndProcessMessage false false 0 0 undefined
	//                               outwitHub.resendEndProcessMessage()@main.js:790




	if ((!widgets.page.extractorManager.isInstanceRunning()) && extractor.extractionFinished && extractor.lastCount != countFound && !extractor.waitToUpdateCount) {
		ow.log.debug("outwitHub.resendEndProcessMessage " + widgets.page.extractorManager.isInstanceRunning() + " " + extractor.extractionFinished + " " + extractor.lastCount + " " + countFound + " " + extractor.waitToUpdateCount);
		var messageVariableDictionary = {};
		messageVariableDictionary['#pageTitle#'] = widgets.page.title;
		messageVariableDictionary['#pageURI#'] = widgets.page.currentURI.spec;
		messageVariableDictionary['#componentName#'] = anExtractorName;
		messageVariableDictionary['#count#'] = function(postpone) {
			try {
				if (widget.XULDatasheet) {
					countFound = widget.XULDatasheet.rowCount;
				}
				extractor.lastCount = countFound;
				//extractor.waitToUpdateCount = (postpone == true);
				//alert("updated count");
				//if(postpone) alert("postponing");
			} catch (e) {
				ow.log.error("resendEndProcessMessage count error", e);
			}
			return countFound;
		};

		if (widget.XULDatasheet) {
			messageVariableDictionary['#displayedColumns#'] = function() {
				return widget.XULDatasheet.innerTree.columns.count;
			};
			messageVariableDictionary['#allColumns#'] = function() {
				return widget.JSDatasheet.getColumns().getLength();
			};
		}

		// if (!(/links|images|documents/.test(anExtractorName) && ow.app.kernel.prefs.getBool("dontExtractLinks"))) {
		coreKit.observerService.observe(new coreKit.message(anExtractorName, coreKit.message.TYPE_NOTICE, "endProcess.recount", extractor.messageVerbosity["endProcess"], messageVariableDictionary));
		// }
		//extractor.waitToUpdateCount = true;
	}
};
