import javax.swing.JOptionPane;
import java.util.Random;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class VigenereCipher {
    
    public VigenereCipher() {
                /*
                char[] keyArray = new char[256];
                for(int a =0; a < 256; a++) {
                        keyArray[a] = (char)a;
                } // end for
                permute(keyArray);
                 */
        //String keyString = "The snow lay thick on the steps.";
        //String keyString = "tsltotsatsfdbtwlbithotc";
        String keyString = "Florida";
        char[] keyArray = keyString.toCharArray();
        int[] key = new int[keyArray.length];
        for(int i = 0; i < keyArray.length; i++ ) {
            key[i] = keyArray[i];
        } // end for
        while( true ) {
            String input = JOptionPane.showInputDialog("Enter Message","Meet Vaslik at the usual place at 10pm with the $$.");
            if( input == null ) break;
            byte[] inputBytes = new byte[input.length()];
            for( int i = 0; i < inputBytes.length; i++ ) inputBytes[i] = (byte)input.charAt(i);
            byte[] encrypted = encryptVigenere(inputBytes,key);
            try {
                FileOutputStream out = new FileOutputStream("Encrypted");
                out.write(encrypted);
            } catch(IOException e) {
                System.out.println(e);
                e.printStackTrace();
                System.exit(0);
            } // end try/catch
            try {
                FileInputStream in = new FileInputStream("Encrypted");
                in.read(encrypted);
            } catch(IOException e) {
                System.out.println(e);
                e.printStackTrace();
                System.exit(0);
            } // end try/catch
            String encryptedHex = "";
            for( int i = 0; i < encrypted.length; i++ ) encryptedHex += convertToHex(encrypted[i]) + " ";
            JOptionPane.showMessageDialog(null,"Encrypted message is < " + encryptedHex + " >");
            byte[] decrypted = decryptVigenere(encrypted,key);
            String decryptedString = "";
            for( int i = 0; i < decrypted.length; i++ ) decryptedString += (char)decrypted[i];
            JOptionPane.showMessageDialog(null,"Decrypted message is < " + decryptedString + " >");
        } // end while
    } // end constructor
    
    byte[] encryptVigenere(byte[] input, int[] key) {
        byte[] encrypted = new byte[input.length];
        for( int i = 0; i < input.length; i++ ) {
            encrypted[i] = (byte)((input[i]+key[i%key.length])%256);
        }// end for
        return encrypted;
    }// end encryptVigenere
    
    byte[] decryptVigenere(byte[] encrypted, int[] key) {
        byte[] decrypted = new byte[encrypted.length];
        for( int i = 0; i < encrypted.length; i++ ) {
            decrypted[i] = (byte)((encrypted[i]-key[i%key.length]+256)%256);
        }// end for
        return decrypted;
    }// end decryptVigenere
    
    public static void main(String[] a) {
        new VigenereCipher();
    } // end main
    
    public final void permute(char[] chars) {
        Random r = new Random();
        for( int i = 1; i < chars.length; i++ ) {
            char ch = chars[i];
            int j = r.nextInt(i);
            chars[i] = chars[j];
            chars[j] = ch;
        } // end for
    } // end permute
    
    public String convertToHex(byte b) {
        String hex = Integer.toString(b&0xFF,16).toUpperCase();
        if( hex.length() == 1 ) hex = "0" + hex;
        return hex;
    } // end convertToHex
    
} // end VigenereCipher
