/* import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JTextField;
import javax.swing.JLabel;
import javax.swing.JCheckBox;
*/
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.lang.Thread;
import java.lang.Runnable;

/**
 * Title:        PlacementApplet
 * Description:  Animation of VLSI Module Placement
 * Copyright:    Copyright (c) 2001
 * Company:      Lafayette College
 * @author John Nestor
 * @version 1.0
 *
 */

/** provides user-interface for annealing */
public class UIAnnealer extends JPanel implements Runnable, ActionListener {
  private PAnnealer myAnnealer;
  private static final int STOP=0;
  private static final int RUN=1;
  private static final int PAUSE = 2;
  private static final int STEP = 3;
  private int state = STOP;
  private boolean animate = true;
  private Thread runner = null;
  private UIOptionsDialog myDialog;

  // options
  private double optT0=0.0001;
  private boolean optT0Adaptive = true;
  private boolean optAnimateMoves = true;
  private int optMovesPerTemp = 0;
  private boolean optMovesPerTempPerModule = false;
  private double optCoolRate = 0.95;
  private int optSpeed = 50;

  public void setOptT0Adaptive(boolean b) { optT0Adaptive = b; }

  public void setOptInitialTemperature(double t0) { optT0 = t0; }

  public void setOptAnimateMoves(boolean b) { optAnimateMoves = b; }

  public void setOptMovesPerTemp(int m) { optMovesPerTemp = m; }
  public int getOptMovesPerTemp() { return optMovesPerTemp; }

  public void setOptMovesPerTempPerModule(boolean b) { optMovesPerTempPerModule = b; }
  public boolean getOptMovesPerTempPerModule() { return optMovesPerTempPerModule; }

  public void setOptCoolRate(double d) { optCoolRate = d; }

  public double getOptCoolRate() { return optCoolRate; }

  public void setOptSpeed(int s) { optSpeed = s; }

  public int getOptSpeed() { return optSpeed; }

  // user-interface elements
  private JPanel historyPanel;
  private JPanel statusPanel;
  private JPanel controlPanel;
  private JToggleButton stopButton = new JToggleButton("STOP",true);
  private JToggleButton runButton = new JToggleButton("RUN");
  private JToggleButton pauseButton = new JToggleButton("PAUSE");
  private JToggleButton stepButton = new JToggleButton("STEP");
  private ButtonGroup bg = new ButtonGroup();
  private JLabel tempLabel = new JLabel("T=");
  private JTextField tempField = new JTextField(8);
  private UIValDisplay tempDisplay = new UIValDisplay("Temperature",0);
  private UIValDisplay attemptsDisplay = new UIValDisplay("Attempts",0);
  private UIValDisplay acceptedDisplay = new UIValDisplay("Accepted",0);
  private UIValDisplay percentDisplay = new UIValDisplay("%",0);

  public UIAnnealer(PAnnealer p) {
    myAnnealer = p;
    setLayout(new BorderLayout());
    JPanel statusPanel = new JPanel(new GridLayout(1,5));
    statusPanel.add(tempDisplay);
    statusPanel.add(attemptsDisplay);
    statusPanel.add(acceptedDisplay);
    statusPanel.add(percentDisplay);
    JPanel controlPanel = new JPanel(new FlowLayout());
    bg.add(stopButton);
    bg.add(runButton);
    bg.add(pauseButton);
    bg.add(stepButton);
    stopButton.setActionCommand("STOP");
    runButton.setActionCommand("RUN");
    pauseButton.setActionCommand("PAUSE");
    stepButton.setActionCommand("STEP");
    stopButton.addActionListener(this);
    runButton.addActionListener(this);
    pauseButton.addActionListener(this);
    stepButton.addActionListener(this);

    controlPanel.add(stopButton);
    controlPanel.add(runButton);
    controlPanel.add(pauseButton);
    controlPanel.add(stepButton);
    add(statusPanel,BorderLayout.NORTH);
    add(controlPanel,BorderLayout.SOUTH);
    historyPanel = new UITempHistory(p);
    add(historyPanel,BorderLayout.CENTER);
    myDialog = new UIOptionsDialog(this);
    myDialog.pack();
    myDialog.setVisible(true);
    myDialog.repaint();
  }

  public synchronized void actionPerformed(ActionEvent e) {
    String cmd = e.getActionCommand();
    if (cmd == "STOP") {
      System.out.println("STOP pressed");
      runButton.enable();
      pauseButton.disable();
      stepButton.disable();
      state = STOP;
      if (runner != null) {
        runner.interrupt();
        runner = null;
      }
    } else if (cmd == "RUN") {
      System.out.println("RUN pressed");
      pauseButton.enable();
      stepButton.disable();
      if (state == STOP) {
        if (runner == null) {
          runner = new Thread(this); // fire 'em up!
          runner.start();
          state = RUN;
      } else System.out.println("trying to start but non-null thread");
      } else if (state == PAUSE) {
        state = RUN;
        notifyAll();
      }
    } else if (cmd == "PAUSE") {
      System.out.println("PAUSE pressed");
      if (state == STOP) {
        stopButton.setSelected(true);
      } else {
        stepButton.enable();
        state = PAUSE;
      }
    } else if (cmd == "STEP") {
      System.out.println("STEP pressed");
      if (state == STOP) {
        stopButton.setSelected(true);
      } else {
        state = STEP;
        notifyAll();
      }
    }
  }

  public void run() {
    try {
      System.out.println("starting annealing run!");
      if (optT0Adaptive) myAnnealer.findT0(optAnimateMoves);
      else myAnnealer.setT0(optT0);
      myAnnealer.anneal(optAnimateMoves);
    } catch (InterruptedException e) {
      // do nothing except quit
    }
    System.out.println("annealing done");
    state = STOP;
    stopButton.setSelected(true);
    runner = null;
  }

  private static int ANIMATE_DELAY = 4000;

  void setAnnealDisplay(PTempHistory pt) {
    tempDisplay.setValue(pt.getTemperature());
    attemptsDisplay.setValue(pt.getAttemptCount());
    acceptedDisplay.setValue(pt.getAcceptCount());
    percentDisplay.setValue(pt.getAcceptPercent());
  }

  public synchronized void animateStep() throws InterruptedException {
    getParent().repaint();
    Thread.sleep(ANIMATE_DELAY / optSpeed);
    if (state == STEP) {
      state = PAUSE;
      pauseButton.setSelected(true);
    }
    while (state == PAUSE) wait();
  }

  public static void main(String [] args) {
    PLayout pl = new PLayout("ntest.in");
    JFrame jf = new JFrame("UIAnnealer Test");
    JPanel stuffPanel = new JPanel(new GridLayout(1,2));
    UILayout uil = new UILayout(pl);
    stuffPanel.add(uil);
    jf.setSize(600,300);
    PAnnealer pa = new PAnnealer(pl);
    UIAnnealer ua = new UIAnnealer(pa);
    stuffPanel.add(ua);
    jf.getContentPane().add(stuffPanel);
    pa.setUIAnnealer(ua);
    jf.setVisible(true);
    jf.addWindowListener( new WindowAdapter()
      {
	public void windowClosing(WindowEvent e) { System.exit(0); }
      } );
    uil.autoZoom();
  }

}
