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);
      }
    }
  })();

  // 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 jsm.utils.exposeReadOnly(new jsm.utils.logger(aLoggerName));
    },
    log: function(msg) {
      dump(msg);
    },
    getPrefFromRoot: jsm.utils.getPrefFromRoot,

    // content apis for string bundles
    stringBundle:    stringBundle,

    getLocalizedStr: function _(strName, values) {
      if (!values)
        return stringBundle.getString(strName);
      else
        return stringBundle.getFormattedString(strName, values);
    },

    // 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', '');
    },

    makeObjAccessible: function(obj) {
      return jsm.utils.exposeReadOnly(obj);
    }
  };

  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 = jsm.utils.exposeReadOnly(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);
    }
  };
})();

