Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
function _tbApi() { 
 this.wrappedJSObject = this;
}
_tbApi.prototype = {
  classDescription: "toolbarhome API XPCOM Component",
  classID:          Components.ID("{ee33c315-abea-4463-a2ce-3639867478d3}"),
  contractID:       "@toolbarhome.com/_tbApi;1",
  flags: Components.interfaces.nsIClassInfo.DOM_OBJECT,
  implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
  getInterfaces: function(count) {
        var ifaces = new Array();
        //ifaces.push(Components.interfaces.nsIToolbarHome);
        ifaces.push(Components.interfaces.nsIClassInfo);
        ifaces.push(Components.interfaces.nsISupports);
        ifaces.push(Components.interfaces.nsIObserver);
        count.value = ifaces.length;
        return ifaces;
    },
  getHelperForLanguage: function(language) {
        return null;
    },
  _xpcom_categories: [{
      category: "JavaScript global property", entry: "toolbarhomeAPI"}
     ,{category: "profile-after-change", entry: "toolbarhomeAPI"}],
   QueryInterface: function(iid) {
        if (//!iid.equals(Components.interfaces.nsIToolbarhome) &&
            !iid.equals(Components.interfaces.nsIClassInfo) &&
            !iid.equals(Components.interfaces.nsIObserver) &&
            !iid.equals(Components.interfaces.nsISupports)) {
            throw Components.results.NS_ERROR_NO_INTERFACE;
        }
        return this;
    },
    __exposedProps__ : { GetPreferences : "r", SetAllowedSite : "r", MergeOverLay: "r", MergeOverLayWithReloadChrome: "r", RegisterClientScriptFunction: "r", SetHomePage: "r", GetHomePage: "r", GetBrowserURL: "r", GetPreferenceKey: "r", SetPreferenceKey: "r", ResetPreferenceKey: "r", UninstallAddon: "r", GetTabID: "r", GetTrackersByTab: "r", GetDNTDB: "r", DisableDNT: "r", PostSet: "r"},
    Init: function (partnerID) {
        Components.utils.import("resource://avg/avgJsm.js");
        var pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
        var obsService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
        obsService.addObserver(this, "profile-before-change", false);
        try {
            //Firefox 4 and above
            Components.utils.import("resource://gre/modules/AddonManager.jsm");
            AddonManager.getAddonByID(partnerID + "@toolbar", function (addon) {
                var nsiURI = addon.getResourceURI("");
                var fileFromURI = nsiURI.QueryInterface(Components.interfaces.nsIFileURL).file;
                Domains_avg.InstallDirPath = fileFromURI.path;
                pref.setCharPref(partnerID + ".install.installDirPath", fileFromURI.path);
                //Ovewrite locale files according to user language
                if (pref.prefHasUserValue(partnerID + ".install.currLocale"))
                    return;

                _tbApi.prototype.OverWriteLocale(partnerID);
            });
        } catch (ex) {
            //Firefox  below version 4
            var em = Components.classes["@mozilla.org/extensions/manager;1"].getService(Components.interfaces.nsIExtensionManager);
            var folder = em.getInstallLocation(partnerID + "@toolbar").getItemLocation(partnerID + "@toolbar");
            Domains_avg.InstallDirPath = folder.path;
            pref.setCharPref(partnerID + ".install.installDirPath", folder.path);
            //Ovewrite locale files according to user language
            if (pref.prefHasUserValue(partnerID + ".install.currLocale"))
                return;

            this.OverWriteLocale(partnerID);
        }
    },
    Uninit: function(partnerID){
          //Unregister profile-before-chabge observer
          var obsService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
	      obsService.removeObserver(this, "profile-before-change");

          var pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
	
          Components.utils.import("resource://avg/avgJsm.js");
          Components.utils.import("resource://avg/IOJsm.js");
          if(!Domains_avg.dumpLogDataEnabled)
	        return;
      
          var tmpDir = IODirModule_avg.OperatingSystemTempDir();
          var dumpFile = IOFileModule_avg.open(tmpDir.path + IODirModule_avg.sep + "AVG_TB_DumpLog.txt");
          IOFileModule_avg.create(dumpFile);
          var fsize = dumpFile.fileSize;
          if(fsize > 2097152) // 2 MB
	        return;
      
      var osString = Components.classes["@mozilla.org/network/protocol;1?name=http"].getService(Components.interfaces.nsIHttpProtocolHandler).oscpu;
      var objXULApp = Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULAppInfo);
      var platformVersion = objXULApp.platformVersion;
      var browserName = objXULApp.name;
      
      var guid = pref.prefHasUserValue(Domains_avg.PartnerID + ".install.guid") ? pref.getCharPref(Domains_avg.PartnerID + ".install.guid") : null;
      var tbversion = pref.prefHasUserValue(Domains_avg.PartnerID + ".install.finished") ? pref.getCharPref(Domains_avg.PartnerID + ".install.finished") : null;
      var build = pref.prefHasUserValue(Domains_avg.PartnerID + ".install.overlayVersion") ? pref.getCharPref(Domains_avg.PartnerID + ".install.overlayVersion") : null;
      IOFileModule_avg.write(dumpFile, Domains_avg.InstallDirPath + "\r\nVERSION: " + tbversion + ", BUILD: " + build + "\r\nCID: " + guid + "\r\nOS: " + osString + "\r\nPlatform: " + platformVersion + "\r\nBrowser: " + browserName + "\r\n======================================================\r\n" + Domains_avg.dumpLogData + "\r\n" , "a");
    },
    // nsIObserver implementation
    observe: function (aSubject, aTopic, aData) {
        switch (aTopic) {
            case "profile-after-change":
                dump("\n ###### toolbarhomeAPI Comp Start ######\n");
                this.Init('avg');
                dump("\n ###### toolbarhomeAPI Comp End ######\n");
                break;
            case "profile-before-change":
	            dump("\n ###### toolbarhomeAPI Comp Shutdown ######\n");
	            this.Uninit('avg');
	            break;
        }
    },
    OverWriteLocale: function (partnerID) {
        Components.utils.import("resource://avg/avgJsm.js");
        Components.utils.import("resource://avg/IOJsm.js");
        //check if there is locale files that need to replace old ones
        var localeFolderName = "locale";
        var localeSpecificFolderName = "en-US";
        var resourceFolder = "modules";
        var installDir = IOFileModule_avg.open(Domains_avg.InstallDirPath);
        var tempLocale = IOFileModule_avg.open(installDir.path + IODirModule_avg.sep + resourceFolder + IODirModule_avg.sep + localeFolderName);
        try {
            if (!tempLocale.exists() || !tempLocale.isDirectory())
                return;

            var localeDir = IOFileModule_avg.open(installDir.path + IODirModule_avg.sep + localeFolderName);
            if (!localeDir.exists() || !localeDir.isDirectory())
                return;

            var userLangChoice = "";
            userLangChoice = IORegistryModule_avg.ReadRegistryKey(IORegistryModule_avg.WIN_REG_ROOT.LOCAL_MACHINE, Domains_avg.IE_REG_USER_CHOICES_PATH, Domains_avg.IE_REG_KEYS.LOCAlE);
            if (userLangChoice == "")
                return;

            var entries = tempLocale.directoryEntries;
            var array = [];
            while (entries.hasMoreElements()) {
                var entry = entries.getNext();
                entry.QueryInterface(Components.interfaces.nsIFile);
                if (entry.leafName == userLangChoice) {
                    array.push(entry);
                    break;
                }
            }

            for (var i in array) {
                var langDir = localeDir.clone();
                //langDir.append(array[i].leafName);
                langDir.append(localeSpecificFolderName);
                entries = array[i].directoryEntries;
                while (entries.hasMoreElements()) {
                    var entry = entries.getNext();
                    entry.QueryInterface(Components.interfaces.nsIFile);
                    if (entry.isFile()) {
                        if (!langDir.exists())
                            IODirModule_avg.create(langDir);

                        IOFileModule_avg.move(entry, langDir, "");
                    }
                }
            }
            IODirModule_avg.unlink(tempLocale, true);
            var pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
            pref.setCharPref(partnerID + ".install.currLocale", userLangChoice);
            dump("\nLocalization Set: " + userLangChoice + "\n")
		    LogAddonMsgs_avg.CreateDumpLogString("Localization Set: " + userLangChoice);
        } catch (ex) {dump("\n" + ex + "\n"); IODirModule_avg.unlink(tempLocale, true);}
    },
   GetPreferences: function(partnerID){
   	    var tbDetails = {};
   	    try{
	   	    var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
	                       .getService(Components.interfaces.nsIWindowMediator);
		
		    var browserWindow = wm.getMostRecentWindow("navigator:browser");
		
		    var tbData = eval("browserWindow.InitializeOverlay_" + partnerID + ".GetToolbarDetails(true)");
		    var nodeName;
		    var nodeValue;
		    for (var i in tbData.childNodes) {
			    if(typeof tbData.childNodes[i].nodeName == "undefined")
				    continue;
				
	                    nodeName = tbData.childNodes[i].nodeName;
	                    nodeValue = tbData.childNodes[i].innerText;
	                    tbDetails[nodeName] = nodeValue;
	            }
		
	   	    return tbDetails;
   	    }catch(ex){}
   	    return tbDetails;
   },
   SetAllowedSite: function(uri){
      try{
	        var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
		                       .getService(Components.interfaces.nsIWindowMediator);
	    var browserWindow = wm.getMostRecentWindow("navigator:browser");
	    var browser = browserWindow.gBrowser.selectedBrowser;
	    browserWindow.SiteSafety_avg.PushIgnoredURL(browser, uri);
        browserWindow.LoadUrl_avg.LoadUrl(uri);
      }catch(ex){
      }
   },
   MergeOverLay: function(partnerID, jarFilePath){
   	try{
		var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
		                   .getService(Components.interfaces.nsIWindowMediator);
			
		var browserWindow = wm.getMostRecentWindow("navigator:browser");
		
		eval("browserWindow.OverLay_" + partnerID + ".forceOverlay = true");
		eval("browserWindow.OverLay_" + partnerID + ".AddonRemoteConfigurationCallback(0, '" + jarFilePath + "', 0)");
	}catch(ex){}
   },
    MergeOverLayWithReloadChrome: function (partnerID, jarFilePath) {
        try {
            var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
		                       .getService(Components.interfaces.nsIWindowMediator);

            var browserWindow = wm.getMostRecentWindow("navigator:browser");
            eval("browserWindow.OverLay_" + partnerID + ".reloadChrome = true");
            eval("browserWindow.OverLay_" + partnerID + ".AddonRemoteConfigurationCallback(0, '" + jarFilePath + "', 0)");
        } catch (ex) { }
    },
    ReloadChrome: function (partnerID) {
        try {
            var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
		                       .getService(Components.interfaces.nsIWindowMediator);

            var browserWindow = wm.getMostRecentWindow("navigator:browser");
            eval("browserWindow.RunProc_" + partnerID + ".ReloadChrome(true)");
        } catch (ex) { }
    },
    RegisterClientScriptFunction: function(partnerID, fx, encFx){
      try {
            var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
		                       .getService(Components.interfaces.nsIWindowMediator);

            var browserWindow = wm.getMostRecentWindow("navigator:browser");
            eval("browserWindow.ClientScriptManipulation_" + partnerID + ".RegisterClientScriptFunction(\"" + fx + "\", \"" + encFx + "\")");
        } catch (ex) { }
    },
    SetHomePage: function (partnerID) {
        var result = { "Success": "", "FailureSummary": "", "Exception": "" };
        var nativeJSON = Components.classes["@mozilla.org/dom/json;1"]
                .createInstance(Components.interfaces.nsIJSON);
        try {
            var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
		                       .getService(Components.interfaces.nsIWindowMediator);

            var browserWindow = wm.getMostRecentWindow("navigator:browser");
            eval("browserWindow.HandleInstallation_" + partnerID + ".SetHomepageOnly(null, true)");
            result.Success = true;
        } catch (ex) { result.Success = false; result.Exception = ex; result.FailureSummary = "Could Not Invoke SetHomePage method"; }
        return nativeJSON.encode(result);
    },
    GetHomePage: function () {
        var pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
        var prefValue = "";
        try {
            prefValue = pref.getCharPref("browser.startup.homepage");
        } catch (ex) { }
        return prefValue;
    },
    GetBrowserURL: function () {
        var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
		                       .getService(Components.interfaces.nsIWindowMediator);

        var browserWindow = wm.getMostRecentWindow("navigator:browser");
        return browserWindow.gBrowser.currentURI.spec;

    },
    GetPreferenceKey: function (partnerID, key) {
        Components.utils.import("resource://avg/Preferences.js");
        var prefValue = Preferences.get(partnerID + ".userPreferences." + key, "");

        return prefValue;
    },
    SetPreferenceKey: function (partnerID, key, val) {
        Components.utils.import("resource://avg/Preferences.js");
        
        var result = { "Success": "", "FailureSummary": "", "Exception": "" };
        if (typeof val == "undefined" || val == "" || val == null) {
            result.Success = false;
            result.FailureSummary = "Value is null or empty"
            return JSON.stringify(result);
        }
        try {
            Preferences.set(partnerID + ".userPreferences." + key, val);
            result.Success = true;
        } catch (ex) {
            result.Success = false;
            result.Exception = ex;
            result.FailureSummary = "xpcom js method SavePreferenceKey exception";
        }
        return JSON.stringify(result);
    },
    ResetPreferenceKey: function(partnerID, key){
      Components.utils.import("resource://avg/Preferences.js");
      Preferences.reset(partnerID + ".userPreferences." + key);
    },
    UninstallAddon: function(partnerID, resetSAPs, key){
	    Components.utils.import("resource://avg/avgJsm.js");
	    Components.utils.import("resource://avg/IOJsm.js");
	    var result = { "Success": true, "FailureSummary": "", "Exception": "" };
	    if(Domains_avg.LoadedPreferenceKeys[Domains_avg.IE_REG_KEYS.MachineIDEnc] == null){
	      result.Success = true;
	      result.FailureSummary = "Encryption for MAchineID failed";
	      LogAddonMsgs_avg.CreateDumpLogString("partnerID: " + partnerID + "  Encryption for MAchineID failed");
	    }
  
	    if(Domains_avg.LoadedPreferenceKeys[Domains_avg.IE_REG_KEYS.MachineIDEnc] != null && Domains_avg.LoadedPreferenceKeys[Domains_avg.IE_REG_KEYS.MachineIDEnc] != key){
	      result.Success = false;
	      result.FailureSummary = "Keys not matched"
	      LogAddonMsgs_avg.CreateDumpLogString("partnerID: " + partnerID + "  Keys not matched");
	    }
  
	    var uninstallerPath = IORegistryModule_avg.ReadRegistryKey(IORegistryModule_avg.WIN_REG_ROOT.LOCAL_MACHINE, Domains_avg.IE_REG_USER_CHOICES_PATH, "Uninstall");
	    if(uninstallerPath == "" || uninstallerPath == null){
	      result.Success = false;
	      result.FailureSummary = "Uninstall file path not found in win reg";
	      LogAddonMsgs_avg.CreateDumpLogString("partnerID: " + partnerID + "  Uninstall file path not found in win reg");
	    }
	    if(!result.Success){
	      return JSON.stringify(result);
	    }
	    try
	    {
		    // create an nsILocalFile for the executable
		    var file = IOFileModule_avg.open(uninstallerPath.replace(/\\/g,"\\\\"));
		    // create an nsIProcess
		    var process = Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
		    process.init(file);
		    // Run the process.
		    // If first param is true, calling thread will be blocked until
		    // called process terminates.
		    // Second and third params are used to pass command-line arguments
		    // to the process.
		    var args = [];
		    args.push("/UNINSTALL");
		    if(resetSAPs){
		      args.push("/RESETSAPS");
		    }
            //LogAddonMsgs_avg.CreateDumpLogString("Addon Uninstalled by " + partnerID + " Installer. Uninstall SAPs: " + resetSAPs);
		    process.run(false, args, args.length);
		    result.Success = true;
	    }
	    catch(ex){
	      result.Success = false;
	      result.Exception = ex;
	      result.FailureSummary = "error UninstallAddon XPCOM";
	      LogAddonMsgs_avg.CreateDumpLogString("partnerID: " + partnerID + "  error UninstallAddon XPCOM. " + ex);
	    }
	    return JSON.stringify(result);
    },
    GetTabID: function(){
      //Components.utils.import("resource://avg/avg-dnt-adapter.js");
      var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator);
      var browserWindow = wm.getMostRecentWindow("navigator:browser");
      if(typeof browserWindow.gBrowser.selectedBrowser.dntID != "undefined"){
	return browserWindow.gBrowser.selectedBrowser.dntID;
      }else{
	return null;
      }
    },
    GetTrackersByTab : function(dntTabID){
      Components.utils.import("resource://avg/avg-dnt-adapter.js");

      var tabTrackers = adapter_avgdnt.GetTrackersForTab(dntTabID);
      var trackerObj = null;
      var jsonResult = "";
      if(tabTrackers == null){
	      return jsonResult;
      }
      
      for(var i in tabTrackers){
	      trackerObj = adapter_avgdnt.GetTrackerDetails(tabTrackers[i]);
	      trackerObj = JSON.parse(trackerObj);
	      jsonResult += trackerObj["id"] + ":" + trackerObj["blocked"] + ":" + trackerObj["action"] + ";"
      }
      jsonResult = jsonResult != "" ? jsonResult.replace(/allow/gi, 0).replace(/block/gi, 1) : jsonResult; 
      return jsonResult != "" ? jsonResult.slice(0, jsonResult.length-1) : jsonResult;
    },
    DisableDNT: function(state){
      Components.utils.import("resource://avg/avg-dnt-adapter.js");
      adapter_avgdnt.DisableDNT(state);
    },
    GetDNTDB: function(){
      Components.utils.import("resource://avg/avg-dnt-adapter.js");
      return adapter_avgdnt.GetTrackersDB();
    },
    PostSet: function (partnerID, operationKey) {
        var methodOnMain = [];
        var result = { "Success": "", "FailureSummary": "", "Exception": "" };
        switch (operationKey) {
            case "saveUiOptions":
                methodOnMain.push("ToolbarUIOptions_" + partnerID + ".SaveUserUIOptionsCallBack('" + partnerID + "')");
                break;
            case "saveAdvancedOptions":
                methodOnMain.push("ToolbarUIOptions_" + partnerID + ".SaveUserAdvancedOptionsCallBack('" + partnerID + "')");
                break;
            case "saveSecurityOptions":
                methodOnMain.push("ToolbarUIOptions_" + partnerID + ".SaveUserSecurityOptionsCallBack('" + partnerID + "')");
                break;
            case "saveAll":
                methodOnMain.push("ToolbarUIOptions_" + partnerID + ".SaveUserSecurityOptionsCallBack('" + partnerID + "')");
                methodOnMain.push("ToolbarUIOptions_" + partnerID + ".SaveUserAdvancedOptionsCallBack('" + partnerID + "')");
                methodOnMain.push("ToolbarUIOptions_" + partnerID + ".SaveUserUIOptionsCallBack('" + partnerID + "')");
                break;
            default:
                break;
        }
        var nativeJSON = Components.classes["@mozilla.org/dom/json;1"]
                .createInstance(Components.interfaces.nsIJSON);

        if (methodOnMain.length == 0) {
            result.Success = true;
            return nativeJSON.encode(result);
        }

        try {
            var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
					 .getService(Components.interfaces.nsIWindowMediator);

            var browserWindow = wm.getMostRecentWindow("navigator:browser");
            for (var i in methodOnMain) {
                eval("browserWindow." + methodOnMain[i]);
            }
            result.Success = true;
        } catch (ex) {
            result.Success = false;
            result.Exception = ex;
        }
        return nativeJSON.encode(result);
    }
};
var components = [_tbApi];
/**
* XPCOMUtils.generateNSGetFactory was introduced in Mozilla 2 (Firefox 4).
* XPCOMUtils.generateNSGetModule is for Mozilla 1.9.2 (Firefox 3.6).
*/
if (XPCOMUtils.generateNSGetFactory)
    var NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
else
    var NSGetModule = XPCOMUtils.generateNSGetModule(components);
    
//function NSGetModule(compMgr, fileSpec) {
  //return XPCOMUtils.generateModule(components);
//}