CommandException = function(msg) {
  return {name:"CommandException",message:msg};
}

document.data_store = new Persist.Store('CPTools');
document.command_history = new Array();
document.command_history_index = 0;

constants.err_argnum = "Invalid number of arguments.";

function scroll_bottom() {
  $('html, body').animate({scrollTop:$("#prompt").offset().top}, 'fast'); 
}
function write_output(text) {
  $("#output").append("<div><pre>" + text + "</pre></div>");
  scroll_bottom();
}

function write_error(text) {
  $("#output").append("<div class=\"error\">" + text.replace(/\n/g,"<br />") + "</div>");
  scroll_bottom();
}

function clear_output() {
  $("#output").html("");
  focusPrompt();
}

function focusPrompt() {
  $("#prompt").focus();
}

function loadHelp(name) {
  var iframe = $("iframe#help_contents").contents();
  iframe.find(".cipher").hide();
  iframe.find("." + name).show();
}

function load_cipher() {
  document.solvers.load(arguments, function(solver){loadHelp(solver.name.toLowerCase());});
}

function display_matches(count,matches) {
  if (matches != null)
  {
    if (count == 0)
      write_output("No matches found.")
    else 
    {
      write_output(numberToStr(count) + " match" + ((count > 1)?"es":"") + " found.");
      var output = "";
      for(i=0;i < matches.length;i++)
        output += matches[i] + "   ";
      write_output(breaklines(output,windowMaxWidth()));
      if (matches.length != count)
        write_output(numberToStr(count - (matches.length - 1)) + " words not shown.");
    }
  }
}

function execute_command(line) {
  var args = new Array();
  try {
    args = spaceSplit(line);
    if (document.solver == null)
      throw CommandException("No solver is loaded.  Please use the LOAD menu on the right to begin.");
    if (args.length > 0)
    {
      args[0] = args[0].toLowerCase();
      if (document.solver._shortcuts[args[0]] != null)
        args[0] = document.solver._shortcuts[args[0]];
      switch (args[0]) {
        case "cls": case "clear":
          clear_output();
          break;
          
        case "pattern": case "p": 
          var output = "";
          if (!document.wordlists.active())
          {
            var temp = "";
            for(i=0;i<arguments.length;i++)
              temp += arguments[i] + " ";
              
            document.data_store.get("wordlist", function(ok, val) {
                if (!ok || val == null) 
                  document.wordlists.load("cplist", function(){execute_command(temp.substring(0,temp.length-1));});                
                else
                  document.wordlists.load(val, function(){execute_command(temp.substring(0,temp.length-1));});
              });
          }
          else
          {
            args.push(display_matches);
            var matches = document.wordlists.lookup_pattern.apply(document.wordlists,args.slice(1,args.length));
          }
          break;
          
        case "wordlist":
          if (args.length == 1)
          {
            if (document.wordlists.active())
              write_output("Current Wordlist: " + document.wordlists.active_name)
            else
              write_output("There is no wordlist currently active.");
          }
          else
            document.wordlists.load(args[1].toUpperCase());
          break;
        
        case "wordlists":
          var output = "";
          for(i=0;i<document.wordlists.available_lists.length;i++)
            output += document.wordlists.available_lists[i] + " ";
          write_output(output);
          break;
          
        default:
          var output = "";
          if (document.solver[args[0]])
          {
            if (document.solver[args[0]] instanceof Function)
              output = document.solver[args[0]].apply(document.solver, args.slice(1))
            else
              output = document.solver[args[0]];
          }
          else
            output = "Unknown command: " + args[0];
          if (!output)
            output = "";
          write_output(output);
          break;
      }
    }
  }
  catch (e) {
    if (e.name == "CommandException")
      write_error(e.message)
    else
      throw e;
  }
  focusPrompt();
}

$(document).ready(function(){
  $("#prompt").keydown(function(e){
    switch(e.which)
    {
      case 13:
        var line = $(this).val();
        if (document.command_history.length + 1 > 10)
          document.command_history.shift();
        document.command_history_index = document.command_history.push(line);
        write_output("> " + line);
        execute_command(line);
        $(this).val("");
        break;
      case 38:
        document.command_history_index = Math.max(0, document.command_history_index - 1);
        $(this).val(document.command_history[document.command_history_index]);
        break;
      case 40:
        document.command_history_index = Math.min(document.command_history.length - 1, document.command_history_index + 1);
        $(this).val(document.command_history[document.command_history_index]);
        break;
      default:
        break;
    }
  });
  
  $("#btnHelp").click(function(){
    $("#btnLoad").removeClass("active");
    $("#pnlLoad").hide();
  
    $("#pnlHelp").toggle("fast");
    $(this).toggleClass("active");
    if ($(this).hasClass("active"))
      loadHelp(document.solver.name.toLowerCase());
    return false;
  });
  
  $("#btnLoad").click(function(){
    $("#btnHelp").removeClass("active");
    $("#pnlHelp").hide();
    
    if (document.solver != null)
    {
      $("#cmbCipher").val(document.solver.name);
      $("#txtCT").val(document.solver.cipher.text);
    }
    $("#pnlLoad").toggle("fast");
    $(this).toggleClass("active");
    return false;
  });
  
  $("#btnLoadCipher").click(function(){  
    $("#pnlLoad").toggle("fast");
    $("#btnLoad").toggleClass("active");
    load_cipher($("#cmbCipher").val(),$("#txtCT").val());
    document.solver.save();
    return false;
  });
  
  document.data_store.get("saved_cipher", function(ok, val) {
    if (!ok || val == null) 
    {
      $("#pnlLoad").toggle("fast");
      $("#btnLoad").toggleClass("active");
    }
    else {
      load_cipher(TAFFY.JSON.parse(val));
    }
  });
});

