package com.wjholden.PasswordTable;

import java.applet.Applet;
import java.awt.Font;
import java.awt.Graphics;
import java.security.SecureRandom;

import javax.swing.JTextArea;

/**
 * Creates a password table as inspired by Rex Roof in a LifeHacker article:
 * http://lifehacker.com/5715794/how-to-write-down-and-encrypt-your-passwords-with-an-old+school-tabula-recta
 * @author William John Holden (http://wjholden.com)
 * @version 0.2
 */
public class PasswordTable extends Applet
{
	/**
	 * Eclipse auto-generated this value. Not really sure what it does.
	 */
	private static final long serialVersionUID = -3055579128658695699L;

	/**
	 * The final string to be written to the clients browser window.
	 */
	private StringBuilder sb;
	
	/**
	 * Sun says that the SecureRandom fulfills FIPS 140-2 requirements as described in RFC 1750.
	 * http://download.oracle.com/javase/6/docs/api/java/security/SecureRandom.html
	 */
	private SecureRandom random;
	
	/**
	 * Allows for formatted text (needs to be monospace to look good) and also enables user to 
	 * copy output into whatever they want.
	 */
	private JTextArea textArea;
	
	/**
	 * Initializes the variables, sets up GUI, and builds cypher table.
	 * @since 0.2 Minor formatting bugs fixed.
	 */
	public void init()
	{
		sb = new StringBuilder("");
		random = new SecureRandom();

		textArea = new JTextArea(null, 26 * 2, 26 * 2);
		textArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));
		
		// Whew!  Now I understand why this craziness was painting more than once: this *really* needs to be in init()!
		sb.append("    ");
		for (int i = 0; i < 26; i++)
		{
			sb.append((char) ('A' + i));
			sb.append(' ');
		}
		sb.append("\n  +");
		for (int i = 0; i < 26 * 2; i++)
		{
			sb.append('-');
		}
		sb.append(' ');
		for (int i = 0; i < 26; i++)
		{
			sb.append('\n');
			sb.append((char) ('A' + i));
			sb.append(" | ");
			for (int k = 0; k < 26; k++)
			{
				sb.append(randomCharacter());
				sb.append(' ');
			}
		}
		textArea.setText(sb.toString());
	}
	
	/**
	 * Not used.
	 */
	public void stop() {}
	
	/**
	 * Using two separate loops, the program quickly iterates
	 * and creates the textual table expected by the end user,
	 * then draws it on their browser window.
	 */
	public void paint (Graphics g)
	{
		this.add(textArea);		
	}
	
	/**
	 * Creates a secure, random ASCII character.
	 * @return Random ASCII character ['!','z']
	 */
	private char randomCharacter()
	{
		// '!' is the first character in the ASCII table ('!' == 33)
		// 'z' is the last character in the ASCII table ('z' == 122)
		return((char) (random.nextInt('z' - '!') + '!'));
	}
}
