var usernameInput = null;
var passwordInput = null;
var submitInput = null;

var isChrome = false;

if (typeof browser === 'undefined') {
	isChrome = true;
	browser = chrome;
}

var sendMessage = function(id, data) {
	browser.runtime.sendMessage({"path":'page-to-background', "method": id, "data" : data});
}

var loginForm = null;

function getMeaningfulText(node) {
	// return the alt text for images, if it exists
	if (node.tagName.toLowerCase() == "img" && node.alt != null)
		return  node.alt.trim();
	// return the inner text if it's not an image or doesn't have alt text
	if (node.innerText)
		return node.innerText.trim();
	// and the innerHTML if all else fails
	return node.innerHTML.trim();
}

function getInnermostText(node) {
	//var innermost = node;
	var i = 0;
	if (node.children.length > 0) {
		best_text = ""
		for (i = 0; i < node.children.length; i++) {
			tmp = getInnermostText(node.children[i]);
			if (tmp.length > best_text.length) {
				best_text = tmp
			}
		}
		// now we return the best option
		return best_text;
	} else {
		// Node has no children
		return getMeaningfulText(node);
	}
}

var loginTextSet = new Set(["Sign in", "Sign In", "Signin", "Log in", "Log In", "Login", "LOGIN", "LOGON", "SIGNIN", "SIGNON", "SIGN IN", "SIGN ON", "LOG IN", "LOG ON", "Next", "NEXT", "Continue"]);

function searchForForms() {
	var formTags = document.getElementsByTagName("Form");
	for (i = 0; i < formTags.length; i++) {
		searchForInputs(formTags.item(i))
		if (submitInput != null && (usernameInput != null || passwordInput != null)) {
			// good enough for an attempt to login
			break;
		}
	}
}

function searchForInputs(form) {
	var buttons = form.getElementsByTagName("button");
	var inputs = form.getElementsByTagName("input");
	var anchors = form.getElementsByTagName("a");
	var tempSubmitInput = null;
	var tempUsernameInput = null;
	var tempPasswordInput = null;
	for (j = 0; j < buttons.length && submitInput == null; j++) {
		var button = buttons.item(j);
		if (loginTextSet.has(getInnermostText(button))) {
			tempSubmitInput = button;
			break;
		}
	}
	for (j = 0; j < inputs.length && tempSubmitInput == null; j++) {
		var input = inputs.item(j);
		if (input.getAttribute("type") == "submit") {
			var isLoginButton = false;
			if (!isLoginButton && loginTextSet.has(input.value)) {
				isLoginButton = true;
			}
			var inputParent = input.parentNode;
			if (!isLoginButton && inputParent.tagName.toLowerCase() == "span") {
				var siblings = inputParent.children;
				for (y = 0; y < siblings.length; y++) {
					var sibling = siblings.item(y);
					var siblingText = getInnermostText(sibling);
					if (loginTextSet.has(siblingText)) {
						isLoginButton = true;
						break;
					}
				}
			}
			if (isLoginButton) {
				tempSubmitInput = input;
			}
		}
	}
	for (j = 0; j < anchors.length && tempSubmitInput == null; j++) {
		var anchor = anchors.item(j);
		var anchorText = getInnermostText(anchor);
		if (loginTextSet.has(anchorText)) {
			tempSubmitInput = anchor;
			break;
		}
	}
	for (k = 0 ; k < inputs.length && (tempUsernameInput == null || tempPasswordInput == null); k++) {
		var input = inputs.item(k);
		if (input.type == "text" || input.type == "email" || input.type == null || input.type == "") {
			tempUsernameInput = input;
		} else if (input.type == "password") {
			tempPasswordInput = input;
			break;
		}
	}
	if (tempSubmitInput != null && (tempUsernameInput != null || tempPasswordInput != null))  {
		var betterMatchFound = false;
		var bestMatchFound = false;
		if (tempUsernameInput != null && tempPasswordInput != null) {
			// if we have the submit button, username and password, stop looking
			betterMatchFound = true;
			bestMatchFound = true;
		} else if (tempUsernameInput != null && usernameInput == null) {
			// if we didn't have a username field from before, but we found one here
			// we want to use this form. We don't check for a password here because
			// the user may be on a site that has the username and password on
			// separate pages.
			betterMatchFound = true;
		} else if (tempPasswordInput != null) {
			betterMatchFound = true;
		}
		if (betterMatchFound) {
			usernameInput = tempUsernameInput;
			passwordInput = tempPasswordInput;
			submitInput = tempSubmitInput;
			if (bestMatchFound) {
				return;
			}
		}
	}
}

function finishLoading() {
	searchForForms();
	// if we don't have enough to attempt to log in, search harder
	if (submitInput == null || (usernameInput == null && passwordInput == null)) {
		searchForInputs(document);
	}

	var data = {messageType: "pageLoaded", url: window.location.href};
	if (submitInput != null && (usernameInput != null || passwordInput != null)) {
		data.hasLoginForm = true;
		data.hasUsernameField = true;
		if (passwordInput != null) {
			data.hasPasswordField = true;
		}
		sendMessage("pageLoaded", data);
	}
}
setTimeout(finishLoading, 4000); // wait a few seconds so elements appear in the DOM

browser.runtime.onMessage.addListener(function (req, sender, res) {
	var request = JSON.parse(req);
	if (request.method == "loadPage") {
		var data = {messageType: "pageLoaded", url: window.location.href};
		if (submitInput != null && (usernameInput != null || passwordInput != null)) {
			data.hasLoginForm = true;
			data.hasUsernameField = true;
			if (passwordInput != null) {
				data.hasPasswordField = true;
			}
			sendMessage("pageLoaded", data);
		}
	} else if (request.method == "fill") {
		searchForInputs(document); // new inputs may have appeared
		if (usernameInput != null && request.username != null) {
			usernameInput.value = request.username;
			usernameInput.dispatchEvent(
				new Event("input", { bubbles: true, cancelable: true })
			);  // triggers any JS handlers, which is important on some sites
		}
		if (passwordInput != null && request.password != null) {
			passwordInput.value = request.password;
			passwordInput.dispatchEvent(
				new Event("input", { bubbles: true, cancelable: true })
			);  // triggers any JS handlers, which is important on some sites
		}
		if ((usernameInput != null || passwordInput != null) && submitInput != null) {
			// we want to click the button as long as we have either
			// a username or password (and a button to click)
			submitInput.click();
		}
		// after we've submitted this form, clear out all the inputs so
		// we don't try to use them after the DOM has changed (for
		// those single-page sign-on screens that separate the username
		// from the password).
		submitInput = usernameInput = passwordInput = null;
	}
	return true;
});
