package kryptoScript;

//
// http://www-ti.informatik.uni-tuebingen.de/haeusser/krypto/
// java/Affine.java (Affine Cipher)
// 
// Copyright (c) 1999 Matthias Haeusser
//
// last change: 14.11.1999
//

import java.awt.*;
import java.applet.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class Affine extends Applet implements ActionListener {
   KeyField aField, bField;
   TextField cipherField, plainField, aInvField, bInvField, origField;
   Button encryptButton, decryptButton;
   String _ciphertext, newline = System.getProperty("line.separator");
   int _a, _b;
   boolean encryptDone = false;
   
   // Layout
   public void init() {
      setLayout(new GridBagLayout());
      GridBagConstraints c;

      c = new GridBagConstraints();
      c.gridx = 0; c.gridy = 0;
      c.anchor = GridBagConstraints.WEST;
      add(new Label(getParameter("plaintext")+" m:"), c);
      
      c = new GridBagConstraints();
      c.gridx = 1; c.gridy = 0;
      c.gridwidth = 4; c.anchor = GridBagConstraints.EAST;
      add(plainField = new TextField("AFFINE",28), c);

      c = new GridBagConstraints();
      c.gridx = 0; c.gridy = 1;
      c.anchor = GridBagConstraints.WEST;
      add(encryptButton = new Button(getParameter("encrypt")), c);  

      c = new GridBagConstraints();
      c.gridx = 1; c.gridy = 1;
      add(new Label("a:"), c);
      
      c = new GridBagConstraints();
      c.gridx = 2; c.gridy = 1;
      add(aField = new KeyField("11", 3), c);
      
      c = new GridBagConstraints();
      c.gridx = 3; c.gridy = 1;
      add(new Label("   b:"), c);

      c = new GridBagConstraints();
      c.gridx = 4; c.gridy = 1;
      add(bField = new KeyField("5", 3), c);

      c = new GridBagConstraints();
      c.gridx = 0; c.gridy = 2;
      add(new Label(""), c);

      c = new GridBagConstraints();
      c.gridx = 0; c.gridy = 3;
      c.anchor = GridBagConstraints.WEST;
      add(new Label(getParameter("ciphertext") + " e(m) ="),c);

      c = new GridBagConstraints();
      c.gridx = 1; c.gridy = 3;
      c.gridwidth = 4; c.anchor = GridBagConstraints.EAST;
      add(cipherField = new TextField(28), c);
      cipherField.setEditable(false); // choose true to ease scrolling

      c = new GridBagConstraints();
      c.gridx = 0; c.gridy = 4;
      add(new Label(""), c);

      c = new GridBagConstraints();
      c.gridx = 0; c.gridy = 5;
      c.anchor = GridBagConstraints.WEST;
      add(decryptButton = new Button(getParameter("decrypt")), c);

      c = new GridBagConstraints();
      c.gridx = 1; c.gridy = 5;
      add(new Label("a^-1 ="), c);

      c = new GridBagConstraints();
      c.gridx = 2; c.gridy = 5;
      add(aInvField = new TextField(3), c);
      aInvField.setEditable(false);

      c = new GridBagConstraints();
      c.gridx = 0; c.gridy = 6;
      c.anchor = GridBagConstraints.WEST;
      add(new Label(getParameter("decrypted")+" ="), c);

      c = new GridBagConstraints();
      c.gridx = 1; c.gridy = 6;
      c.gridwidth = 4; c.anchor = GridBagConstraints.EAST;
      add(origField = new TextField(28), c);
      origField.setEditable(false); // choose true to ease scrolling

      // register listeners
      encryptButton.addActionListener(this);
      aField.addActionListener(this);
      bField.addActionListener(this);
      decryptButton.addActionListener(this);
   }

   // listen, dispatch
   public void actionPerformed(ActionEvent e) {
      Object source = e.getSource();
      if ((source == encryptButton) | (source == aField) | (source == bField)) {
	 encrypt();
      }
      if ((source == decryptButton) && encryptDone) {
	 decrypt();
      }
   }
   
   // affine algorithm
   public void encrypt() {
      _a = aField.getKey();
      _b = bField.getKey();
      if ((_a<1) | (_a>26)) {
	 cipherField.setText(getParameter("invalid"));
	 return;
      }
      
      String plaintext;
      char plainchr=0, cipherchr=0;
      _ciphertext="";
      plaintext = plainField.getText();
      for (int t=0; t < plaintext.length(); t++) {
	 plainchr = plaintext.charAt(t);
	 if (Character.isLetter(plainchr)) {
	    int plainint = Helpers.chrIndex(plainchr);
	    int cipherint = (plainint * _a + _b) % 26;
	    cipherchr = Helpers.numToChar(cipherint);
	 }
	 else {
	    cipherchr = plainchr;
	 }
	 _ciphertext += cipherchr;
      }
      
      cipherField.setText(_ciphertext);
      encryptDone = true;
   }
   
   public void decrypt() {
      String origtext="";
      int ainv=0;
      switch (_a) {
      case 1: ainv = 1; break;
      case 3: ainv = 9; break;
      case 5: ainv = 21; break;
      case 7: ainv = 15; break;
      case 9: ainv = 3; break;
      case 11: ainv = 19; break;
      case 15: ainv = 7; break;
      case 17: ainv = 23; break;
      case 19: ainv = 11; break;
      case 21: ainv = 5; break;
      case 23: ainv = 17; break;
      case 25: ainv = 25; break;
      }
      aInvField.setText(String.valueOf(ainv));
      // user may have changed  ciphertext (if isEditable())
      _ciphertext = cipherField.getText();
      for (int t=0; t < _ciphertext.length(); t++) {
	 char cipherchr = _ciphertext.charAt(t);
	 char origchr; int origint=0;
	 if (Character.isLetter(cipherchr)) {
	    int cipherint = Helpers.chrIndex(cipherchr);
	    origint = (ainv * (cipherint + 26 - _b)) % 26;
	    origchr = Helpers.numToChar(origint);
	 }
	 else {
	    origchr = cipherchr;
	 }
	 origtext += origchr;
      }
      origField.setText(origtext);
   }
}
