Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");

// Firebug does not work at this scope, so we must define this here for logging
var console = new Object();
console.log = function(msg) {
	var consoleService = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);
 	consoleService.logStringMessage(msg);
}

var OnePasswd = new Object();
OnePasswd.initialized = false;
OnePasswd.host = "http://onepasswd.com";
OnePasswd.version = "<unknown>";
OnePasswd.errorShown = false;
OnePasswd.firstLoad = true;
OnePasswd.themePath = "";
OnePasswd.cachedVersion = -1;
OnePasswd.toolbarShouldHideWhenPopupHidden = false;

OnePasswd.QueryInterface = XPCOMUtils.generateQI([/*Ci.nsIObserver,*/ 
										Ci.nsIFormSubmitObserver,
										Ci.nsISupportsWeakReference]),


OnePasswd.removeAllChildren = function(e) {
	if (e.childNodes) {
		while (e.childNodes.length > 0) {
			e.removeChild(e.childNodes[0]);
		}
	}
}

OnePasswd.$ = function(id) {
	return document.getElementById(id);
}

OnePasswd.capitalizedTLD = function() {
	try {
		var href = getBrowser().contentWindow.location.href + "/";
		var domain = href.replace(/^http[s]*:\/\/(.*?)\/.*$/i, "$1");
		var middle = domain.replace(/^(www.)*(.*)/i, "$2");
		return middle.substring(0,1).toUpperCase() + middle.substring(1,middle.length);
	}
	catch (e) {}

	return "";
}

OnePasswd.geckoVersion = function() {
	if(OnePasswd.cachedVersion == -1)
	{
		var version = "rv:1.9"; // future proof best guess
		var prefService = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
		if(prefService) {
			try {
				version = prefService.getCharPref("browser.startup.homepage_override.mstone");
				//alert(version);
			} catch(e){}
		}
		if(version.substring(0, 6) == "rv:1.8") {
			OnePasswd.cachedVersion = 8;
		}
		else if(version.substring(0, 8) == "rv:1.9b2") {
			OnePasswd.cachedVersion = 8.5;
		}
		else {
			OnePasswd.cachedVersion = 9;
		}
	}
	return OnePasswd.cachedVersion;
}

/**
 * Register for document load/unload events
 */
window.addEventListener(
  "load",
  function () {	
    // Add a callback to be run every time a document loads.
    // note that this includes frames/iframes within the document
	if(gBrowser) {
		//gBrowser.addEventListener("DOMContentLoaded", OnePasswd.contentLoad, false);
		gBrowser.addEventListener("DOMTitleChanged", OnePasswd.domTitleChanged, false);
		gBrowser.addEventListener("pageshow", OnePasswd.contentLoad, true);
		gBrowser.addEventListener("pagehide", OnePasswd.contentUnload, true);
		gBrowser.tabContainer.addEventListener("TabSelect", OnePasswd.tabSelected, false);
		gBrowser.tabContainer.addEventListener("TabClose", OnePasswd.contentUnload, false);
	}
  },
  false
);
window.addEventListener(
  "unload",
  function () {	
	OnePasswd.xpcom().contentUnload(null);
	if(gBrowser) {
		//gBrowser.removeEventListener("DOMContentLoaded", OnePasswd.contentLoad, false);
		gBrowser.removeEventListener("DOMTitleChanged", OnePasswd.domTitleChanged, false);
		gBrowser.removeEventListener("pageshow", OnePasswd.contentLoad, true);
		gBrowser.removeEventListener("pagehide", OnePasswd.contentUnload, true);
		gBrowser.tabContainer.removeEventListener("TabClose", OnePasswd.contentUnload, false);
		gBrowser.tabContainer.removeEventListener("TabSelect", OnePasswd.tabSelected, false);
//		OnePasswd.xpcom().log(1, "removing form submit observer");
		Services.obs.removeObserver(OnePasswd, "earlyformsubmit");
	}
  },
  false
);


/**
 * Events sent to us during load sequence for Firefox 2:
 *
 *   1. about:blank
 *        - Do not do anything on this first one; FF is not ready for us.
 *   2. about:blank
 *   3. realpage.url
 *
 * NOTE: When homepage = about:blank, only the first two events come through.
 *
 * Events sent to us during the load sequence for Firefox 3:
 *
 *   1. about:blank
 *        - Do not do anything on this first one; FF is not ready for us.
 *          We set a timer to call init again on the next event loop.
 *
 */
OnePasswd.init = function(e) {
	if (OnePasswd.initialized == true) return;
	
 	if (getBrowser().contentWindow.location == "about:blank" && OnePasswd.firstLoad) {
		if (OnePasswd.geckoVersion() == 8) {
			OnePasswd.firstLoad = false;
			return;
		}
		else {
			OnePasswd.firstLoad = false;
			window.setTimeout(function() {OnePasswd.init(e)}, 0);
			return;
		}
	}
		
	try {
		OnePasswd.version = OnePasswd.xpcom().getVersion();
		window.addEventListener("input", OnePasswd.textDidChangeInTextField, true);
		OnePasswd.configVersion();
		OnePasswd.add1P2Tbb();
//		OnePasswd.xpcom().log(1, "adding form submit observer");
		Services.obs.addObserver(this, "earlyformsubmit", false);
	}
	catch (e) {
		if (!OnePasswd.errorShown && getBrowser().contentWindow.location.href != "about:blank") {
			OnePasswd.errorShown = true;
			if (confirm("The 1Password extension encountered an error:\n\n" + e + "\n\nThis is likely caused by a failure during installation and can be fixed by reinstalling 1Password. \n\nDetails on reinstalling the 1Password extension can be found in the user guide. Would you like to go there now?")) {
				getBrowser().contentWindow.location.href = "http://help.agile.ws/1Password/missing_browser_icon.html";
			}
		}
		return;
	}
	OnePasswd.initialized = true;

	//OnePasswd.contentLoad(e);
	if (!OnePasswd.xpcom().doesKeychainExist()) {
		document.getElementById("OnePassword-Toolbar").hidden = true;
	}
	else {
		document.getElementById("OnePassword-Toolbar").hidden = false;
	}
}

OnePasswd.notify = function (formElement, aWindow, actionURI) {
	if(getBrowser().contentWindow == aWindow) {
		OnePasswd.xpcom().autosave(aWindow.document);
	}
	return true; // Always return true, or form submit will be canceled.
}

OnePasswd.removeKeyComboFromExistingMenus = function(key, modifiers) {
	var newMods = modifiers.split(",");
	var keyset = document.getElementById("mainKeyset");
	if(keyset) {
		if (keyset.hasChildNodes()) {
		 	var children = keyset.childNodes;
		 	for (var i = 0; i < children.length; i++) {
				var child = children[i];
				if(child.hasAttribute('key') && child.hasAttribute('modifiers')) {
					if(child.getAttribute('key').toUpperCase() == key.toUpperCase()) {
						var existingMods = child.getAttribute('modifiers').split(",");
						var match = true;
						if(existingMods.length != newMods.length) {
							match = false;
						}
						else {
							for(var j=0; j<newMods.length; j++) {
								// TODO - allow interchangeable 'accel' and 'meta' tags (they both mean the same thing)
								if(-1 == existingMods.indexOf(newMods[j])) {
									match = false;
									break;
								}
							}
						}
						if(match == true) {
							child.removeAttribute('key');
							child.removeAttribute('modifiers');
						}
					}
				}
		 	};
		}
	}
 }

OnePasswd.updateKeyboardShortcuts = function() {
	if((null == OnePasswd.$('mi_onePasswordHUD') && null == OnePasswd.$('onepasswd_menu')) || getBrowser() == null) {
		var hotkey_data = OnePasswd.xpcom().hudHotkey();
		if(hotkey_data.length > 0) {
			var hotkey_components = hotkey_data.split("\1");		
			var hudKey = OnePasswd.$('key_onePasswordHUD');
			if(hudKey) {
				//OnePasswd.removeKeyComboFromExistingMenus(hotkey_components[0], hotkey_components[1]);
				hudKey.setAttribute('key', hotkey_components[0]);
				hudKey.setAttribute('modifiers', hotkey_components[1]);
			}
		}

		var hotkey_data = OnePasswd.xpcom().restoreFormHotkey();
		if(hotkey_data.length > 0) {
			var hotkey_components = hotkey_data.split("\1");
			var restoreKey = OnePasswd.$('key_onePasswordRestoreForm');
			if(restoreKey) {
				//OnePasswd.removeKeyComboFromExistingMenus(hotkey_components[0], hotkey_components[1]);
				restoreKey.setAttribute('key', hotkey_components[0]);
				restoreKey.setAttribute('modifiers', hotkey_components[1]);
			}
		}
		
		if(OnePasswd.xpcom().getIntProperty("ShowSeparate1PBrowserMenu", 0)) {
			var menuBar = OnePasswd.$('main-menubar');

			var menu = document.createElement('menu');
			menu.setAttribute('label', "1P");
			menuBar.appendChild(menu);
			
			var popup = document.createElement('menupopup');
			popup.setAttribute('id', "onepasswd_menu");
			popup.setAttribute('onpopupshowing', "OnePasswd.onePasswordMenuShowing(event);");
			popup.setAttribute('onpopuphiding', "OnePasswd.onePasswordMenuHiding(event);");
			menu.appendChild(popup);
		}
		var viewMenu = OnePasswd.$('menu_viewPopup');
		
		var mi = document.createElement('menuseparator');
		viewMenu.appendChild(mi);
		
		mi = document.createElement('menuitem');
		mi.setAttribute('id', 'mi_onePasswordHUD');
		mi.setAttribute('label', 'Show Logins');
		mi.setAttribute('command', 'cmd_1PasswordShowHUD');
		mi.setAttribute('key', 'key_onePasswordHUD');
		viewMenu.appendChild(mi);
		if(!OnePasswd.xpcom().getIntProperty("ShowSeparate1PBrowserMenu", 0)) {
			mi = document.createElement('menuitem');
			mi.setAttribute('id', 'mi_onePasswordRestoreForm');
			mi.setAttribute('label', 'Login with 1Password');
			mi.setAttribute('command', 'cmd_1PasswordRestoreForm');
			mi.setAttribute('key', 'key_onePasswordRestoreForm');
			viewMenu.appendChild(mi);
		}
	}
}

OnePasswd.is1PInToolbar = function() {
	var tbElem = document.getElementById("nav-bar");
	return tbElem.currentSet.indexOf("OnePassword_main_toolbarbutton") != -1;
}

OnePasswd.isToolbarInstalledPropertyName = function() {
	var base = "OPFirefox1PasswdToolbarButtonInstalled";
	try {
		var profilePath = Components.classes["@mozilla.org/file/directory_service;1"].getService( 
	                        	Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile).path;
		return base + "-" + profilePath.match(/.*\.([^\.]*)$/)[1];
	}
	catch (e) {
		return base;
	}
}

OnePasswd.add1P2Tbb = function() {
	var isInstalledPropertyName = OnePasswd.isToolbarInstalledPropertyName();
	
	if (OnePasswd.xpcom().getIntProperty(isInstalledPropertyName, 0) == 0) {
		// Just incase we are lied to
		if (OnePasswd.is1PInToolbar()) return;

		var tb = document.getElementById("nav-bar");
		tb.insertItem("OnePassword_main_toolbarbutton", document.getElementById("urlbar-container"));
		var currentset = document.getElementById("nav-bar").currentSet; 
		tb.setAttribute("currentset",currentset); 
		document.persist("nav-bar", "currentset");

		OnePasswd.xpcom().setIntProperty(isInstalledPropertyName, 1);
	}
}

OnePasswd.contentUnload = function(e) {
	if (e == null) return;

	// Fired from pagehide event
	if (e.originalTarget instanceof HTMLDocument || e.originalTarget instanceof XMLDocument) {
		var doc = e.originalTarget;
		if (e.originalTarget.defaultView.frameElement) {
			return;
		}
		if(doc != null) {
			OnePasswd.xpcom().contentUnload(doc);
		}
	}
	// Fired from TabClose
	else {
		OnePasswd.xpcom().contentUnload(e.target.linkedBrowser.contentWindow.document);
	}	
	return;
}

OnePasswd.contentLoad = function(e) {
	if (e == null) return;

	if (e.originalTarget instanceof HTMLDocument || e.originalTarget instanceof XMLDocument) {
		var doc = e.originalTarget;
		if (e.originalTarget.defaultView.frameElement) {
			// Frame within a tab was loaded. doc should be the root document of
			// the frameset.
			while(doc.defaultView.frameElement) {
			 	doc = doc.defaultView.frameElement.ownerDocument;
			}
			if(doc != null) {
				window.setTimeout(function() {OnePasswd.realContentLoad(doc)}, 0);
			}
			return;
		}
		if(doc != null) {
			window.setTimeout(function() {OnePasswd.realContentLoad(doc)}, 0);
		}
	}
	
	return;
}

OnePasswd.realContentLoad = function(contentDoc) {
//	OnePasswd.xpcom().contentLoad(contentDoc.location.href, content.document);
	if(contentDoc && contentDoc.location && contentDoc.location.href) OnePasswd.xpcom().locationChanged(contentDoc.location.href, contentDoc);
	OnePasswd.configFillFormButton(contentDoc);
}

OnePasswd.domTitleChanged = function(e) {
	if (e == null) return;

	if (e.originalTarget instanceof HTMLDocument || e.originalTarget instanceof XMLDocument) {
		var doc = e.originalTarget;
		if (e.originalTarget.defaultView.frameElement) {
			return;
		}
		if(doc != null && doc.location != null) {
			if(doc.location.href == "file:///1Password:import") {
				// Get an array of all passwords
			 	var passwordManager = Components.classes["@mozilla.org/login-manager;1"].getService(Components.interfaces.nsILoginManager);
				//OnePasswd.xpcom().log(1, "passwordManager = " + passwordManager);
				var logins = passwordManager.getAllLogins({});
				//OnePasswd.xpcom().log(1, "logins = " + logins);
				//OnePasswd.xpcom().log(1, "logins.length = " + logins.length);
				
				// Convert array type to nsIArray
			  	var array = Components.classes["@mozilla.org/array;1"].createInstance(Components.interfaces.nsIMutableArray);
				//OnePasswd.xpcom().log(1, "array = " + array);
				for(var i=0; i<logins.length; i++) {
					//OnePasswd.xpcom().log(1, "logins[" + i + "] = " + logins[i]);
					array.appendElement(logins[i], false);
				}
				OnePasswd.xpcom().importPasswords(array);
				
				getBrowser().contentWindow.location.href = "about:blank";
				return;
			}
			if(doc.location && doc.location.href) OnePasswd.xpcom().locationChanging(doc.location.href, doc);
			OnePasswd.configFillFormButton(doc);
		}
	}
}

OnePasswd.xpcom = function() {
	netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
	
//	return Components.classes['@osxform.com/osxform'].createInstance(Components.interfaces.iOsxForm);
//	alert("Components: " + Components.classes);
	dump("Dump: " + Components.classes + "\n");
	
	var obj = Components.classes["@osxform.com/osxform"].createInstance();
	obj = obj.QueryInterface(Components.interfaces.iOsxForm);
	return obj;
}

OnePasswd.tabSelected = function(e) {
	if (e == null) return;

	if (e.originalTarget instanceof HTMLDocument || e.originalTarget instanceof XMLDocument) {
		var doc = e.originalTarget;
		if (e.originalTarget.defaultView.frameElement) {
			return;
		}
		if(doc != null) {
			OnePasswd.configFillFormButton(doc);
		}
	}
	else {
		OnePasswd.configFillFormButton(e.target.linkedBrowser.contentWindow.document);
	}
}

OnePasswd.configFillFormButton = function(contentDoc) {
	var fillEl = OnePasswd.$('OnePasswordFillForm');
	if (!fillEl) return;

	var form_data = OnePasswd.xpcom().find(contentDoc, contentDoc.location.href);

	if (form_data.length == 0) {
		fillEl.label = ' Fill (none)';
	}
	else {
		fillEl.style.color = 'black';
		var forms = form_data.split("\1");
		fillEl.label = ' Fill (' + forms.length + ' matches)';
	}
}

OnePasswd.fillform = function(event) {
	var e = event.target;
	var uuid = e.getAttribute('value');
	if (e == null || uuid == 'noforms') {
		alert("You have no saved forms to use on this page.  Please save a form first.");
	}
	else {
		if(OnePasswd.xpcom().getIntProperty("FirefoxUseNewFillAlgorithm", 0) == 1) {
			var json = JSON.parse(OnePasswd.xpcom().jsonForUuid(uuid));		
			OnePasswd.brainFill("fillLogin", json, null);
		}
		else {
			OnePasswd.xpcom().fill(uuid, content.document);
		}
	}
}

OnePasswd.brainFill = function(action, json, autosubmit) {
	console.log("brainFill("+action+")");
	OPBrain(getBrowser().contentWindow, action, json);

	// TODO: add Autosubmit once we can do OPBrain.fillLogin(json, autosubmit)
	// if(null == autosubmit) {
	// 	autosubmit = true;
	// 	if (OnePasswd.xpcom().getIntProperty("autosubmit", 1) == 0) {
	// 		autosubmit = false;
	// 	}
	// }
}

OnePasswd.configVersion = function() {
	var v = "1Password v" + OnePasswd.version;
	OnePasswd.setStatusMessage(v, null, null);
}

OnePasswd.setStatusMessage = function(msg, tooltip, cmd) {
	OnePasswd.removeAllChildren(OnePasswd.$('OnePasswdMsgAreaTB'));
	OnePasswd.$('OnePasswdMsgAreaTB').appendChild(OnePasswd.msgarea(msg, tooltip, cmd));
}

OnePasswd.msgarea = function(msg, tooltip, cmd) {
	var msgarea = document.createElement('toolbarbutton');
	msgarea.setAttribute("label", msg);
	if (tooltip != null) {
		msgarea.setAttribute("tooltiptext", tooltip);
	}
	if (cmd != null) {
		msgarea.setAttribute("oncommand", cmd);
	}
	return msgarea;
}

OnePasswd.populate_formlist = function(popup) {
	var t0 = new Date();
	var curr_time = new Date();

	OnePasswd.removeAllChildren(popup);

	var t1 = new Date();
	
	var form_data = "";
	if(getBrowser()) form_data = OnePasswd.xpcom().find(content.document, content.document.location.href);
	else form_data = OnePasswd.xpcom().find(null, null);
	var t2 = new Date();
	
	if (form_data.length == 0) {
		var mi = document.createElement('menuitem');
		mi.setAttribute('label', 'No saved forms for this page');
		mi.setAttribute('id', 'nosavedforms');
		mi.setAttribute('tooltiptext', 'Once some forms have been saved on this page, they will appear here.');
		mi.setAttribute('oncommand', "OnePasswd.fillform(this, event)");
		mi.setAttribute('value', 'noforms');
		popup.appendChild(mi);
	}
	else {
		var forms = form_data.split("\1");
		var autosaved_entries = [];
		
		for (var i=0; i < forms.length; i++) {
			var values = forms[i].split("\2");
			var name = values[0];
			var uuid = values[1];

			var priority = name[0];

			var tooltipText;
			var extraClass;
			switch (priority) {
				case '0': 
					extraClass = 'low';
					break;
				case '1':
					extraClass = 'medium';
					break;
				case '2':
					extraClass = 'high';
					break;
				default:
					extraClass = 'exact';
			}

			name = name.substring(1);
			
			var mi = document.createElement('menuitem');
			mi.setAttribute('label', name);
			mi.setAttribute('oncommand', "OnePasswd.fillform(event)");
			mi.setAttribute('value', uuid);
			mi.setAttribute('class', 'menuitem-iconic ' + extraClass);

			if (!name.match( /Autosaved \(/ )) {
				popup.appendChild(mi);
			}
			else {
				autosaved_entries[autosaved_entries.length] = mi;
			}
		}

		if (autosaved_entries.length > 0) {
			if (popup.getElementsByTagName('menuitem').length > 0) {
				var sep = document.createElement('menuseparator');
				popup.appendChild(sep);
			}
		
			for (var i=0; i < autosaved_entries.length; i++) {
				popup.appendChild(autosaved_entries[i]);
			}
		}		
	}
	var t3 = new Date();
	
	// var msg = "Total time: " + (t3.getTime() - t0.getTime())
	//         + "\n\nCleanup (t0 - t1): " + (t1.getTime() - t0.getTime())
	//         + "\n\nLoad forms (t1 - t2): " + (t2.getTime() - t1.getTime())
	//         + "\n\nForm setup (t2 - t3): " + (t3.getTime() - t2.getTime());
	// alert(msg);
}

OnePasswd.clearFields = function(e) {
	OnePasswd.xpcom().clear(content.document);
}

OnePasswd.showLoginMenu = function(e) {
	if(OnePasswd.xpcom().getIntProperty("FirefoxUseNewFillAlgorithm", 0) == 1) {
		var form_data = [];
		if(getBrowser()) form_data = OnePasswd.xpcom().find(content.document, content.document.location.href);
		if(form_data.length == 0) {
			var json = JSON.parse(OnePasswd.xpcom().jsonForUuid(uuid));		
			OnePasswd.brainFill("fillLogin", json, null);
		}
		else {
			OnePasswd.xpcom().showLoginMenu(content.document);
		}
	}
	else {
		OnePasswd.xpcom().showLoginMenu(content.document);
	}
}

OnePasswd.openSaveFormDialog = function(e) {
	OnePasswd.xpcom().saveForm(content.document);
}

OnePasswd.openAbout1PasswdDialog = function(e) {
	OnePasswd.xpcom().about();
}

OnePasswd.quickGenerate = function() {
	OnePasswd.xpcom().generatePassword(content.document);
}

OnePasswd.editPasswords = function() {
	OnePasswd.xpcom().launch1Password(content.document);
}

OnePasswd.useIdentityFromHotKey = function(index) {
	var ident_data = OnePasswd.xpcom().identities(content.document);
	if (ident_data.length > 0) {
		var idents = ident_data.split("\1");
		
		if (idents.length >= index)
			var values = idents[index].split("\2");
			var name = values[0];
			var uuid = values[1];
			if(OnePasswd.xpcom().getIntProperty("FirefoxUseNewFillAlgorithm", 0) == 1) {
				OnePasswd.xpcom().log(1, "uuid = " + uuid);
				var json = JSON.parse(OnePasswd.xpcom().jsonForUuid(uuid));	
				OnePasswd.brainFill("fillIdentity", json, null);
			}
			else {
				OnePasswd.xpcom().fillIdentity(uuid, content.document);
			}
			return true;
	}

	return false;
}

OnePasswd.textDidChangeInTextField = function(e) {
	var doc = content.document;
	var textField = document.commandDispatcher.focusedElement;
	// OnePasswd.xpcom().log(1, e);
	// OnePasswd.xpcom().log(1, doc);
	// OnePasswd.xpcom().log(1, textField);
	OnePasswd.xpcom().textDidChangeInTextField(null, doc, textField);
}

OnePasswd.toggleToolbar = function() {
	var toolbar = document.getElementById("OnePassword-Toolbar");
    toolbar.collapsed = !toolbar.collapsed;
    document.persist("OnePassword-Toolbar", "collapsed");
}

OnePasswd.toggleKeychainLock = function() {
	if(OnePasswd.xpcom().isLocked()) {
		OnePasswd.unlockKeychain();
	}
	else {
		OnePasswd.lockKeychain();
	}
//	OnePasswd.setIcon();
}

OnePasswd.unlockKeychain = function() {
	OnePasswd.xpcom().unlock();
//	OnePasswd.setIcon();
}	
OnePasswd.lockKeychain = function() {
	OnePasswd.xpcom().lock();
//	OnePasswd.setIcon();
}

OnePasswd.setIcon = function(reschedule) {
	if (!OnePasswd.xpcom().doesKeychainExist()) return;
	
	if (OnePasswd.$('OnePassword_main_toolbarbutton')) {
		if (OnePasswd.xpcom().isLocked()) {
			OnePasswd.$('OnePassword_main_toolbarbutton').setAttribute('keychain', 'locked');
		}
		else {
			OnePasswd.$('OnePassword_main_toolbarbutton').setAttribute('keychain', 'unlocked');
		}
	}

	if (reschedule == true) {
		self.setTimeout('OnePasswd.setIcon(true);', 15000);
	}
}

OnePasswd.showGoAndFillHUD = function(e) {
	OnePasswd.xpcom().showHUD(2);
}

// We can assume keychain exists b/c toolbar is hidden otherwise
OnePasswd.configureToolbarPopup = function() {
	OnePasswd.registered = OnePasswd.xpcom().isRegd(false) == 1;
	OnePasswd.$('tb_1passwd_purchase_mi').hidden = OnePasswd.registered;

/*	var locked = OnePasswd.xpcom().isLocked();
	OnePasswd.$('tb_unlock_keychain_mi').hidden = !locked;
	OnePasswd.$('tb_lock_keychain_mi').hidden = locked;
*/	
	if (OnePasswd.xpcom().isAutosave()) {
		OnePasswd.$('tb_autosave_mi').setAttribute("checked","true"); 
	} else {
		OnePasswd.$('tb_autosave_mi').removeAttribute("checked"); 
	}
	
	var autosubmit = true;
	if (OnePasswd.xpcom().getIntProperty("autosubmit", 1) == 0) {
		autosubmit = false;
	}
	if (autosubmit) {
		OnePasswd.$('tb_autosubmit_mi').setAttribute("checked","true"); 
	} else {
		OnePasswd.$('tb_autosubmit_mi').removeAttribute("checked"); 
	}
}


OnePasswd.toggleAutoSave = function() {
	OnePasswd.xpcom().setAutosave(!OnePasswd.xpcom().isAutosave());
}

OnePasswd.toggleAutoSubmit = function() {
	var autosubmit = OnePasswd.xpcom().getIntProperty("autosubmit", 1);
	if (autosubmit == 0) {
		autosubmit = 1;
	}
	else {
		autosubmit = 0;
	}
	OnePasswd.xpcom().setIntProperty("autosubmit", autosubmit);
}

OnePasswd.purchase = function() {
	window.open("https://agilewebsolutions.com/store", "Purchase 1Password");
}

OnePasswd.fillPopupWithData = function(popup, data) {
	var i;
	var length = data.length;
	for(i=0; i<length; i++) {
		var dataNode = data.queryElementAt(i, Components.interfaces.nsIArray);
		
		if(dataNode.length > 0) {
			var title = dataNode.queryElementAt(0, Components.interfaces.nsISupportsString);
			var representedObjectType = dataNode.queryElementAt(1, Components.interfaces.nsISupportsString);
			var representedObject = dataNode.queryElementAt(2, Components.interfaces.nsISupportsString);
			var checked = dataNode.queryElementAt(3, Components.interfaces.nsISupportsString);
			var enabled = dataNode.queryElementAt(4, Components.interfaces.nsISupportsString);
			var target = dataNode.queryElementAt(5, Components.interfaces.nsISupportsString);
			var action = dataNode.queryElementAt(6, Components.interfaces.nsISupportsString);
			
			if(dataNode.length > 7) {
				// OnePasswd.xpcom().log(1, "i = " + i);
				var m = document.createElement('menu');
				m.setAttribute('id', "agmenu");
				// OnePasswd.xpcom().log(1, "m.id = " + m.id);
				var existing = popup.childNodes[i];
			// if(existing) OnePasswd.xpcom().log(1, "Existing id = " + existing.id);
			// else OnePasswd.xpcom().log(1, "Existing = " + existing);
				
				if(existing && existing.id == "agmenu") {
					// OnePasswd.xpcom().log(1, "Using existing" + existing);
					m = existing;
				}
				else if(existing) {
					// OnePasswd.xpcom().log(1, "Removing existing");
					popup.insertBefore(m, existing);
					popup.removeChild(existing);
				}
				else {
					popup.appendChild(m);
				}
				
				var children = dataNode.queryElementAt(7, Components.interfaces.nsIArray);
				m.setAttribute('label', title);
                //OnePasswd.xpcom().log(1, title + " children count = " + children.length);
				
				var p = document.createElement('menupopup');
				p.setAttribute('id', "agitemspopup");
				// OnePasswd.xpcom().log(1, "array length = " + m.childNodes.length);
				var existingPopup = m.firstChild;
			// if(existingPopup) OnePasswd.xpcom().log(1, "ExistingPopup id = " + existingPopup.id);
			// else OnePasswd.xpcom().log(1, "ExistingPopup = " + existingPopup);

				if(existingPopup && existingPopup.id == "agitemspopup") {
				 	p = existingPopup;
				}
				else if(existingPopup) {
					m.insertBefore(p, existingPopup);
					m.removeChild(existingPopup);
				}
				else {
					m.appendChild(p);
				}
				
				OnePasswd.fillPopupWithData(p, children);
			}
			else {
				// OnePasswd.xpcom().log(1, "i = " + i);
				var mi = document.createElement('menuitem');
				mi.setAttribute('id', "agmenuitem");
				var existing = popup.childNodes[i];
			// if(existing) OnePasswd.xpcom().log(1, "Existing id = " + existing.id);
			// else OnePasswd.xpcom().log(1, "Existing = " + existing);
				if(existing && existing.id == "agmenuitem") {
					// OnePasswd.xpcom().log(1, "Using existing" + existing);
					mi = existing;
				}
				else if(existing) {
					// OnePasswd.xpcom().log(1, "Removing existing");
					popup.insertBefore(mi, existing);
					popup.removeChild(existing);
				}
				else {
					popup.appendChild(mi);
				}
				
				mi.setAttribute('label', title);
				
				if(enabled == "false") mi.setAttribute('disabled', "true");
				else mi.setAttribute('disabled', "false");
				
				if(checked == "true") {
					mi.setAttribute('type', "checkbox");
					mi.setAttribute('autocheck', "false");
					mi.setAttribute('checked', "true");
				}
				else {
					mi.setAttribute('type', "checkbox");
					mi.setAttribute('autocheck', "false");
					mi.setAttribute('checked', "false");
				}
				mi.setAttribute('oncommand', "OnePasswd.performMenuItem(event);");
				var value = target + "\1" + action + "\1" + representedObjectType + "\1" + representedObject;
				mi.setAttribute('value', value);
			}
		}
		else {
			// OnePasswd.xpcom().log(1, "i = " + i);
			var mi = document.createElement('menuseparator');
			mi.setAttribute('id', "agmenuseparator");
			var existing = popup.childNodes[i];
		// if(existing) OnePasswd.xpcom().log(1, "Existing id = " + existing.id);
		// else OnePasswd.xpcom().log(1, "Existing = " + existing);			
			if(existing && existing.id == "agmenuseparator") {
				// OnePasswd.xpcom().log(1, "Using existing" + existing);
				mi = existing;
			}
			else if(existing) {
				// OnePasswd.xpcom().log(1, "Removing existing");
				popup.insertBefore(mi, existing);
				popup.removeChild(existing);
			}
			else {
				popup.appendChild(mi);
			}
		}
	}

	// remove extra items here
	var j = i;
	for(j = i; j < popup.childNodes.length; j++) {
        //OnePasswd.xpcom().log(1, "Removing existing " + j + " " + popup.childNodes[j].getAttribute('label'));
		popup.removeChild(popup.childNodes[j]);
        j--;
	}
}

OnePasswd.performMenuItem = function(e) {
	var title = e.target.getAttribute('label');
	var value = e.target.getAttribute('value');
	var params = value.split("\1");
	var target = params[0];
	var action = params[1];
	var representedObjectType = params[2];
	var representedObject = params[3];
	
	if(OnePasswd.xpcom().getIntProperty("FirefoxUseNewFillAlgorithm", 0) == 1) {
		//OnePasswd.xpcom().log(1, "representedObjectType = " + representedObjectType);
		var json = null;
		if(representedObjectType == "uuid") {
			json = JSON.parse(OnePasswd.xpcom().jsonForUuid(representedObject));	
		}
		//OnePasswd.xpcom().log(1, "json = " + json);
	
		// Re-route filling code into JS Brain
		//OnePasswd.xpcom().log(1, "Action string = " + action);
		if(action == "fillForm:" && json) {
			OnePasswd.brainFill("fillLogin", json, false);
		}
		else if(action == "fillAndSubmitForm:" && json) {
			OnePasswd.brainFill("fillLogin", json, true);
		}
		else if(action == "fillWalletItem:" && json) {
			OnePasswd.brainFill("fillCreditCard", json, null);
		}
		else if(action == "fillIdentity:" && json) {
			OnePasswd.brainFill("fillIdentity", json, null);
		}
		else {
			// Otherwise, send back to cocoa to perform action
			OnePasswd.xpcom().performTargetAction(title, target, action, representedObjectType, representedObject);
		}
	}
	else {
		OnePasswd.xpcom().performTargetAction(title, target, action, representedObjectType, representedObject);
	}
}

OnePasswd.onePasswordMenuShowing = function(e) {
	var popup = e.target;
	
	OnePasswd.$('OnePasswdContextItem').hidden = (OnePasswd.xpcom().getIntProperty("AddShortcutMenu", 1) == 0);
	if (OnePasswd.$('OnePasswdContextItem').hidden && popup == OnePasswd.$('onepasswd_context_menu')) 
		return;

	if(popup != OnePasswd.$('onepasswd_menu') &&
		popup != OnePasswd.$('onepasswd_context_menu') &&
		popup != OnePasswd.$('onepasswd_toolbar_menu'))
		return;
	
	if(window) {
		//OnePasswd.xpcom().log(1, "Adding keypress listener");
		window.addEventListener("keydown", OnePasswd.keyPressedInMenu, true);
		window.addEventListener("keyup", OnePasswd.keyPressedInMenu, true);
	}
	
	OnePasswd.fillOnePasswordMenu(popup);
}

OnePasswd.onePasswordMenuHiding = function(e) {
	var popup = e.target;
	if(popup != OnePasswd.$('onepasswd_menu') &&
		popup != OnePasswd.$('onepasswd_context_menu') &&
		popup != OnePasswd.$('onepasswd_toolbar_menu'))
		return;
		
	//OnePasswd.xpcom().log(1, "OnePasswordMenuHiding");
	if(window) {
		//OnePasswd.xpcom().log(1, "Removing keypress listener");
		window.removeEventListener("keydown", OnePasswd.keyPressedInMenu, true);
		window.removeEventListener("keyup", OnePasswd.keyPressedInMenu, true);
	}
}

OnePasswd.fillOnePasswordMenu = function(popup) {
	//OnePasswd.removeAllChildren(popup);
	var menu_data = null;
	if(getBrowser() != null) menu_data = OnePasswd.xpcom().fullMenu(content.document);
	else menu_data = OnePasswd.xpcom().fullMenu(null);
	OnePasswd.fillPopupWithData(popup, menu_data);
}

OnePasswd.keyPressedInMenu = function(e) {
//	OnePasswd.xpcom().log(1, "keyPressedInMenu " + e.keyCode);
	var popup = null;
	if(OnePasswd.$('onepasswd_menu') && OnePasswd.$('onepasswd_menu').state == "open") popup = OnePasswd.$('onepasswd_menu');
	else if(OnePasswd.$('onepasswd_context_menu') && OnePasswd.$('onepasswd_context_menu').state == "open") popup = OnePasswd.$('onepasswd_context_menu');
	else if(OnePasswd.$('onepasswd_toolbar_menu') && OnePasswd.$('onepasswd_toolbar_menu').state == "open") popup = OnePasswd.$('onepasswd_toolbar_menu');
	else return;
	
//	OnePasswd.xpcom().log(1, "keyPressedInMenu " + e.keyCode);
	if(e.keyCode == 0x10 || // shift
	   e.keyCode == 0x11 || // control
	   e.keyCode == 0x12 || // option
	   e.keyCode == 0xE0 // command
		) {
		// Re-load popup with data
		var openchildren = OnePasswd.getOpenChildrenOfPopup(popup);
		//OnePasswd.xpcom().log(1, "openchildren " + openchildren);
		OnePasswd.fillOnePasswordMenu(popup);
		OnePasswd.setOpenChildrenOfPopup(popup, openchildren);
	}
}

OnePasswd.getOpenChildrenOfPopup = function(popup) {
	var openchildren = new Array();

	for(var i=0; popup.childNodes && i<popup.childNodes.length; i++) {
		if(!popup.childNodes[i].childNodes || popup.childNodes[i].childNodes.length <= 0) continue;
		if(popup.childNodes[i].childNodes[0].state == "open") {
			openchildren.push(i);
			openchildren = openchildren.concat(OnePasswd.getOpenChildrenOfPopup(popup.childNodes[i].childNodes[0]));
			break;
		}
	}
	return openchildren;
}

OnePasswd.setOpenChildrenOfPopup = function(popup, openchildren) {
	if(openchildren.length <= 0) return;

	//OnePasswd.xpcom().log(1, "setOpenChildrenOfPopup numChildren = " + popup.childNodes.length);
	
	var childIndex = openchildren[0];
	//OnePasswd.xpcom().log(1, "trying to open child at index " + childIndex + " which has numChildren = " + popup.childNodes[childIndex].childNodes.length);
	if(!popup.childNodes[childIndex].childNodes || popup.childNodes[childIndex].childNodes.length <= 0) return;
	//OnePasswd.xpcom().log(1, popup.childNodes[childIndex].childNodes[0]);
	popup.childNodes[childIndex].childNodes[0].showPopup();
	//OnePasswd.xpcom().log(1, "done");
	openchildren.shift();
	OnePasswd.setOpenChildrenOfPopup(popup.childNodes[childIndex].childNodes[0], openchildren);
}

OnePasswd.identity_popupshown = function(e) {
	OnePasswd.populate_identity_popup(e.target);
}

OnePasswd.restore_form_popupshown = function(e) {	
	OnePasswd.populate_formlist(e.target);
}

OnePasswd.restore_form_popuphidden = function(e) {
	if (OnePasswd.toolbarShouldHideWhenPopupHidden) {
		var toolbar = document.getElementById("OnePassword-Toolbar");
		toolbar.collapsed = true;
		OnePasswd.toolbarShouldHideWhenPopupHidden = false;
	}
}

OnePasswd.populate_identity_popup = function(popup) {
	OnePasswd.removeAllChildren(popup);

	var index = 0;
	var ident_data = "";
	if(getBrowser()) ident_data = OnePasswd.xpcom().identities(content.document);
	else ident_data = OnePasswd.xpcom().identities(null);
	
	if (ident_data.length == 0) {
		var mi = document.createElement('menuitem');
		mi.setAttribute('label', 'You have no identities defined');
		mi.setAttribute('id', 'noidents');
		mi.setAttribute('tooltiptext', 'Once you create some indentities using 1Password, they appear here.');
		mi.setAttribute('oncommand', "");
		popup.appendChild(mi);
	}
	else {
		var idents = ident_data.split("\1");
		for (var i=0; i < idents.length; i++) {
			var values = idents[i].split("\2");
			var name = values[0].substring(1);
			var uuid = values[1];
			
			var mi = document.createElement('menuitem');
			mi.setAttribute('label', name);
			mi.setAttribute('oncommand', "OnePasswd.useIdentity(event);");
			mi.setAttribute('value', uuid);
			
			if (index < 3) {
				mi.setAttribute('key', 'onepasswd-use-identity-' + index);
				index = index + 1;
			}
			popup.appendChild(mi);
		}
	}
}

OnePasswd.useIdentity = function(e) {
	var uuid = e.target.value;
	if(OnePasswd.xpcom().getIntProperty("FirefoxUseNewFillAlgorithm", 0) == 1) {
		OnePasswd.xpcom().log(1, "uuid = " + uuid);
		var json = JSON.parse(OnePasswd.xpcom().jsonForUuid(uuid));	
		OnePasswd.brainFill("fillIdentity", json, null);
	}
	else {
		OnePasswd.xpcom().fillIdentity(uuid, content.document);
	}
}

OnePasswd.wallet_popupshown = function(e) {
	OnePasswd.populate_wallet_popup(e.target);
}

OnePasswd.populate_wallet_popup = function(popup) {
	OnePasswd.removeAllChildren(popup);

	var wallet_data = "";
	if(getBrowser()) wallet_data = OnePasswd.xpcom().wallet(content.document);
	else wallet_data = OnePasswd.xpcom().wallet(null);
	
	if (wallet_data.length == 0) {
		var mi = document.createElement('menuitem');
		mi.setAttribute('label', 'You have no wallet items defined');
		mi.setAttribute('id', 'noidents');
		mi.setAttribute('tooltiptext', 'Once you create some wallet entries using 1Password, they appear here.');
		mi.setAttribute('oncommand', "");
		popup.appendChild(mi);
	}
	else {
		var items = wallet_data.split("\1");
		for (var i=0; i < items.length; i++) {
			var values = items[i].split("\2");
			var name = values[0].substring(1);
			var uuid = values[1];
			
			var mi = document.createElement('menuitem');
			mi.setAttribute('label', name);
			mi.setAttribute('oncommand', "OnePasswd.useWallet(event);");
			mi.setAttribute('value', uuid);
			popup.appendChild(mi);
		}
	}
}

OnePasswd.useWallet = function(e) {
	var uuid = e.target.value;
	if(OnePasswd.xpcom().getIntProperty("FirefoxUseNewFillAlgorithm", 0) == 1) {
		OnePasswd.xpcom().log(1, "uuid = " + uuid);
		var json = JSON.parse(OnePasswd.xpcom().jsonForUuid(uuid));	
		OnePasswd.brainFill("fillCreditCard", json, null);
	}
	else {
		OnePasswd.xpcom().fillWallet(uuid, content.document);
	}
}

OnePasswd.openPreferences = function() {
	OnePasswd.xpcom().openPreferences();
}

const kPromptServiceUUID = "{c27e8561-611f-4c4b-a24c-cdf611f8a069}";
const kPromptServiceContractID = "@mozilla.org/embedcomp/prompt-service;1";
const kOriginalPromptServiceContractID = "@mozilla.org/embedcomp/original-prompt-service;1";

let opPromptService = {
    classID          : Components.ID(kPromptServiceUUID),
	QueryInterface: XPCOMUtils.generateQI([Ci.nsIPromptService, Ci.nsIPromptService2]),

	/* ----------  nsIPromptService  ---------- */

	alert : function (domWin, title, text) {
		var originalPromptService = Components.classes[kOriginalPromptServiceContractID].getService(Components.interfaces.nsIPromptService2);
		return originalPromptService.alert(domWin, title, text);
	},

	alertCheck : function () {
		var originalPromptService = Components.classes[kOriginalPromptServiceContractID].getService(Components.interfaces.nsIPromptService2);
		return originalPromptService.alertCheck(domWin, title, text, checkLabel, checkValue);
	},

	confirm : function (domWin, title, text) {
		var originalPromptService = Components.classes[kOriginalPromptServiceContractID].getService(Components.interfaces.nsIPromptService2);
		return originalPromptService.confirm(domWin, title, text);
	},

	confirmCheck : function (domWin, title, text, checkLabel, checkValue) {
		var originalPromptService = Components.classes[kOriginalPromptServiceContractID].getService(Components.interfaces.nsIPromptService2);
		return originalPromptService.confirmCheck(domWin, title, text, checkLabel, checkValue);
	},

	confirmEx : function (domWin, title, text, flags, button0, button1, button2, checkLabel, checkValue) {
		var originalPromptService = Components.classes[kOriginalPromptServiceContractID].getService(Components.interfaces.nsIPromptService2);
		return originalPromptService.confirmEx(domWin, title, text, flags, button0, button1, button2, checkLabel, checkValue);
	},

	prompt : function (domWin, title, text, value, checkLabel, checkValue) {
		var originalPromptService = Components.classes[kOriginalPromptServiceContractID].getService(Components.interfaces.nsIPromptService2);
		return originalPromptService.prompt(domWin, title, text, value, checkLabel, checkValue);
	},

	promptUsernameAndPassword : function (domWin, title, text, user, pass, checkLabel, checkValue) {
		var originalPromptService = Components.classes[kOriginalPromptServiceContractID].getService(Components.interfaces.nsIPromptService2);
		return originalPromptService.promptUsernameAndPassword(domWin, title, text, user, pass, checkLabel, checkValue);
	},

	promptPassword : function (domWin, title, text, pass, checkLabel, checkValue) {
		var originalPromptService = Components.classes[kOriginalPromptServiceContractID].getService(Components.interfaces.nsIPromptService2);
		return originalPromptService.promptPassword(domWin, title, text, pass, checkLabel, checkValue);
	},

	select : function (domWin, title, text, count, list, selected) {
		var originalPromptService = Components.classes[kOriginalPromptServiceContractID].getService(Components.interfaces.nsIPromptService2);
		return originalPromptService.select(domWin, title, text, count, list, selected);
	},

	/* ----------  nsIPromptService2  ---------- */

	promptAuth : function (domWin, channel, level, authInfo, checkLabel, checkValue) {
		return OnePasswd.xpcom().promptAuth(domWin, channel, level, authInfo, checkLabel, checkValue);
	},

	asyncPromptAuth : function (domWin, channel, callback, context, level, authInfo, checkLabel, checkValue) {
		var originalPromptService = Components.classes[kOriginalPromptServiceContractID].getService(Components.interfaces.nsIPromptService2);
		return originalPromptService.asyncPromptAuth(domWin, channel, callback, context, level, authInfo, checkLabel, checkValue);
	},
};

let opPromptServiceFactory = {
	classID : Components.ID("{1ea74406-2489-4cef-812a-a83df9ee5101}"),
	createInstance : function(aOuter, aIid) {
		if (aOuter != null)
		throw Cr.NS_ERROR_NO_AGGREGATION;
		return opPromptService.QueryInterface(aIid);
	}
};

registerPromptService = function()
{	
	//OnePasswd.xpcom().log(1, "start registerPromptService");
	
	// Get the component registrar
	var registrar = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
	if(!registrar) {
		OnePasswd.xpcom().log("Couldn't get component registrar");
		return;
	}
	
	// Don't reregister if we have already done the swap
	originalCID = registrar.contractIDToCID(kPromptServiceContractID);
	//OnePasswd.xpcom().log(1, "ID = " + originalCID);
	if((""+originalCID) == (""+Components.ID(kPromptServiceUUID))) {
		OnePasswd.xpcom().log(1, "already registered");
		return;
	}
 		
	// Find existing prompt service factory
	var originalPromptServiceFactory = Components.manager.getClassObject(Components.classes[kPromptServiceContractID], Components.interfaces.nsIFactory);	
	//OnePasswd.xpcom().log(1, "factory = " + originalPromptServiceFactory);
	if (!originalPromptServiceFactory) {
		OnePasswd.xpcom().log("Couldn't find existing prompt service factory.");
        return;
	}
	
	// Unregister old
	registrar.unregisterFactory(registrar.contractIDToCID(kPromptServiceContractID), originalPromptServiceFactory);

	// Register ourself as prompt-service
	registrar.registerFactory(Components.ID(kPromptServiceUUID), "Prompt Service",
	                             kPromptServiceContractID,
	                             opPromptServiceFactory);
	

	// Register old as original-prompt-service
	registrar.registerFactory(originalCID, "Original Prompt Service",
	                             kOriginalPromptServiceContractID,
	                             originalPromptServiceFactory);

	//OnePasswd.xpcom().log(1, "finish registerPromptService");
}

if(!OnePasswd.xpcom().getIntProperty("Disable1PasswdHttpAuthWindows", 0) == 1) {
	registerPromptService();
}