function Wordlist_Local(data) {
  this.data = new TAFFY(data);
  this.lookup_pattern = function (pattern,filter,callback) {
    var output = new Array();
    var matches = new Array();
    var pattern_type = "p";
    switch (getPatternType(pattern))
    {
      case "hl":
        matches = this.data.find({hl:pattern.toUpperCase()});
        break;
      case "p":
        matches = this.data.find({p:getPattern(pattern.toUpperCase())});
        break;
      case "p2":
        matches = this.data.find({p2:pattern.toUpperCase()});
        break;
    }
    if (filter != null)
    {
      filter = filter.toLowerCase()
      filter = filter.replace(/\-/g,".");
      filter = filter.replace(/\*/g,".*");
      filter = filter.replace(/\+/g,".+");
      matches = this.data.find({w:{regex:new RegExp("^" + filter + "$")}}, matches);
    }
    this.data.forEach(function(f,n){output.push(f.w);},matches);
    callback(output.length,output.slice(0,100));
  }
}

function Wordlist_External(name) {
  this.name = name;
  if (document.domain=="")
    this.url = "http://localhost:8080/patterns/json/" + name;
  else
    this.url = "http://tools.codepenguin.com/patterns/json/" + name;
  this.data = null;
  
  this.lookup_pattern = function (pattern,filter,callback) {
    var url = this.url + "/" + pattern;
    if (filter != null)
      url += "/" + filter.replace(/\*/g, "_");
    this.json_callback = callback;
    var wordlist = this;
    $.getJSON(url+'?callback=?', function(data) {callback(data.count,data.words);});
  }
}

function Wordlists() {
  this.wordlists = new Array();
  this.lastmatch = [];
  this.active_name = "";
  this.active_list = null;
  this.available_lists = new Array("CPLIST","ENABLE2K","PHOENIX","CAGE");

  this.active = function() {
    if (this.active_list == null)
      return false
    else
      return true;
  }
  
  this.activate_wordlist = function(index) {
    this.active_name = this.wordlists[index].name;
    this.active_list = this.wordlists[index].list;
    write_output(this.active_name + " Wordlist activated.");
  }
  
  this.has_wordlist = function (name) {
    name = name.toUpperCase();
    for (i=0;i<this.available_lists.length;i++)
      if (this.available_lists[i].name == name)
        return true;
    return false;
  }
  
  this.list_index = function (name) {
    name = name.toUpperCase();
    for (i=0;i<this.wordlists.length;i++)
      if (this.wordlists[i].name.toUpperCase() == name)
        return i;
    return -1;
  }
  
  this.register = function(name, list) {
    list.name = name;
    this.activate_wordlist(this.wordlists.push({"name":name,"list":list})-1);
  }
  
  this.load = function(name,exec) {
    name = name.toUpperCase();
    var index = this.list_index(name);
    if (index > -1)
      this.activate_wordlist(index)
    else if (this.has_wordlist(name))
      throw CommandException("Unknown wordlist: " + name)
    else
    {
      write_output("Loading " + name + " Wordlist...");
      name = strRemoveOthers(name.toLowerCase(), constants.ascii_lowercase + constants.digits);
      LazyLoad.js('wordlists/' + name + '.js',exec);
      setTimeout(function() {document.data_store.set("wordlist",name);}, 0);
    }
  }
 
  this.lookup_pattern = function() {
    var pattern = null;
    var filter = null;
    var callback = null;
    if (arguments == null)
      throw CommandException(constants.err_argnum);
    switch (arguments.length) {
      case 2:
        pattern = arguments[0];
        callback = arguments[1];
        break;
      case 3:
        pattern = arguments[0];
        filter = arguments[1];
        callback = arguments[2];
        break;
      default:
        throw CommandException(constants.err_argnum);
        break;
    }
    if (!this.active())
      return;
    if (pattern == null)
      throw CommandException("Pattern can not be blank.");
    return this.active_list.lookup_pattern(pattern,filter,callback);
  }

}
document.wordlists = new Wordlists();
