<!DOCTYPE html>
<html ng-app="subApp">
  <head>
    <link data-require="bootstrap-css@*" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
    <script data-require="angular.js@*" data-semver="1.4.0-beta.6" src="https://code.angularjs.org/1.4.0-beta.6/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body ng-controller="subController">
    <textarea ng-model="ciphertext" ng-change="update()">
    </textarea>
    <hr>
    <label>Convert: </label><input type="text" ng-model="codechar"/>
    <br>
    <label>To: </label><input type="text" ng-model="plainchar"/>
    <button type="button" class="btn btn-std" ng-click="addchar()">Convert</button>
    <button type="button" class="btn btn-warning" ng-click="guess()">Guess</button>
    <hr>
    <p class="text" ng-bind="ciphertext">
    </p>
    <hr>
    <p class="text" ng-bind="plaintext">
    </p>
    <hr>
    <h3>Current Guess:</h3>
    <ul>
      <li ng-repeat="(cip, pla) in thecode">{{cip}} -> {{pla}}</li>
    </ul>
    <h3>Frequency:</h3>
    <ul>
      <li ng-repeat="letter in freq">{{letter.key}} -> {{letter.value}}</li>
    </ul>

  </body>
</html>
// Code goes here
var theapp = angular.module("subApp", []);

var replaceAll = function(string, needle, replace){
  return string.split(needle).join(replace);
};

var singletons = 
     ["e","t","a","i","n","s","h","r","d","l",
      "c","u","m","w","f","g","y","p","b","o",
      "v","k","j","x","z","q"];

theapp.controller("subController", ["$scope", function($scope){
  $scope.ciphertext = "CAXWE DKXEW ETQXW ETZGZ EACST QXSZY JTYEA ONZTQ CVTKX ZABEKP XTCGC WMVT XZTZJ MCJJZ KPXTC KXEBY XETGC WMVTX YNZTQ CVTQE FZABT QXJPZ  BQTXJ TZRXE  CSWET  QXWET  ZGJ";
  $scope.thecode = {
  };
  $scope.freq = [];
  $scope.update = function(){
    $scope.plaintext = $scope.ciphertext.toUpperCase();
    for (var cchar in $scope.thecode) {
      if ($scope.thecode.hasOwnProperty(cchar)) {
        $scope.plaintext = replaceAll($scope.plaintext, cchar.toUpperCase(), $scope.thecode[cchar].toLowerCase());
      }
    }
    
    var opts = {};
    for (var i = 0; i < $scope.ciphertext.length; i++){
      var codechar = $scope.ciphertext[i].toLowerCase();
      if (opts.hasOwnProperty(codechar) && codechar != ' '){
        opts[codechar] += 1;
      } else {
        opts[codechar] = 1;
      }
    }

    var results = [];
    for (var thekey in opts){
      if (opts.hasOwnProperty(thekey)){
        results.push({key: thekey, value: opts[thekey]});
      }
    }
    results.sort(function(a,b){
      return parseFloat(b.value) - parseFloat(a.value);
    });
    
    $scope.freq = results;
    $scope.$apply();
  };
  
  $scope.guess = function(){
    for (var i =0; i < $scope.freq.length; i++){
      var guessletter = $scope.freq[i].key;
      var plainletter = singletons[i];
      $scope.thecode[guessletter] = plainletter;
      $scope.update();
    }
  };
  
  $scope.addchar = function(){
    $scope.thecode[$scope.codechar] = $scope.plainchar;
    $scope.update();
  };
  
  $scope.update();
}]);
@import url(http://fonts.googleapis.com/css?family=Roboto+Slab);

.text {
  font-family: 'Roboto Slab', serif;
  word-wrap: break-word;
  letter-spacing : 2px;
}