import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.util.LinkedList;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class FaceRecMainGUI extends JFrame implements ActionListener {
	//gui elements
	private JPanel mainPanel, peoplePanel; 
	private JLabel currentStateLabel; //displays the current state
	private JButton haltButton, acquireTrainButton, trainButton, acquireTestButton, testButton; 
	
	//other elements
	LinkedList personPanelLL; 
	
	private FaceRec fr; 
	
	public FaceRecMainGUI(FaceRec fr) {
		super("Face Recognition"); 
		this.fr = fr; 
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
		this.setSize(640, 480); 
		
		mainPanel = new JPanel(); 
		peoplePanel = new JPanel(); 
		
		mainPanel.setLayout(new BorderLayout()); 
		peoplePanel.setLayout(new BoxLayout(peoplePanel, BoxLayout.PAGE_AXIS));
		
		mainPanel.add(peoplePanel, BorderLayout.CENTER); 
		mainPanel.add(getSettingsPanel(), BorderLayout.SOUTH); 
		
		this.add(mainPanel); 
		personPanelLL = new LinkedList(); 
	}
	
	public JPanel getSettingsPanel() { 
		JPanel settingsPanel = new JPanel(); 
		JPanel buttonsPanel = new JPanel();
		
		settingsPanel.setLayout(new BoxLayout(settingsPanel, BoxLayout.PAGE_AXIS));
		buttonsPanel.setLayout(new FlowLayout(FlowLayout.CENTER)); 
		
		currentStateLabel = new JLabel("Current State: Halted"); //default state is halted
		haltButton = new JButton("Halt");
		acquireTrainButton = new JButton("Acquire Training");
		trainButton = new JButton("Train"); 
		acquireTestButton = new JButton("Acquire Test");
		testButton = new JButton("Test"); 
		
		haltButton.addActionListener(this); 
		acquireTrainButton.addActionListener(this); 
		trainButton.addActionListener(this); 
		acquireTestButton.addActionListener(this); 
		testButton.addActionListener(this); 
		
		
		settingsPanel.add(currentStateLabel);
		
		buttonsPanel.add(haltButton);
		buttonsPanel.add(acquireTrainButton);
		buttonsPanel.add(trainButton);
		buttonsPanel.add(acquireTestButton);
		buttonsPanel.add(testButton); 
		
		settingsPanel.add(buttonsPanel); 
		
		return settingsPanel; 
	}
	
	//called by FaceRec when a new person's template has been selected
	public void addPerson(BufferedImage template) {
		PersonPanel pp = new PersonPanel(template); 
		personPanelLL.add(pp); 
		
		peoplePanel.add(pp); 
		this.pack(); 
	}
	public void disableButtons(boolean disableHalt, boolean disableAcquireTrain,
			boolean disableTrain, boolean disableAcquireTest, boolean disableTest) { 

		haltButton.setEnabled(!disableHalt);
		acquireTrainButton.setEnabled(!disableAcquireTrain);
		trainButton.setEnabled(!disableTrain);
		acquireTestButton.setEnabled(!disableAcquireTest);
		testButton.setEnabled(!disableTest); 
	}
	public void updateState(FaceRec.State state) {
		switch (state) {
		case HALTED:
			disableButtons(false, false, false, false, false); 
			currentStateLabel.setText("Halted");
			break;
		case ACQUIRING_TRAINING:
			currentStateLabel.setText("Acquiring Training");
			disableButtons(false, false, true, true, true); 
			break;
		case TRAINING:
			currentStateLabel.setText("Training in Progress");
			disableButtons(true, true, true, true, true); 
			break;
			
		case ACQUIRING_TESTING:
			currentStateLabel.setText("Acquiring Testing Data");
			disableButtons(false, true, true, false, true);
			break;
		case TESTING:
			currentStateLabel.setText("Testing in Progress");
			disableButtons(true, true, true, true, true); 
			break;
		}
	}
	
	public void updateTemplate(int personNum, BufferedImage template, int correlation, FaceRec.State state) {
		PersonPanel pp = (PersonPanel) personPanelLL.get(personNum);
		switch (state) {
		case ACQUIRING_TRAINING:
			pp.updateLastSeen(template, correlation, 0); 
			break;
		case ACQUIRING_TESTING:
			pp.updateLastSeen(template, correlation, 1); 
			break;
		default:
			pp.updateLastSeen(template, correlation, 2); 
			break;
		}
		
	}

	public void actionPerformed(ActionEvent e) {
		if (e.getSource()==haltButton) {
			fr.setState(FaceRec.State.HALTED);
		}
		else if (e.getSource()==acquireTrainButton) {
			fr.setState(FaceRec.State.ACQUIRING_TRAINING);
		}
		else if (e.getSource()==trainButton) {
			fr.setState(FaceRec.State.TRAINING);
		}
		else if (e.getSource()==acquireTestButton) {
			fr.setState(FaceRec.State.ACQUIRING_TESTING);
		}
		else if (e.getSource()==testButton) {
			fr.setState(FaceRec.State.TESTING);
		}
		
	}
}
