var appCenter = (function() {
	var Cu = Components.utils;
	var Ci = Components.interfaces;
	var Cc = Components.classes;
	
	var jsm = { };
	Cu["import"]("resource://livemargins/appcenter.jsm", jsm);
	Cu["import"]("resource://livemargins/dao.jsm", jsm);
	Cu["import"]("resource://livemargins/utils.jsm", jsm);
	Cu["import"]("resource://livemargins/track.jsm", jsm);
	
	var logger = new jsm.utils.logger("LM4.appcenter.appContentAPI");
	
	var stringBundle = (function() {
		var stringBundleService = Components.classes['@mozilla.org/intl/stringbundle;1']
									.getService(Components.interfaces.nsIStringBundleService);
									
		var _stringBundle = stringBundleService.createBundle("chrome://livemargins/locale/appcenter.properties");
		
		return {
			getString: function(strName) {
				return _stringBundle.GetStringFromName(strName);
			}, 
			
			getFormattedString: function(strName, values) {
				return _stringBundle.formatStringFromName(strName, values, values.length);
			}
		}
	})();
	
	function _(strName, values) {
		if (!values)
			return stringBundle.getString(strName);	
		else
			return stringBundle.getFormattedString(strName, values);	
	}
	
	// Privileged api for appcenter page for concerning the security.
	// Make sure that all the api has limited privileges.
	var contentAPI = {
		// content apis for utils
		getPref:         jsm.utils.getPref,
		setPref:         jsm.utils.setPref,
		getLogger: function(aLoggerName) {
			return new jsm.utils.logger(aLoggerName);
		},
		log: function(msg) {
			dump(msg);
		},
		getPrefFromRoot: jsm.utils.getPrefFromRoot,
		
		// content apis for string bundles
		stringBundle:    stringBundle,
		_:               _,
		
		// content apis for dao
		appCenterDAO:    jsm.utils.wrapAsContentAPI(jsm.AppCenterDAO),
		
		// content apis for AppCenter module
		appCenter:       jsm.utils.wrapAsContentAPI(jsm.AppCenter, 1),
		
		// content apis for tracker
		tracker:         jsm.Tracker,
		
		getLocation: function(iframe) {
			return iframe.contentWindow.document.location.toString();
		},
		
		setLocation: function(iframe, src) {
			iframe.contentWindow.document.location = src;
		},
		
		getImageDataURL: function(img) {
			var canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "html:canvas");
			var context = canvas.getContext("2d");
			canvas.height = img.height;
			canvas.width = img.width;
			context.drawImage(img, 0, 0, img.width, img.height);
			return canvas.toDataURL('image/png', '');
		}
	};
	
	var _progListener = new jsm.utils.browserLoadListener(function(win) {
		if (win.frameElement.id == "web-apps-frame") {
			// show loading indicator
			win.parent.document.getElementById("web-apps-loading").style.display = "block";
		}
	}, function(win) {
		if (win.frameElement.id == "web-apps-frame") {
			// hide loading indicator
			win.parent.document.getElementById("web-apps-loading").style.display = "none";
		}
	}, function(win) {
		if (win.frameElement.id == "web-apps-frame") {
			// hide loading indicator
			win.parent.document.getElementById("web-apps-loading").style.display = "none";
		}
	});
	
	return {
		init: function(event) {
			var appWin = event.originalTarget.contentWindow;
			
			// Only run the following codes for appcenter page.
			if (appWin.document.location.href.indexOf("resource://livemargins/appcenter.xhtml") != 0) {
				return;
			}
			
			// If using Cc["@mozilla.org/systemprincipal;1"].createInstance(Ci.nsIPrincipal) to create principal like Jetpack worker.js, problems occurs:
			//     a) can not judge if two elemente equal, like line 33 in main.js
			//     b) need to use unsafedwindow (wrappedJSObject) to make sure expando attributes can be accessed, like image.onload, iframe.onload etc.
			// If using appWin as principal, problems occurs:
			//     a) expando attributes can not be accessed, like image.onload, even by using unsafedwindow (wrappedJSObject)
			//        have to use addEventListener instead.
			var sandbox = new Cu.Sandbox(appWin);
			sandbox.window = appWin;
			// have to set "document", or document will not be found under ff3
			sandbox.document = appWin.document;
			sandbox.__proto__ = sandbox.window;
			sandbox.contentAPI = contentAPI;
			
			Cu.evalInSandbox(jsm.utils.getContentFromURL("chrome://livemargins/content/appcenter/iq.js"),          sandbox, "1.8");
			Cu.evalInSandbox(jsm.utils.getContentFromURL("chrome://livemargins/content/appcenter/common.js"),      sandbox, "1.8");
			Cu.evalInSandbox(jsm.utils.getContentFromURL("chrome://livemargins/content/appcenter/widgets.js"),     sandbox, "1.8");
			Cu.evalInSandbox(jsm.utils.getContentFromURL("chrome://livemargins/content/appcenter/viewhistory.js"), sandbox, "1.8");
			Cu.evalInSandbox(jsm.utils.getContentFromURL("chrome://livemargins/content/appcenter/main.js"),        sandbox, "1.8");
			Cu.evalInSandbox(jsm.utils.getContentFromURL("chrome://livemargins/content/appcenter/apps.js"),        sandbox, "1.8");
			Cu.evalInSandbox(jsm.utils.getContentFromURL("chrome://livemargins/content/appcenter/history.js"),     sandbox, "1.8");
			sandbox["appCenterInit"]();
			
			jsm.Tracker.track(jsm.Tracker.view.type, jsm.Tracker.view.actions.OPEN_APPCENTER, 0);
			
			// Add progresslistener to show loading indicator.
			document.getElementById("appcenter_content")
						.addProgressListener(_progListener, Ci.nsIWebProgress.NOTIFY_ALL | Ci.nsIWebProgress.NOTIFY_STATE_ALL);
	
			appWin.addEventListener("unload", function() {
				document.getElementById("appcenter_content")
						.removeProgressListener(_progListener, Ci.nsIWebProgress.NOTIFY_ALL | Ci.nsIWebProgress.NOTIFY_STATE_ALL);
	
				delete sandbox.__proto__;
				for (var attr in sandbox) {
					delete sandbox[attr];
				}
				logger.trace("cleanup sanbox.");
			}, false);
		}
	};
})();