import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class FibEvent extends JFrame {
    private JTextField numField, seqField, statusField;
    private JButton start, stop;
    private FibThread ft;
    private FibUpdater updater;
    private ButtonHandler buttons;
    
    public FibEvent() {
        setTitle("Fibonacci");
        setSize(1000, 100);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        Container pane = getContentPane();
        pane.setLayout(new FlowLayout());
        
        numField = new JTextField(10);
        pane.add(numField);
        
        buttons = new ButtonHandler();
        
        start = new JButton("Compute Fibonacci");
        start.addActionListener(buttons);
        pane.add(start);
        
        stop = new JButton("Stop");
        stop.addActionListener(buttons);
        pane.add(stop);
        
        statusField = new JTextField(10);
        pane.add(statusField);
        
        seqField = new JTextField(80);
        pane.add(seqField);
        
        ft = null;
        updater = new FibUpdater();
    }
    
    private class ButtonHandler implements ActionListener {        
        public void actionPerformed(ActionEvent e) {
            if (e.getSource() == start && ft == null) {
                ft = new FibThread(Integer.parseInt(numField.getText()));
                ft.addFibListener(updater);
                ft.start();
                statusField.setText("running...");
            } else if (e.getSource() == stop && ft != null) {
                ft.endComputation();
            }
        }
    }
    
    private class FibUpdater implements FibListener {
        public void nextFibTerm(int term) {
            String current = seqField.getText();
            seqField.setText(term + " " + current);
        }
        
        public void finished() {
            statusField.setText("done");
            ft = null;
        }
    }
    
    public static void main(String[] args) {
        FibEvent f = new FibEvent();
        f.setVisible(true);
    }
}
