(function() {
	var ns = MOA.ns('SafeFlag.Monitor')

	var Cc = Components.classes;
	var Ci = Components.interfaces;
	var Cu = Components.utils;
	var Cr = Components.results;

	Cu['import']('resource://cmsafeflag/safeflag.jsm');
	// Current tab id which used to check if lookup callback is for current tab.
	var _current_tab_id_ = null;

	// Store safe info for tab, including:
	// 	url:      for checking if tab url has been changed.
	// 	safeflag: safe flag checking result, if url is not changed, then reuse it.
	var _tab_url_safeflag_ = {};

	var progListener = {
		QueryInterface: function(iid) {
			if (iid.equals(Ci.nsISupports) ||
				iid.equals(Ci.nsISupportWeakReference) ||
				iid.euqals(Ci.nsIWebProgressListener)) {
				return this;
			}

			throw Cr.NS_ERROR_NO_INTERFACE;
		},

		onStateChange:    function() {},
		onProgressChange: function() {},
		onStatusChange:   function() {},
		onSecurityChange: function() {},
		onLocationChange: function(webProgress, request, uri) {
			var win = webProgress.DOMWindow;
			var tabId = MOA.SafeFlag.Utils.getTabIdForWindow(win);
			if (!tabId)
				return;

			MOA.debug(tabId + ', uri: ' + uri);
			_current_tab_id_ = tabId;
			if (!uri) {
				// When a new tab is opened, uri is null.
				_updateIcon(uri);
				return;
			}

			var url_safeflag = _tab_url_safeflag_[tabId];

			if (!url_safeflag || url_safeflag.url != uri.spec) {
				_tab_url_safeflag_[tabId] = {
					url: uri.spec,
					safe_flag: null
				};

				safeflag.lookup(uri.spec, MOA.SafeFlag.Utils.bindFunc(function(result) {
					_tab_url_safeflag_[this].safe_flag = result;
					if (_current_tab_id_ == this) {
						MOA.debug('Update icons');
						_updateIcon();
					}
				}, tabId));

				_updateIcon();
				return;
			}

			if (url_safeflag.url == uri.spec && null != url_safeflag.safe_flag) {
				_updateIcon();
			}
		},

		handleEvent: function(event) {
			_onTabClose(event.target.linkedPanel);
		}
	};

	function _onTabClose(tabId) {
		delete _tab_url_safeflag_[tabId];
	}

	function _getIconPath(filename) {
		return "chrome://cmsafeflag/content/icons/" + filename + ".png";
	}
	
	function _updateIcon() {
		MOA.SafeFlag.Layout.updateIcon();
	}

	ns.getCurrentTabSafeflag = function() {
		if (!_tab_url_safeflag_[_current_tab_id_] || !_tab_url_safeflag_[_current_tab_id_].safe_flag)
			return null;

		return _tab_url_safeflag_[_current_tab_id_].safe_flag;
	};

	ns.init = function() {
		// do not use any mask which cause an "error" on Firefox5:
		// Error: gBrowser.addProgressListener was called with a second argument, which is not supported. See bug 608628.
		// Source: chrome://browser/content/tabbrowser.xml
		// Line: 1840
		gBrowser.addProgressListener(progListener/*, Ci.nsIWebProgress.NOTIFY_LOCATION*/);
		gBrowser.tabContainer.addEventListener('TabClose', progListener, false);
	}

	ns.stop = function() {
		gBrowser.removeProgressListener(progListener);
		gBrowser.tabContainer.removeEventListener('TabClose', progListener, false);
	}

	if (MOA.SafeFlag.Utils.getPrefs().getBoolPref("enable")) {
		window.addEventListener('load', function(evt) {
			MOA.SafeFlag.Monitor.init()
		}, false);
	}
})();
