import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import javax.swing.border.TitledBorder;

/**
 * This class defines the GUI for the main and 
 * only window (Control Panel) of QuanFruit.
 */
public class FruitApplet extends JApplet{
	private JLabel 		_L_image;
	private JTextField	_TF_filePrefix;
	private JComboBox 	_CB_lineNumBits;
	private JComboBox 	_CB_treeNumBits;
	private JTextField	_TF_strength;
	private JTextField	_TF_lineDoor;
	private JTextField	_TF_oracleBands;
	private JComboBox 	_CB_lineNumTrots;
	private JComboBox 	_CB_lineOrderApprox;
	private JComboBox 	_CB_treeNumTrots;
	private JComboBox 	_CB_metaNumTrots;
	private JComboBox 	_CB_metaOrderApprox;
	private JButton		_B_computeSEO;
	private JTextField	_TF_numBits;
	private JTextField	_TF_lenOfSEO;
	private JTextField	_TF_error;
	private JTextArea	_TA_message;
/**
 * 
 */
	public void init(){
		java.net.URL iconURL = getClass().getResource("qfru-logo.gif");
		_L_image = new JLabel(new ImageIcon(iconURL));
		_TF_filePrefix = new JTextField();
		_CB_lineNumBits = new JComboBox(new String[]
		    {"2", "3", "4", "5", "6", "7", "8"});
		_CB_treeNumBits = new JComboBox(new String[]
		    {"2", "3", "4", "5", "6", "7", "8"});
		_TF_strength = new JTextField();
		_TF_lineDoor = new JTextField();
		_TF_oracleBands = new JTextField();
		_CB_lineNumTrots = new JComboBox(new String[]
            {"1", "2", "3", "4", "5"});
        _CB_lineOrderApprox = new JComboBox(new String[]
            {"2", "4", "6", "8"});
		_CB_treeNumTrots = new JComboBox(new String[]
		    {"1", "2", "3", "4", "5"});
		_CB_metaNumTrots = new JComboBox(new String[]
		    {"1", "2", "3", "4", "5"});
		_CB_metaOrderApprox = new JComboBox(new String[]
		    {"2", "4", "6", "8"});		                                        
		_B_computeSEO = new JButton("Write Files");
		_TF_numBits = new JTextField();
		_TF_numBits.setEditable(false);
		_TF_lenOfSEO = new JTextField();
		_TF_lenOfSEO.setEditable(false);
		_TF_error = new JTextField();
		_TF_error.setEditable(false);
		_TA_message = new JTextArea();
		_TA_message.setEditable(false);
		_TA_message.setRows(2);
		_TA_message.setLineWrap(true);
		_TA_message.setWrapStyleWord(true);
		
		
		JPanel pan0 = new JPanel(new BorderLayout(2, 2));//hgap, vgap
		pan0.add(_L_image, BorderLayout.CENTER);
		pan0.add(new JLabel(Globals.VERSION), BorderLayout.SOUTH);
		
		JPanel pan1 = new JPanel(new GridLayout(12, 2));//rows, cols
		pan1.add(new JLabel("File Prefix"));
			pan1.add(_TF_filePrefix);
		pan1.add(new JLabel("Line: Number of Qubits"));
			pan1.add(_CB_lineNumBits);
		pan1.add(new JLabel("Tree: Number of Qubits"));
			pan1.add(_CB_treeNumBits);
		pan1.add(new JLabel("Coupling Constant"));
			pan1.add(_TF_strength);
		pan1.add(new JLabel("Line Door"));
			pan1.add(_TF_lineDoor);
		pan1.add(new JLabel("Bands"));
			pan1.add(_TF_oracleBands);
		pan1.add(new JLabel("Line: Number of Trots"));
			pan1.add(_CB_lineNumTrots);
		pan1.add(new JLabel("Line: Order of Approx."));
			pan1.add(_CB_lineOrderApprox);
		pan1.add(new JLabel("Tree: Number of Trots"));
			pan1.add(_CB_treeNumTrots);
		pan1.add(new JLabel("Tree: Order of Approx."));
			pan1.add(new JLabel("3"));
		pan1.add(new JLabel("Meta: Number of Trots"));
			pan1.add(_CB_metaNumTrots);
		pan1.add(new JLabel("Meta: Order of Approx."));
			pan1.add(_CB_metaOrderApprox);

		pan1.setBorder(new TitledBorder("Inputs"));
		
		JPanel pan2 = new JPanel(new FlowLayout(FlowLayout.RIGHT));
		pan2.add(_B_computeSEO);

		JPanel pan012 = new JPanel(new BorderLayout(2, 2));//hgap, vgap
		pan012.add(pan0, BorderLayout.NORTH);
		pan012.add(pan1, BorderLayout.CENTER);
		pan012.add(pan2, BorderLayout.SOUTH);
		
		JPanel pan3 = new JPanel(new GridLayout(4, 2));//rows, cols
		pan3.add(new JLabel("Number of Qubits"));
			pan3.add(_TF_numBits);
		pan3.add(new JLabel("Number of Elem. Ops."));
			pan3.add(_TF_lenOfSEO);
		pan3.add(new JLabel("Error"));
			pan3.add(_TF_error);
		pan3.add(new JLabel("Message"));
			pan3.add(_TA_message);
		pan3.setBorder(new TitledBorder("Output Highlights"));
		
		setLayout(new BorderLayout(2, 2));//hgap, vgap
		add(pan012, BorderLayout.CENTER);
		add(pan3, BorderLayout.SOUTH);
		
		_B_computeSEO.addActionListener(new ButtonListener());
	}
	
/**
 *
 */
	private class ButtonListener implements ActionListener{

		public void actionPerformed(ActionEvent eve) {

	        String 	filePrefix;
	        int lineNumBits;
	        int treeNumBits;
	        double strength;
	        int lineDoor;
			OracleBands bands;
			int  lineNumTrots;
			int  lineSuzukiHalfOrder;			
			int  treeNumTrots;
			int  metaNumTrots;
			int  metaSuzukiHalfOrder;
			
			try{
				if(	_TF_filePrefix.getText().length()==0 ||
					_TF_strength.getText().length()==0 ||
					_TF_lineDoor.getText().length()==0 ||
					_TF_oracleBands.getText().length()==0)
				{ throw new Exception();}
				
				filePrefix = _TF_filePrefix.getText();
				
				lineNumBits = _CB_lineNumBits.getSelectedIndex() + 2;
				
				treeNumBits = _CB_treeNumBits.getSelectedIndex() + 2;
				
				strength = Double.parseDouble(_TF_strength.getText());
				
				lineDoor =  Integer.parseInt(_TF_lineDoor.getText());				

				
				String[] s = _TF_oracleBands.getText().split("\\D");
				int numBands = s.length;
				if(numBands%2==1){
					throw new Exception();
				}else{
					numBands = numBands/2;
				}
				int[][] mat = new int[numBands][2];
				int counter = 0;
				for(int j=0; j < s.length; j++){
					mat[counter/2][counter%2] = 
						Integer.parseInt(s[j]);
					counter++;
				}		
				bands = new OracleBands(treeNumBits-1, mat);

				
				lineNumTrots = _CB_lineNumTrots.getSelectedIndex() + 1;
				lineSuzukiHalfOrder = _CB_lineOrderApprox.getSelectedIndex() + 1;

				treeNumTrots = _CB_treeNumTrots.getSelectedIndex() + 1;

				metaNumTrots = _CB_metaNumTrots.getSelectedIndex() + 1;
				metaSuzukiHalfOrder = _CB_metaOrderApprox.getSelectedIndex() + 1;

				FruitMain 	m = new FruitMain(
		    	        filePrefix,
		    	        lineNumBits,
		    	        treeNumBits,
		    	        strength,
		    	        lineDoor,
		    			bands,
		    			lineNumTrots,
		    			lineSuzukiHalfOrder,			
		    			treeNumTrots,
		    			metaNumTrots,
		    			metaSuzukiHalfOrder);
				_TF_numBits.setText(String.format("%d", m.getNumBits()));
				_TF_lenOfSEO.setText(String.format("%d", m.getLenOfSEO()));
				_TF_error.setText(String.format("%e", m.getError()));
				_TA_message.setText("");
			}
			catch(Exception ex){
				_TF_numBits.setText("");
				_TF_lenOfSEO.setText("");
				_TF_error.setText("");
				_TA_message.setText("(BAD INPUT) " + ex.getMessage());
				return;
			}
			
			

		}
	
	}
/**
 *
 */
	public static void main(String[] args) {
	    
	    JFrame frame = new JFrame("QuanFruit");

	    
	    FruitApplet applet = new FruitApplet();

	    frame.add(applet, BorderLayout.CENTER);

	    applet.init();

	    frame.setLocationRelativeTo(null); // Center the frame
	    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);	    
	    frame.pack();//frame.setSize(400, 250);
	    frame.setVisible(true);
	  }


}

