/*global Logger Rules lastActiveTab FormFiller Utils */
// This creates a "safe" namespace for all libs
var Libs = {
  _libs: {},
  add: function(libraryName, librayTopLevelFunction, forceAdd) {
    // Check if the method is already defined
    forceAdd = forceAdd || false;
    if((this._libs[libraryName] || this.hasOwnProperty(libraryName)) && !forceAdd) {
      Logger.info("[libs.js] Can not add library named '" + libraryName + "' because it already exists as a function().");
      return;
    }
    this[libraryName] = librayTopLevelFunction;
    Logger.info("[libs.js] Added library as Libs." + libraryName);
  },
  import: function() {
    return new Promise(function (resolve) {
      Rules.all().then(function (rules) {
        rules.forEach(function (rule) {
          if (typeof rule.export !== "undefined" && typeof rule.lib === "function") {
            // Add the rule into the scope of all library functions
            Libs.add(rule.export, rule.lib, true);
          }
        });
      }).then(resolve("libraries imported"));
    });
  },
  // Dectects libraries used in a rulecode string
  // returns an array of found libraries
  detectLibraries: function(ruleCodeString) {
    var detectedLibs = [];
    Object.keys(Utils.vendoredLibs).forEach(function dtctLib(vLibKey) {
      if(ruleCodeString.match(Utils.vendoredLibs[vLibKey].detectWith) !== null) {
        // Found!
        detectedLibs.push(vLibKey);
      }
    });
    return detectedLibs;
  }
};

// helper for use in value functions
//
// "value" : Libs.h.click  => Clicks on the element specified by 'selector'
var valueFunctionHelper = {
  click: function($domNode) {
    $domNode.click();
  },
  screenshot: function(saveAs) {
    chrome.runtime.sendMessage({action: "takeScreenshot", value: FormFiller.currentRuleMetadata, flag: saveAs});
  }
};
Libs.add("h", valueFunctionHelper);

// Process control functions
var processFunctionsHalt = function(msg) {
  return function() {
    if(typeof lastActiveTab === "undefined") {
      return null;
    }

    if(typeof msg === "undefined") {
      msg = "Canceled by call to Libs.halt()";
    }

    // Since this is called from the b/form_utils.js
    // we need to send a message to the content.js
    chrome.tabs.sendMessage(lastActiveTab.id, {action: "showOverlay", message: msg});

    return null;
  };
};
Libs.add("halt", processFunctionsHalt);

// Import all saved libs
Libs.import();

@@ -1466,16 +1466,926 @@
 edLibs;%0A
+  %7D,%0A  loadLibs: function(scriptPaths) %7B%0A    return new Promise(function (resolve, reject) %7B%0A      if(typeof scriptPaths === %22string%22) %7B%0A        scriptPaths = %5BscriptPaths%5D;%0A      %7D%0A%0A      var anchor = document.querySelector(%22body%22);%0A      var fragment = document.createDocumentFragment();%0A%0A      var loadedScriptCount = 0;%0A      var targetScriptCount = scriptPaths.length;%0A%0A      scriptPaths.forEach(function(scriptPath) %7B%0A        var script = document.createElement(%22script%22);%0A        script.async = false;%0A        script.src = %22../%22 + scriptPath;%0A        script.onload = function() %7B%0A          loadedScriptCount++;%0A          if (loadedScriptCount %3E= targetScriptCount) %7B%0A            resolve(loadedScriptCount);%0A          %7D%0A        %7D;%0A        script.onerror = function() %7B%0A          reject(script.src);%0A        %7D;%0A%0A        fragment.appendChild(script);%0A      %7D);%0A%0A      anchor.appendChild(fragment);%0A    %7D);%0A
   %7D%0A%7D;%0A%0A

add Libs.loadLibs for script loading