function Aristocrat() {
  this.decrypt_filter = function(character) {return (constants.ascii_letters + constants.ascii_punctuation + " \r\n").indexOf(character) > -1};
  this.encrypt_filter = this.decrypt_filter;
  this.ctkey = constants.ascii_uppercase;
  this.ptkey = "--------------------------";
  
  function process(key1, key2, text) {
    var output = "";
    for (i=0;i < text.length;i++)
    {
      var index = key1.indexOf(text[i]);
      if (index > -1)
        output += key2[index]
      else if (constants.ascii_letters.indexOf(text[i]) > -1)
        output += "-"
      else
        output += text[i];
    }
    return output;
  }
  
  this.__proto__decrypt = this.decrypt;
  this.decrypt = function(text) {
    text = this.__proto__decrypt(text);
    return process(this.ctkey, this.ptkey, text.toUpperCase());
  }
 
  this.__proto__encrypt = this.encrypt;
  this.encrypt = function(text) {
    text = this.__proto__encrypt(text);
    return process(this.ptkey, this.ctkey, text.toLowerCase());
  }
  
  this.set = function(ct, pt) {
    var ct = ct.toUpperCase();
    var pt = pt.toLowerCase();
    if (pt == "-")
      pt = strRepeat("-",ct.length);
    if (ct.length != pt.length)
      throw CommandException("Not enough characters were inputted.");
    for (i=0;i < ct.length;i++)
      this.ptkey = setCharAt(this.ptkey,this.ctkey.indexOf(ct[i]), pt[i]);
  }
}
Aristocrat.prototype = new Cipher();

function AristocratSolver () {
  this.cipher = new Aristocrat();
  this._shortcuts["f"] = "frequency";
  this._shortcuts["k"] = "keys";
  this._shortcuts["s"] = "set";
  this._shortcuts["ts"] = "test_set";

  this.display = function() {
    var data = "";
    var ct = breaklines(this.text(), windowMaxWidth()).split("\n");
    var pt = breaklines(this.cipher.decrypt(), windowMaxWidth()).split("\n");
    for (i = 0;i < ct.length;i++)
    {
      data += ct[i] + "\n";
      data += pt[i] + "\n\n";
    }
    return trim(data);
  }

  this.frequency = function(length) {
    if (length == null)
      length = 1;
    return this._print_counts(calcGraphs(this.text().split(" "),length,(length == 1)));
  }
  
  this.keys = function() {
    var output = "";
    output += "CT: " + this.cipher.ctkey + "\npt: " + this.cipher.ptkey + "\n\n";
    sorter = new Array();
    for (i=0;i < this.cipher.ptkey.length;i++)
      sorter[i] = this.cipher.ptkey[i] + this.cipher.ctkey[i];
    sorter = sorter.sort();
    var ptpart = "";
    var ctpart = "";
    for (i=0;i < sorter.length;i++)
    {
      ptpart += sorter[i][0];
      ctpart += sorter[i][1];
    }
    output += "pt: " + ptpart + "\nCT: " + ctpart + "\n";
    return output;
  }

  this.set = function(ct,pt) {
    if (arguments.length < 1)
      throw CommandException(constants.err_argnum);
    if (pt == null)
      pt = "-";
    this.cipher.set(ct,pt);
    this.save();
    return this.display();
  }
  
  this.test_set = function(ct,pt) {
    var temp_pt = this.cipher.ptkey;
    var result = this.set(ct,pt);
    this.cipher.ptkey = temp_pt;
    return result;
  }
  
  this.__proto___load__ = this._load_;
  this._load_ = function(data) {
    this.__proto___load__(data);
    if (data.ctkey != null)  
      this.cipher.ctkey = data.ctkey;
    if (data.ptkey != null)  
      this.cipher.ptkey = data.ptkey;
  }
  
  this.__proto___save__ = this._save_;
  this._save_ = function(data) {
    data = this.__proto___save__(data);
    data.ctkey = this.cipher.ctkey;
    data.ptkey = this.cipher.ptkey;
    return data;
  }
}
AristocratSolver.prototype = new CipherSolver();
document.solvers.register("Aristocrat",AristocratSolver);
