/**
 * File: Keys.java
 * @author A.Kurd <alan.kurd@trincoll.edu>
 * 
 * Description: Implements a Java 1.1 version of a GUI tool for creating possible keys.  Most of this is similar to the methods
*  used throughout this program.  The difference being that the keys have final values.
 * Credits: This program is modelled after the frequency test of the CryptoToolJ program by Ralph Morelli.
 *
 * Copyright: This program is in the public domain. You can do whatever you want with
 *  it as long as I get credit for my work and as long as you offer your changes to me
 *  so I can possible add them to the "official" version.
 */
package analyzers;             // Analyzer plugins belong to this package

import hcrypto.analyzer.*;     // This is where Analyzer is
import java.awt.TextArea;
import hcrypto.cipher.*;
import java.awt.*;
import java.awt.event.*;   
import java.util.*;

public class Keys extends Frame implements WindowListener, Analyzer{

   public  Frame  frame[] = new Frame[10];     //the frames that the top 10 KeyGroups are displayed
   public Random rand = new Random();
   public  KeyBuilder kb= new KeyBuilder();   //to count letter frequency
   public Calculate ct = new Calculate();        //to score the different KeyGroups
   public  BigramCount bc= new BigramCount();	//to collect Bigram data
   public TrigramCount tc = new TrigramCount();	//to collect Trigram data
   public KeyGroups kg = new KeyGroups();	//to create possible KeyGroups
   public  String output [] = new String [10];		//The 10 strings were the output is collected
   public int result [] = new int[128];	//array to collect the order of letters for the KeyGroup
   public int TriFreq[][] = new int[128][3];	//for changing Trigram frequencies[] from chars to ints
   public int resultKey [] = new int[128];	//for storing possible keys
   public int random1[] = {1,2,3,4,5,6,7,8};	//for ordering groups 2 thru 5 into keys from KeyGroups
   public int random2[] = {1,2};
   public int random3[] = {1,2,3,4,5,6,7,8,9};
   public int random4[] = {1,2,3};
   private TextArea text1;     // Pointers to the text to be analyzed
   private TextArea display1;  // And the window where results are displayed
   public TextArea display [] = new TextArea[10];	//different display areas
   public char  freqI [] = {'e','t', 'a', 'o', 'i', 'n', 's', 'h', 'r', 'd', 'l', 'c', 'u', 'm', 'w', 'f', 'g', 'y', 'p', 'b','v', 'k', 'j', 'x', 'q', 'z'};//order of letters by frequency
   public int total [] = new int [10];	//scores of KeyGroups
   public int rating [] = new int [10];	//scores of "candidate" keys

   public  void Keys(String text){ }//BigramDisplay

//necessary for the analysis package

   public void setup(TextArea text1, TextArea display1) { 
      this.text1 = text1;
      this.display1 = display1;
   }//setup

   public void run() {
      display1.append("Keys activated" + "\n");
      int n = 1;
      int l =0;
      kb.count(text1.getText());
      bc.count(text1.getText());
      tc.count(text1.getText());
      for(int i=0; i<12; i++)
          if(tc.frequencies[i] != null){
              TriFreq[i][0] = (int)tc.frequencies[i][0];
              TriFreq[i][1] = (int)tc.frequencies[i][1];
              TriFreq[i][2] = (int)tc.frequencies[i][2];}//if
      for( int i = 0; i<10; i++){
         create(i);
         score(i,result);}//for
      int k = total[0];
      for(int j = 1; j<10; j++){
           if(k<total[j]) {k = total[j]; l = j;}//if
      }//for
      result = create(1);
      build(result);
      probable(rating);
   }//run

   public void probable(int r []){
       int greatest = r[0];
       int position = 0;
       for(int i=1;i<10;i++){
           if(r[i] > greatest){ greatest = r[i]; position = i;}//if
       }//for
       display1.append("the value of the most probable key is: " + greatest + " at Key" + (position+1) + "\n");
   }//probable

   public int[] create(int i){
      if(i == 0){
         for(int k = 0; k<kb.tabulate.length; k++)
            result [k] = kb.tabulate[k][1];}//if
      else{
         result[0] = kb.tabulate[i][1];
         result[i] = kb.tabulate[0][1];
         for(int k = 1; k<kb.tabulate.length; k++)
            if (k == i) result[k] = result[k];
            else result[k] = kb.tabulate[k][1]; }//else
      return result;
   }//create

   public void score (int j, int [] res){
     total[j] = ct.accumulate(res, bc.tabulate, 0);
     
   }//score

   public void build (int [] res){
        for( int i = 0; i<4; i++){
             createKey(res,i);
             rate(i);
             frame(i);
        }//for
   }//res
   
   public int [] createKey(int [] res, int count){
        resultKey[0] = res [0];
        for(int i = 0; i<8; i++) resultKey[i+1] = res[((random1[i]+count)%8)+1];
        for(int i = 0; i<2; i++) resultKey[i+9] = res[((random2[i]+count)%2)+9];
        for(int i = 0; i<9; i++) resultKey[i+11] = res[((random3[i]+count)%9)+11];
        for(int i = 0; i<3; i++) resultKey[i+20] = res[((random4[i]+count)%3)+20];
        for(int i = 0; i<3; i++) resultKey[i+23] = res[((random4[i]+count)%3)+23];
        return resultKey;
   }//createKey

   public int [] rate(int r){
        for(int i=0; i<30; i++){
        if(resultKey[1] == bc.tabulate[i][1] && resultKey[7]==bc.tabulate[i][2]) rating[r] = rating[r] + 30-i;
        else if(resultKey[7] == bc.tabulate[i][1] && resultKey[0]==bc.tabulate[i][2]) rating[r] = rating[r] + 29-i;
        else if(resultKey[4] == bc.tabulate[i][1] && resultKey[5]==bc.tabulate[i][2]) rating[r] = rating[r] + 28-i;
        else if(resultKey[0] == bc.tabulate[i][1] && resultKey[8]==bc.tabulate[i][2]) rating[r] = rating[r] + 27-i;
        else if(resultKey[2] == bc.tabulate[i][1] && resultKey[5]==bc.tabulate[i][2]) rating[r] = rating[r] + 26-i;
        else if(resultKey[8] == bc.tabulate[i][1] && resultKey[0]==bc.tabulate[i][2]) rating[r] = rating[r] + 25-i;
        else if(resultKey[0] == bc.tabulate[i][1] && resultKey[9]==bc.tabulate[i][2]) rating[r] = rating[r] + 24-i;
        else if(resultKey[3] == bc.tabulate[i][1] && resultKey[5]==bc.tabulate[i][2]) rating[r] = rating[r] + 23-i;
        else if(resultKey[0] == bc.tabulate[i][1] && resultKey[6]==bc.tabulate[i][2]) rating[r] = rating[r] + 22-i;
        else if(resultKey[6] == bc.tabulate[i][1] && resultKey[1]==bc.tabulate[i][2]) rating[r] = rating[r] + 21-i;
        else if(resultKey[0] == bc.tabulate[i][1] && resultKey[5]==bc.tabulate[i][2]) rating[r] = rating[r] + 20-i;
        else if(resultKey[2] == bc.tabulate[i][1] && resultKey[1]==bc.tabulate[i][2]) rating[r] = rating[r] + 19-i;
        else if(resultKey[1] == bc.tabulate[i][1] && resultKey[3]==bc.tabulate[i][2]) rating[r] = rating[r] + 18-i;
        else if(resultKey[5] == bc.tabulate[i][1] && resultKey[1]==bc.tabulate[i][2]) rating[r] = rating[r] + 17-i;
        else if(resultKey[7] == bc.tabulate[i][1] && resultKey[2]==bc.tabulate[i][2]) rating[r] = rating[r] + 16-i;
        else if(resultKey[5] == bc.tabulate[i][1] && resultKey[9]==bc.tabulate[i][2]) rating[r] = rating[r] + 15-i;
        else if(resultKey[3] == bc.tabulate[i][1] && resultKey[12]==bc.tabulate[i][2]) rating[r] = rating[r] + 14-i;
        else if(resultKey[0] == bc.tabulate[i][1] && resultKey[2]==bc.tabulate[i][2]) rating[r] = rating[r] + 13-i;
        else if(resultKey[5] == bc.tabulate[i][1] && resultKey[16]==bc.tabulate[i][2]) rating[r] = rating[r] + 12-i;
        else if(resultKey[2] == bc.tabulate[i][1] && resultKey[6]==bc.tabulate[i][2]) rating[r] = rating[r] + 11-i;
        else if(resultKey[3] == bc.tabulate[i][1] && resultKey[8]==bc.tabulate[i][2]) rating[r] = rating[r] + 10-i;
        else if(resultKey[1] == bc.tabulate[i][1] && resultKey[4]==bc.tabulate[i][2]) rating[r] = rating[r] + 9-i;
        else if(resultKey[4] == bc.tabulate[i][1] && resultKey[6]==bc.tabulate[i][2]) rating[r] = rating[r] + 8-i;
        else if(resultKey[0] == bc.tabulate[i][1] && resultKey[1]==bc.tabulate[i][2]) rating[r] = rating[r] + 7-i;
        else if(resultKey[4] == bc.tabulate[i][1] && resultKey[1]==bc.tabulate[i][2]) rating[r] = rating[r] + 6-i;
        else if(resultKey[2] == bc.tabulate[i][1] && resultKey[8]==bc.tabulate[i][2]) rating[r] = rating[r] + 5-i;
        else if(resultKey[1] == bc.tabulate[i][1] && resultKey[0]==bc.tabulate[i][2]) rating[r] = rating[r] + 4-i;
        else if(resultKey[6] == bc.tabulate[i][1] && resultKey[0]==bc.tabulate[i][2]) rating[r] = rating[r] + 3-i;
        else if(resultKey[7] == bc.tabulate[i][1] && resultKey[4]==bc.tabulate[i][2]) rating[r] = rating[r] + 2-i;
        else if(resultKey[3] == bc.tabulate[i][1] && resultKey[15]==bc.tabulate[i][2]) rating[r] = rating[r] + 1-i;}//for
   for(int j = 0; j<12; j++){
        if(resultKey[1] == TriFreq[j][0] && resultKey[7]==TriFreq[j][1] && resultKey[0]==TriFreq[j][2]) {rating[r] = rating[r] + 84-j;}//the
        else if(resultKey[4] == TriFreq[j][0] && resultKey[5]==TriFreq[j][1] && resultKey[16]==TriFreq[j][2]) {rating[r] = rating[r] + 41-j;}//ing
        else if(resultKey[2] == TriFreq[j][0] && resultKey[5]==TriFreq[j][1] && resultKey[9]==TriFreq[j][2]) {rating[r] = rating[r] + 40-j; }//and
        else if(resultKey[7] == TriFreq[j][0] && resultKey[0]==TriFreq[j][1] && resultKey[9]==TriFreq[j][2]) {rating[r] = rating[r] + 39-j;}//her
        else if(resultKey[0] == TriFreq[j][0] && resultKey[8]==TriFreq[j][1] && resultKey[0]==TriFreq[j][2]) {rating[r] = rating[r] + 38-j;}//ere
        else if(resultKey[0] == TriFreq[j][0] && resultKey[5]==TriFreq[j][1] && resultKey[1]==TriFreq[j][2]) {rating[r] = rating[r] + 37-j;}//ent
        else if(resultKey[1] == TriFreq[j][0] && resultKey[7]==TriFreq[j][1] && resultKey[2]==TriFreq[j][2]) {rating[r] = rating[r] + 36-j;}//tha
        else if(resultKey[5] == TriFreq[j][0] && resultKey[1]==TriFreq[j][1] && resultKey[7]==TriFreq[j][2]) {rating[r] = rating[r] + 35-j;}//nth
        else if(resultKey[14] == TriFreq[j][0] && resultKey[2]==TriFreq[j][1] && resultKey[6]==TriFreq[j][2]) {rating[r] = rating[r] + 34-j;}//was
        else if(resultKey[0] == TriFreq[j][0] && resultKey[1]==TriFreq[j][1] && resultKey[7]==TriFreq[j][2]) {rating[r] = rating[r] + 33-j;}//eth
        else if(resultKey[15] == TriFreq[j][0] && resultKey[3]==TriFreq[j][1] && resultKey[8]==TriFreq[j][2]) {rating[r] = rating[r] + 32-j;}//for
        else if(resultKey[9] == TriFreq[j][0] && resultKey[1]==TriFreq[j][1] && resultKey[7]==TriFreq[j][2]) {rating[r] = rating[r] + 31-j;}//dth
   }//for
        return rating;
   }//rate()

   public  void frame(int l){   
      
      frame[l] = new Frame ("Keys " + (l+1));
      frame[l].addWindowListener(this);
      frame[l].setResizable(true);
      frame[l].setSize(800, 100);
      frame[l].setLocation(5, 15*l);
      frame[l].setVisible(true);

      output[l] = "";

      for(int k = 0; k<freqI.length; k++){
           if(k%13 == 0 && k != 0) output[l] = output[l] + "\n";
           output[l] = output[l] + freqI[k] + ": " + (char)resultKey[k] + "" + "\t";}//for
      output[l] = output[l] + "\n" + "RATING: " + rating[l];

      display[l] = new TextArea (output[l]);
      frame[l].add(display[l]);
      frame[l].show();
   }//frame
    public void windowClosing(WindowEvent e) {
        for(int l = 0; l<20; l++)
        frame[l].dispose();
    }
    public void windowActivated(WindowEvent e) {}	
    public void windowDeactivated(WindowEvent e) {}
    public void windowClosed(WindowEvent e) {}
    public void windowDeiconified(WindowEvent e) {}
    public void windowIconified(WindowEvent e) {}
    public void windowOpened(WindowEvent e) {}   
}//KeyGroups Class