import edu.wpi.cetask.guide.*;
import edu.wpi.cetask.*;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;

import java.util.List;

import javax.swing.*;

/**
 * A very simple example of connecting a Swing GUI to a task model.
 */
public class StatGui extends GuiGuide implements ActionListener{
	
	JPanel current_panel;
	JPanel topLevel;
	JPanel ParamEst;
	JPanel CheckNorm;
	JPanel NormEst;
	JPanel BootEst;
	
	File ScriptHome;
	File Rexe;
	File ImageHome;
	
	
	Variable variable1 = new Variable("power", "interval");
	Variable variable2 = new Variable("squish-factor", "ordinal");
	Variable variable3 = new Variable("response", "interval");
	Variable variable4 = new Variable("platform", "nominal");
	
	Variable[] Vars = {variable1, variable2, variable3, variable4};
	
   public static void main (String[] args) {
      new StatGui(Guide.make(args)).loop();
   }
   
   public StatGui (final Guide guide) {
      super(guide);
      // initialize model and decompose toplevel goal A
      //guide.load("models/ABC.xml");
      //guide.load("models/ABC-Ext.xml");
      guide.load("models/exp3.xml");
      guide.task("SelectTopLevelAnalysisGoal");
      guide.getEngine().decomposeAll();
      Task task = guide.processTask("SelectTopLevelAnalysisGoal", null, false);
      //Plan aplan = guide.getEngine().findMatches(guide.processTask("CheckNormalities", null, false), false).get(0);
      List<DecompositionClass> decomps = task.getDecompositions();
      //String[] decomp_methds = new String[20];
      
      DecompositionClass[] decomp_methds = new DecompositionClass[0];
      decomp_methds = decomps.toArray(decomp_methds);
      String[] decomp_string = new String[decomp_methds.length];
      for (int i=0;i<decomp_string.length;i++){
    	  decomp_string[i] = decomp_methds[i].toString();
      }
      
      // textual first input to B
      //final JTextField field = new JTextField("FOO");
      // clicking on buttons is equivalent to executing the task 
      // note PlanButton is not enabled unless plan is live
      //JButton b = new PlanButton("CheckSampleVarNormality") {
      //   protected String getCommand () { 
      //      return "execute B / \""+field.getText()+"\" / 1 / \"y\" ";
      //   }
      //};
      //JButton c = new PlanButtonCommand("C", "execute C / 2 / 1 / 3");
      //JButton c = new PlanButtonCommand("CheckNormality", "done");//"execute C / 2 / 1 / 3");
      // real-time display of JavaScript global state variable
      JButton next = new JButton("What next?");
      next.addActionListener(new ActionListener() {
    	  public void actionPerformed (ActionEvent event) {
    		  //System.out.print(event.getActionCommand());
    		  guide.next("ignore");
    		  JOptionPane.showMessageDialog((Component)frame, (Object)guide.response);
//    		  try {
//                  Runtime rt = Runtime.getRuntime();
//                  Process pr = rt.exec("C:/Program Files/R/R-2.8.1/bin/R.exe --vanilla < \"C:/testrun.R\"");
//                  //int exitVal = pr.waitFor();
//                  //System.out.println("Exited with error code "+exitVal);
//              } catch(Exception e) {
//                  System.out.println(e.toString());
//                  e.printStackTrace();
//              }
      	}
      });
      JLabel sum = new JLabel() {
         @Override
         public String getText () { 
            return "hi";//return "Sum = " + guide.getEngine().eval("variable1.name", "GuiExample");
         }
      };
      JLabel analysisQuery = new JLabel("What type of analysis would you like to perform?");

      JLabel selectEstVar = new JLabel("Please select a variable to estimate.");
      String[] sumStats = {"Mean", "Median", "IQR"};
      final JComboBox statList = new JComboBox(sumStats);
      JLabel selectSumStat = new JLabel("Select a statistic to estimate for the variable.");
      final JComboBox estVarList = new JComboBox(Vars);
      JLabel isNormal = new JLabel("Is the distribution of this statistic normal?");
      final JRadioButton yesButton = new JRadioButton("Yes");
      final JRadioButton noButton = new JRadioButton("No");
      final JRadioButton dunnoButton = new JRadioButton("I don't know");
      dunnoButton.setSelected(true);
      ButtonGroup normalAsk = new ButtonGroup();
      normalAsk.add(yesButton);
      normalAsk.add(noButton);
      normalAsk.add(dunnoButton);
      JPanel normalPanel = new JPanel(new GridLayout(0, 1));
      normalPanel.add(yesButton);
      normalPanel.add(noButton);
      normalPanel.add(dunnoButton);
      JButton EstVarContinue = new JButton("Continue");
      EstVarContinue.addActionListener(this);
      EstVarContinue.addActionListener(new ActionListener() {
    	  public void actionPerformed (ActionEvent event) {
    		  int normality = 0;
    		  if (yesButton.isSelected()) {
    			  normality = 3;
    		  } else if (noButton.isSelected()) {
    			  normality = 2;
    		  } else {
    			  normality = 0;
    		  }
    		  processCommand("execute SelectEstimateVariable / \""+estVarList.getSelectedItem()+"\" / \""+statList.getSelectedItem()+"\" / "+normality);
    	  }
      });
      
      ImageIcon graph = new ImageIcon("lib/test.png", "checking for normality");
      JLabel graphBox = new JLabel(graph);
      JButton graphIsNormal = new JButton("Normal");
      graphIsNormal.addActionListener(this);
      graphIsNormal.addActionListener(new ActionListener() {
    	  public void actionPerformed (ActionEvent event) {
    		  guide.getEngine().eval("normality_check=3", "StatGui");
    		  processCommand("done");
    	  }
      });
      JButton graphIsNotNormal = new JButton("Not Normal");
      graphIsNotNormal.addActionListener(this);
      graphIsNotNormal.addActionListener(new ActionListener() {
    	  public void actionPerformed (ActionEvent event) {
    		  guide.getEngine().eval("normality_check=2", "StatGui");
    		  processCommand("done");
    	  }
      });
      JButton graphIsUnknown = new JButton("I Don't Know");
      graphIsUnknown.addActionListener(this);
      graphIsUnknown.addActionListener(new ActionListener() {
    	  public void actionPerformed (ActionEvent event) {
    		  guide.getEngine().eval("normality_check=1", "StatGui");
    		  processCommand("done");
    	  }
      });
      
      
      final JLabel pValueN = new JLabel("p < 1");
      pValueN.setVisible(false);
      final JButton runNormalEstimation = new JButton("Run Normal Estimation");
      final JButton normEstContinue = new JButton("Try Bootstrap");
      normEstContinue.setVisible(false);
      normEstContinue.addActionListener(this);
      runNormalEstimation.addActionListener(new ActionListener() {
    	  public void actionPerformed (ActionEvent event) {
    		  //guide.getEngine().eval("p_value=0.14", "StatGui");
    		  pValueN.setText("Normal failed! p < 0.14");
    		  pValueN.setVisible(true);
    		  normEstContinue.setVisible(true);
    		  runNormalEstimation.setEnabled(false);
    		  frame.pack();
    		  processCommand("execute NormalEstimation / "+0.14);
    	  }
      });
      
      final JLabel pValueB = new JLabel("p < 1");
      pValueB.setVisible(false);
      final JButton runBootEstimation = new JButton("Run Bootstrap Estimation");
      final JButton failBootEstimation = new JButton("Fail!");
      final JButton bootEstContinue = new JButton("Try a hypothesis test.");
      bootEstContinue.setVisible(false);
      bootEstContinue.addActionListener(this);
      runBootEstimation.addActionListener(new ActionListener() {
    	  public void actionPerformed (ActionEvent event) {
    		  //guide.getEngine().eval("p_value=0.14", "StatGui");
    		  pValueB.setText("Success! p < 0.02");
    		  pValueB.setVisible(true);
    		  runBootEstimation.setEnabled(false);
    		  failBootEstimation.setEnabled(false);
    		  processCommand("execute BootstrapEstimation / "+0.02);
    		  frame.pack();
    	  }
      });
      failBootEstimation.addActionListener(new ActionListener() {
    	  public void actionPerformed (ActionEvent event) {
    		  //guide.getEngine().eval("p_value=0.14", "StatGui");
    		  pValueB.setText("Bootstrap failed! p < 0.09");
    		  pValueB.setVisible(true);
    		  bootEstContinue.setVisible(true);
    		  runBootEstimation.setEnabled(false);
    		  failBootEstimation.setEnabled(false);
    		  processCommand("execute BootstrapEstimation / "+0.09);
    		  frame.pack();
    	  }
      });

    //Create the combo box, select item at index 4.
    //Indices start at 0, so 4 specifies the pig.
    JComboBox decompList = new JComboBox(decomp_string);
    //petList.setSelectedIndex(4);
    decompList.addActionListener(this);
    decompList.addActionListener(new ActionListener() {
    	public void actionPerformed (ActionEvent event) {
    		JComboBox cb = (JComboBox)event.getSource();
    		processCommand("by " + (String)cb.getSelectedItem());
            //guide.by((String)cb.getSelectedItem());
    		cb.setEnabled(false);
    	}
    });

      // layout hacking
      Dimension size = new Dimension(300, 150);
      Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();  // for centering
      frame.addNotify(); // create peer for insets
      frame.setTitle("StatAdvisor");
      Insets insets = frame.getInsets();
      int width = size.width + insets.left + insets.right;
      int height = size.height + insets.top + insets.bottom;
      frame.setBounds((screen.width - width)/2, (screen.height - height)/2,  // center in screen
                     width, height);
      JPanel buttons = new JPanel(new GridLayout(1,2,20,20));
      //buttons.setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
      Font font = new Font("Dialog", Font.BOLD, 30);
      //b.setFont(font);
      //c.setFont(font);
      sum.setFont(font);
      //buttons.add(b);
      //buttons.add(c);
      JPanel panel = new JPanel();
      //panel.setVisible(false);
      topLevel = new JPanel();
      current_panel = topLevel;
      ParamEst = new JPanel();
      ParamEst.setVisible(false);
      CheckNorm = new JPanel();
      CheckNorm.setVisible(false);
      NormEst = new JPanel();
      NormEst.setVisible(false);
      BootEst = new JPanel();
      BootEst.setVisible(false);
      panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
      topLevel.setLayout(new BoxLayout(topLevel, BoxLayout.Y_AXIS));
      ParamEst.setLayout(new BoxLayout(ParamEst, BoxLayout.Y_AXIS));
      CheckNorm.setLayout(new BoxLayout(CheckNorm, BoxLayout.Y_AXIS));
      NormEst.setLayout(new BoxLayout(NormEst, BoxLayout.Y_AXIS));
      BootEst.setLayout(new BoxLayout(BootEst, BoxLayout.Y_AXIS));
      CheckNorm.setVisible(false);
      
      //Parameter Estimation
      ParamEst.add(selectEstVar);
      ParamEst.add(estVarList);
      ParamEst.add(selectSumStat);
      ParamEst.add(statList);
      ParamEst.add(isNormal);
      ParamEst.add(normalPanel);
      ParamEst.add(EstVarContinue);
      
      //Check Normal
      CheckNorm.add(graphBox);
      CheckNorm.add(graphIsNormal);
      CheckNorm.add(graphIsNotNormal);
      CheckNorm.add(graphIsUnknown);
      
      //Normal Estimation
      NormEst.add(pValueN);
      NormEst.add(runNormalEstimation);
      NormEst.add(normEstContinue);
      
      //Bootstrap Estimation
      BootEst.add(pValueB);
      BootEst.add(runBootEstimation);
      BootEst.add(failBootEstimation);
      BootEst.add(bootEstContinue);
      
      //panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
      //topLevel.setVisible(false);
      topLevel.add(analysisQuery);
      topLevel.add(decompList);
      panel.add(topLevel);
      panel.add(ParamEst);
      panel.add(CheckNorm);
      panel.add(NormEst);
      panel.add(BootEst);
      panel.add(next);
      sum.setAlignmentX(Component.CENTER_ALIGNMENT);
      next.setAlignmentX(Component.LEFT_ALIGNMENT);
      //frame.getContentPane().add(BorderLayout.CENTER, panel);
      frame.getContentPane().add(panel);
      //frame.getContentPane().add(BorderLayout.CENTER, topLevel);
      frame.pack();
      frame.setVisible(true);
    }

@Override
public void actionPerformed(ActionEvent e) {
	//apparently java can't use a switch-case statement on strings... dumb
	guide.next("ignore");
	String focus = guide.getEngine().getFocus().toString();
	//guide.getEngine().getFocus().getGoal()
	if (focus.equals("SelectEstimateVariable")) {
		//frame.getContentPane().remove(topLevel);
		current_panel.setVisible(false);
		ParamEst.setVisible(true);
		current_panel = ParamEst;
		frame.pack();
	} else if (focus.equals("CheckNormality")) {
		current_panel.setVisible(false);
		CheckNorm.setVisible(true);
		current_panel = CheckNorm;
		frame.pack();
	} else if (focus.equals("NormalEstimation")) {
		current_panel.setVisible(false);
		NormEst.setVisible(true);
		current_panel = NormEst;
		frame.pack();
	} else if (focus.equals("BootstrapEstimation")) {
		current_panel.setVisible(false);
		BootEst.setVisible(true);
		current_panel = BootEst;
		frame.pack();
	} else if (focus.equals("SelectSampleVar")) {
		current_panel.setVisible(false);
		topLevel.setVisible(true);
		current_panel = topLevel;
		frame.pack();
	}
}
   
}
