import java.applet.Applet;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyAdapter;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class Selector extends Applet {
    public final static byte NUMBER = (byte)Players.values().length;
    public static enum Shot { OUT, PEN, IN }
    public static enum Defense { NORMAL, CLOSE, SAG }

    public static enum Players {
	WALL(       "John Wall       ", Shot.PEN, Defense.NORMAL, 8.9, 7, 3, .805, 0),
	SESSIONS(   "Ramon Sessions  ", Shot.PEN, Defense.NORMAL, 9.6, 11, 5, .807, 0), 
	STUCKEY(    "Rodney Stuckey  ", Shot.PEN, Defense.NORMAL, 9.1, 8, 3, .836, 0), 
	GREEN(      "Gerald Green    ", Shot.PEN, Defense.CLOSE,  9.2, 6, 2, .848, 0), 
	LEONARD_OUT("Leonard outside ", Shot.OUT, Defense.CLOSE,  10.8, 1, 0, .802, 8),
	LEONARD_PEN("Leonard pen     ", Shot.PEN, Defense.CLOSE,  4.2, 1, 0, .802, 8),
	LEONARD_IN( "Leonard inside  ", Shot.IN,  Defense.NORMAL, 12.3, 1, 0, .802, 8), 
	STOUDEMIRE( "Amare Stoudemire", Shot.IN,  Defense.NORMAL, 17.9, 6, 3, .739, 0); 

	Players(String name, Shot shot, Defense defense, double x, int F2, int F1, double ft, int replays) {
	    this.name = name;
	    this.shot = shot;
	    this.defense = defense;
	    this.x = x;
	    this.F2 = F2;
	    this.F1 = F1;
	    this.ft = ft;
	    this.replays = replays;
	}

	private String name;
	private Shot shot;
	private Defense defense;
	private double x;
	private int F2;
	private int F1;
	private double ft;
	private int replays;
    }

    /*
http://web.archive.org/web/20050915093110/http://pages.prodigy.net/drlittle/DefenseProject.html
         norm       close       sag
outside  10.34      4.75        15.95
pen      8.25/3/6   13.75/3/6   norm
inside   10.1/3/6   norm        1.75/3/6
    */
    double teamDefense[][] = { { 0.574, 0.264, 0.886 }, { 0.418, 0.723, 0.418 },
			       { 0.520, 0.520, 0.057 } };

    JPanel panels[] = new JPanel[NUMBER];
    JComboBox defenseChoice[] = new JComboBox[NUMBER];
    LinkedTextField defense[] = new LinkedTextField[NUMBER];
    JPanel intimidator = new JPanel();
    JLabel intimidatorLabel = new JLabel("Intimidator");
    JTextField block = new JTextField(3);
    JTextArea results = new JTextArea(15, 30);
    JButton compute = new JButton("COMPUTE");
    JButton clear = new JButton("CLEAR");
    JButton close = new JButton("CLOSE");
    JPanel buttons = new JPanel();
    JPanel top = new JPanel();
    ButtonListener buttonListener = new ButtonListener();
    PlayerKeyListener keyListener = new PlayerKeyListener();
    Color dodgerBlue = new Color(30, 154, 255);
    Color melon = new Color(254, 186, 173);

    public void init() {
	setLayout(new GridLayout(2, 0));
	top.setLayout(new GridLayout(11, 0));
	int i = 0;
	for (Players player : Players.values()) {
	    panels[i] = new JPanel();
	    JLabel line = new JLabel(player.name);
	    line.setPreferredSize(new Dimension(130, 30));
	    panels[i].add(line);
	    Defense[] defenseChoices = { Defense.NORMAL, Defense.CLOSE, Defense.SAG };
	    defenseChoice[i] = new JComboBox<Defense>(defenseChoices);
	    defenseChoice[i].setSelectedIndex(player.defense.ordinal());
	    panels[i].add(defenseChoice[i]);
	    defense[i] = new LinkedTextField(3);
	    defense[i].setText("");
	    defense[i].setMaximumSize(new Dimension(20, 20));
	    if (i > 0) {
		defense[i].setPrev(defense[i-1]);
		defense[i - 1].setNext(defense[i]);
	    }
	    defense[i].addKeyListener(keyListener);
	    defense[i].setFocusTraversalKeysEnabled(false);
	    panels[i].add(defense[i]);
	    panels[i].setOpaque(false);
	    top.add(panels[i]);
	    i++;
	}
	defense[NUMBER - 1].setNext(defense[0]);
	defense[0].setPrev(defense[NUMBER - 1]);
	int width = (int)defenseChoice[0].getPreferredSize().getWidth() + 135;
	intimidatorLabel.setPreferredSize(new Dimension(width, 20));
	intimidator.add(intimidatorLabel);
	block.setText("10");
	block.setMaximumSize(new Dimension(50, 20));
	intimidator.add(block);
	intimidator.setOpaque(false);
	top.add(intimidator);

	compute.addActionListener(buttonListener);
	compute.setBackground(Color.GREEN);
	clear.addActionListener(buttonListener);
	clear.setBackground(Color.YELLOW);
	close.addActionListener(buttonListener);
	close.setBackground(Color.RED);
	buttons.add(compute);
	buttons.add(clear);
	buttons.add(close);
	buttons.setOpaque(false);
	top.add(buttons);
	top.setBackground(dodgerBlue);
	add(top);
	results.setBackground(melon);
	add(results);
    }

    public class LinkedTextField extends JTextField {
	public LinkedTextField(int val) { super(val); }
	private LinkedTextField prev = null;
	private LinkedTextField next = null;
	public LinkedTextField getPrev() { return prev; }
	public LinkedTextField getNext() { return next; }
	public void setPrev(LinkedTextField field) { prev = field; }
	public void setNext(LinkedTextField field) { next = field; }
    }

    public class PlayerKeyListener extends KeyAdapter {
	public void keyPressed(KeyEvent e) {
	    if (e.getKeyCode() == KeyEvent.VK_TAB) {
		LinkedTextField field = (LinkedTextField)e.getSource();
		if (e.getModifiers() > 0) {
		    if (field.getPrev() != null) {
			field.getPrev().requestFocusInWindow();
		    }
		} else {
		    if (field.getNext() != null) {
			field.getNext().requestFocusInWindow();
		    }
		}
		e.consume();
	    }
	}
    }

    public class ButtonListener implements ActionListener {
	public void actionPerformed(ActionEvent actionEvent) {
	    if (actionEvent.getActionCommand().equals("COMPUTE"))
		compute();
	    if (actionEvent.getActionCommand().equals("CLEAR")) {
		for (int i = 0; i < NUMBER; i++) {
		    defense[i].setText("");
		    defenseChoice[i].setSelectedIndex(Players.values()[i].defense.ordinal());
		}
		block.setText("10");
	    }
	    if (actionEvent.getActionCommand().equals("CLOSE"))
		System.exit(0) ;
	}
    }

    public void compute() {
	results.setText("");
	double blockAdjustment = 12 / 36. * (new Integer(block.getText()) - 10) / 20;
	for (Players player : Players.values()) {
	    int index = player.ordinal();
	    String value = defense[index].getText();
	    if (value.isEmpty())
		continue;
	    double card = (player.x * 2 + (player.F2 * 2 + player.F1) * player.ft) / 36;
	    int choice = defenseChoice[index].getSelectedIndex();
	    double ftAdjustment = player.shot == Shot.OUT ? 0 : 1 / 12. * 2 * (player.ft - .756);
	    double teamD = teamDefense[player.shot.ordinal()][choice] + ftAdjustment;
	    double xDefense = (6 - (new Double(value))) / 3;
	    double pps = (3 * card + 2 * teamD + xDefense - (player.shot == Shot.PEN || player.shot == Shot.IN ? 2 * blockAdjustment : 0)) / 6;
	    pps = trim(pps);
	    int foulDraw = (int)((player.F2 + player.F1 + 2) * 100 / 72.);
	    results.append(player.name + " " + pps + " " + foulDraw + "%\n");
	}
    }

    public double trim(double input) {
	int trim = (int)(input * 100);
	return trim / 100.;
    }

    public static void main(String args[]) {
	Selector instance = new Selector();
	instance.init();

	Frame f = new Frame("Shooter Selection Tool");
	f.setSize(300, 650);
	f.add("Center", instance);
	f.setVisible(true);
    }
}
