/*
 * This Source Code is subject to the terms of the Mozilla Public License
 * version 2.0 (the "License"). You can obtain a copy of the License at
 * http://mozilla.org/MPL/2.0/.
 */

let nodes = null;
let item = null;
let advancedMode = false;

function init()
{
	
var gabPref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
	
var abURL = gabPref.getCharPref("extensions.adblockplus.Blockitem");
var abType = gabPref.getCharPref("extensions.adblockplus.BlockitemType");



	var abDomain="",abURL2=abURL;
	if(abURL.indexOf(".")>-1){
	abURL2=abURL.substring(abURL.indexOf("//") +2);
		if(abURL.indexOf("www.")>-1){
			var abURL2=abURL.substring(abURL.indexOf("www.") +4);
		}
	var abDomain=abURL2.substring(0,abURL2.indexOf(".")+4);
	}


	
item={filter:null,location:abURL,docDomain:abDomain,thirdParty:false,typeDescr:abType,type:""};
		
setCharPref("extensions.adblockplus.Blockitem","");	
	
//[nodes, item] = window.arguments;
//	E("filterType").value = (!item.filter || item.filter.disabled || item.filter instanceof WhitelistFilter ? "filterlist" : "whitelist");
	E("filterType").value = "filterlist" ;

	E("customPattern").value = item.location;

	let insertionPoint = E("customPatternBox");
	let addSuggestion = function(address)
	{
		// Always drop protocol and www. from the suggestion
		address = address.replace(/^[\w\-]+:\/+(?:www\.)?/, "");

		let suggestion = document.createElement("radio");
		suggestion.setAttribute("value", address);
		suggestion.setAttribute("label", address);
		suggestion.setAttribute("crop", "center");
		suggestion.setAttribute("class", "suggestion");
		insertionPoint.parentNode.insertBefore(suggestion, insertionPoint);

		return address;
	}

	let ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
	try
	{
		let suggestions = [""];

		let url = ioService.newURI(item.location, null, null)
											 .QueryInterface(Ci.nsIURL);
		let suffix = (url.query ? "?*" : "");
		url.query = "";
		suggestions[1] = addSuggestion(url.spec + suffix);

		let parentURL = ioService.newURI(url.fileName == "" ? ".." : ".", null, url);
		if (!parentURL.equals(url))
			suggestions[2] = addSuggestion(parentURL.spec + "*");
		else
			suggestions[2] = suggestions[1];

		let rootURL = ioService.newURI("/", null, url);
		if (!rootURL.equals(parentURL) && !rootURL.equals(url))
			suggestions[3] = addSuggestion(rootURL.spec + "*");
		else
			suggestions[3] = suggestions[2];

		try
		{
			suggestions[4] = addSuggestion(url.host.replace(/^www\./, "") + "^");

			// Prefer example.com^ to example.com/*
			let undesired = suggestions[4].replace(/\^$/, "/*");
			for (let i = 0; i < suggestions.length - 1; i++)
				if (suggestions[i] == undesired)
					suggestions[i] = suggestions[4];

			for (let child = insertionPoint.parentNode.firstChild; child; child = child.nextSibling)
			{
				if (child.localName == "radio" && child.getAttribute("value") == undesired)
				{
					child.parentNode.removeChild(child);
					break;
				}
			}
		}
		catch (e)
		{
			suggestions[4] = suggestions[3];
		}

		try
		{
			let effectiveTLD = Cc["@mozilla.org/network/effective-tld-service;1"].getService(Ci.nsIEffectiveTLDService);
			let host = url.host;
			let baseDomain = effectiveTLD.getBaseDomainFromHost(host);
			if (baseDomain != host.replace(/^www\./, ""))
				suggestions[5] = addSuggestion(baseDomain + "^");
			else
				suggestions[5] = suggestions[4];
		}
		catch (e)
		{
			suggestions[5] = suggestions[4];
		}

		E("patternGroup").value = (Prefs.composer_default in suggestions ? suggestions[Prefs.composer_default] : suggestions[1]);
	}
	catch (e)
	{
		// IOService returned nsIURI - not much we can do with it
		addSuggestion(item.location);
		E("patternGroup").value = "";
	}
	if (Prefs.composer_default == 0)
		E("customPattern").focus();
	else
		E("patternGroup").focus();

	let types = [];
	for (let type in Policy.localizedDescr)
	{
		types.push(parseInt(type));
	}
	types.sort(function(a, b) {
		if (a < b)
			return -1;
		else if (a > b)
			return 1;
		else
			return 0;
	});

	let docDomain = item.docDomain;
	let thirdParty = item.thirdParty;

	if (docDomain)
		docDomain = docDomain.replace(/^www\./i, "").replace(/\.+$/, "");
	if (docDomain)
		E("domainRestriction").value = docDomain;

	E("thirdParty").hidden = !thirdParty;
	E("firstParty").hidden = thirdParty;

	let typeGroup = E("typeGroup");
	let defaultTypes = RegExpFilter.prototype.contentType & ~RegExpFilter.typeMap.DOCUMENT;
	let isDefaultType = (RegExpFilter.typeMap[item.typeDescr] & defaultTypes) != 0;
	for each (let type in types)
	{
		if (type == Policy.type.ELEMHIDE)
			continue;

		let typeNode = document.createElement("checkbox");
		typeNode.setAttribute("value", Policy.typeDescr[type].toLowerCase().replace(/\_/g, "-"));
		typeNode.setAttribute("label", Policy.localizedDescr[type].toLowerCase());

		let typeMask = RegExpFilter.typeMap[Policy.typeDescr[type]];
		typeNode._defaultType = (typeMask & defaultTypes) != 0;
		if ((isDefaultType && typeNode._defaultType) || (!isDefaultType && item.type == type))
			typeNode.setAttribute("checked", "true");

		if (item.type == type)
			typeNode.setAttribute("disabled", "true");
		typeNode.addEventListener("command", function() checkboxUpdated(this), false);
		typeGroup.appendChild(typeNode);
	}

	let collapseDefault = E("collapseDefault");
	collapseDefault.label = collapseDefault.getAttribute(Prefs.fastcollapse ? "label_no" : "label_yes");
	E("collapse").value = "";
	E("collapse").setAttribute("label", collapseDefault.label);

	let warning = E("disabledWarning");
	generateLinkText(warning);
	warning.hidden = Prefs.enabled;

	updatePatternSelection();
}

function checkboxUpdated(checkbox)
{
	checkbox._lastChange = Date.now();
	updateFilter();
}

function updateFilter()
{
	let filter = "";

	let type = E("filterType").value
	if (type == "whitelist")
		filter += "@@";

	let pattern = E("patternGroup").value;
	if (pattern == "")
		pattern = E("customPattern").value;

	if (E("anchorStart").checked)
		filter += E("anchorStart").flexibleAnchor ? "||" : "";

	filter += pattern;

	if (E("anchorEnd").checked)
		filter += "|";

	if (advancedMode)
	{
		let options = [];

		if (E("domainRestrictionEnabled").checked)
		{
			let domainRestriction = E("domainRestriction").value.replace(/[,\s]/g, "").replace(/\.+$/, "");
			if (domainRestriction)
				options.push([E("domainRestrictionEnabled")._lastChange || 0, "domain=" + domainRestriction]);
		}

		if (E("firstParty").checked)
			options.push([E("firstParty")._lastChange || 0, "~third-party"]);
		if (E("thirdParty").checked)
			options.push([E("thirdParty")._lastChange || 0, "third-party"]);

		if (E("matchCase").checked)
			options.push([E("matchCase")._lastChange || 0, "match-case"]);

		let collapse = E("collapse");
		disableElement(collapse, type == "whitelist", "value", "");
		if (collapse.value != "")
			options.push([collapse._lastChange, collapse.value]);

		let enabledTypes = [];
		let disabledTypes = [];
		let forceEnabledTypes = [];
		for (let typeNode = E("typeGroup").firstChild; typeNode; typeNode = typeNode.nextSibling)
		{
			let value = typeNode.getAttribute("value");
			if (value == "document")
				disableElement(typeNode, type != "whitelist", "checked", false);

			if (!typeNode._defaultType)
			{
				if (typeNode.getAttribute("checked") == "true")
					forceEnabledTypes.push([typeNode._lastChange || 0, value]);
			}
			else if (typeNode.getAttribute("checked") == "true")
				enabledTypes.push([typeNode._lastChange || 0, value]);
			else
				disabledTypes.push([typeNode._lastChange || 0, "~" + value]);
		}
		if (!forceEnabledTypes.length && disabledTypes.length < enabledTypes.length)
			options.push.apply(options, disabledTypes);
		else
			options.push.apply(options, enabledTypes);
		options.push.apply(options, forceEnabledTypes);

		if (options.length)
		{
			options.sort(function(a, b) a[0] - b[0]);
			filter += "$" + options.map(function(o) o[1]).join(",");
		}
	}
	else
	{
		let defaultTypes = RegExpFilter.prototype.contentType & ~RegExpFilter.typeMap.DOCUMENT;
		let isDefaultType = (RegExpFilter.typeMap[item.typeDescr] & defaultTypes) != 0;
		if (!isDefaultType)
			filter += "$" + item.typeDescr.toLowerCase().replace(/\_/g, "-");
	}

	filter = Filter.normalize(filter);
	E("regexpWarning").hidden = !Filter.regexpRegExp.test(filter);

	let isSlow = false;
	let compiledFilter = Filter.fromText(filter);
	if (E("regexpWarning").hidden)
	{
		if (compiledFilter instanceof RegExpFilter && defaultMatcher.isSlowFilter(compiledFilter))
			isSlow = true;
	}
	E("shortpatternWarning").hidden = !isSlow;

	//E("matchWarning").hidden = compiledFilter instanceof RegExpFilter && compiledFilter.matches(item.location, item.typeDescr, item.docDomain, item.thirdParty);

	E("filter").value ="||"+ filter;

	if (E("disabledWarning").hidden)
	{
		let subscription = FilterStorage.getGroupForFilter(compiledFilter);
		let warning = E("groupDisabledWarning");
		if (subscription && subscription.disabled)
		{
			warning.subscription = subscription;
			generateLinkText(warning, subscription.title);
			warning.hidden = false;
		}
		else
			warning.hidden = true;
	}
	else
		E("groupDisabledWarning").hidden = true;
}

function generateLinkText(element, replacement)
{
	let template = element.getAttribute("textTemplate");
	if (typeof replacement != "undefined")
		template = template.replace(/\?1\?/g, replacement)

	let beforeLink, linkText, afterLink;
	if (/(.*)\[link\](.*)\[\/link\](.*)/.test(template))
		[beforeLink, linkText, afterLink] = [RegExp.$1, RegExp.$2, RegExp.$3];
	else
		[beforeLink, linkText, afterLink] = ["", template, ""];

	while (element.firstChild && element.firstChild.nodeType != Node.ELEMENT_NODE)
		element.removeChild(element.firstChild);
	while (element.lastChild && element.lastChild.nodeType != Node.ELEMENT_NODE)
		element.removeChild(element.lastChild);
	if (!element.firstChild)
		return;

	element.firstChild.textContent = linkText;
	element.insertBefore(document.createTextNode(beforeLink), element.firstChild);
	element.appendChild(document.createTextNode(afterLink));
}

function updatePatternSelection()
{
	let pattern = E("patternGroup").value;
	if (pattern == "")
	{
		pattern = E("customPattern").value;
	}
	else
	{
		E("anchorStart").checked = true;
		E("anchorEnd").checked = false;
	}

	function testFilter(/**String*/ filter) /**Boolean*/
	{
		return RegExpFilter.fromText(filter + "$" + item.typeDescr).matches(item.location, item.typeDescr, item.docDomain, item.thirdParty);
	}

	let anchorStartCheckbox = E("anchorStart");
	if (!/^\*/.test(pattern) && testFilter("||" + pattern))
	{
		disableElement(anchorStartCheckbox, false, "checked", false);
		anchorStartCheckbox.setAttribute("label", anchorStartCheckbox.getAttribute("labelFlexible"));
		anchorStartCheckbox.accessKey =  anchorStartCheckbox.getAttribute("accesskeyFlexible");
		anchorStartCheckbox.flexibleAnchor = true;
	}
	else
	{
		disableElement(anchorStartCheckbox, /^\*/.test(pattern) || !testFilter("|" + pattern), "checked", false);
		anchorStartCheckbox.setAttribute("label", anchorStartCheckbox.getAttribute("labelRegular"));
		anchorStartCheckbox.accessKey = anchorStartCheckbox.getAttribute("accesskeyRegular");
		anchorStartCheckbox.flexibleAnchor = false;
	}
	disableElement(E("anchorEnd"), /[\*\^]$/.test(pattern) || !testFilter(pattern + "|"), "checked", false);

	updateFilter();
	setAdvancedMode(document.documentElement.getAttribute("advancedMode") == "true");
}

function updateCustomPattern()
{
	E("patternGroup").value = "";
	updatePatternSelection();
}

function addFilter() {
	let filter = Filter.fromText(document.getElementById("filter").value);
	filter.disabled = false;

	FilterStorage.addFilter(filter);

	if (nodes)
		Policy.refilterNodes(nodes, item);

	return true;
}

function setAdvancedMode(mode) {
	advancedMode = mode;

	var dialog = document.documentElement;
	dialog.setAttribute("advancedMode", advancedMode);

	var button = dialog.getButton("disclosure");
	button.setAttribute("label", dialog.getAttribute(advancedMode ? "buttonlabeldisclosure_off" : "buttonlabeldisclosure_on"));

	updateFilter();
}

function disableElement(element, disable, valueProperty, disabledValue) {
	if ((element.getAttribute("disabled") == "true") == disable)
		return;

	if (disable)
	{
		element.setAttribute("disabled", "true");
		element._abpStoredValue = element[valueProperty];
		element[valueProperty] = disabledValue;
	}
	else
	{
		element.removeAttribute("disabled");
		if ("_abpStoredValue" in element)
			element[valueProperty] = element._abpStoredValue;
		delete element._abpStoredValue;
	}
}

function openPreferences() {
	Utils.openFiltersDialog(Filter.fromText(E("filter").value));
}

function doEnable() {
	Prefs.enabled = true;
	E("disabledWarning").hidden = true;
}

function enableSubscription(subscription)
{
	subscription.disabled = false;
	E("groupDisabledWarning").hidden = true;
}

/**
 * Selects or unselects all type checkboxes except those
 * that are disabled.
 */
function selectAllTypes(/**Boolean*/ select)
{
	for (let typeNode = E("typeGroup").firstChild; typeNode; typeNode = typeNode.nextSibling)
		if (typeNode.getAttribute("disabled") != "true")
			typeNode.checked = select;
	updateFilter();
}
