package at.oefai.aaa.gui;

import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.AbstractButton;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;

import at.oefai.aaa.IState;

/**
 * The ControlerPanel contains elements for controlling the action, start-stop-load.
 * @author Stefan Rank
 */
public class ControlerPanel extends JPanel {
    private static final long STEP_INTERVAL_TIME = 1000; //ms
    private static final String START_TEXT = "Start";
    private static final String STEP_TEXT = "Step 1sec";
    private static final String PAUSE_TEXT = "Pause";
    private static final String SAVE_TEXT = "Save Snapshot (not yet working)";
    private static final String RESTORE_TEXT = "Load Snapshot";
    private static final String RESET_TEXT = "Reset";
    private static final String EXIT_TEXT = "Exit";
    private static final String TOGGLE_COMMAND = "Toggle";
    /** @todo icons for each button */
    private IState mediator = null;

    // use actions to enable command keys:
    private Action restoreAction = new AbstractAction(RESTORE_TEXT) {
        public void actionPerformed(final ActionEvent e) {
            ControlerPanel.this.mediator.load(null);
        }
    };

    private Action resetAction = new AbstractAction(RESET_TEXT) {
        public void actionPerformed(final ActionEvent e) {
            ControlerPanel.this.mediator.reset();
        }
    };

    private Action saveAction = new AbstractAction(SAVE_TEXT) {
        public void actionPerformed(final ActionEvent e) {
            ControlerPanel.this.mediator.save(null);
        }
    };

    private Action startAction = new AbstractAction(START_TEXT) {
        public void actionPerformed(final ActionEvent e) {
            ControlerPanel.this.mediator.start();
        }
    };

    private Action pauseAction = new AbstractAction(PAUSE_TEXT) {
        public void actionPerformed(final ActionEvent e) {
            ControlerPanel.this.mediator.pause();
        }
    };

    private Action stepAction = new AbstractAction(STEP_TEXT) {
        public void actionPerformed(final ActionEvent e) {
            ControlerPanel.this.mediator.start(); // and after some pause
            try {
                Thread.sleep(STEP_INTERVAL_TIME); // one second
            } catch (InterruptedException ex) { // so what
            }
            ControlerPanel.this.mediator.pause();
        }
    };

    private Action exitAction = new AbstractAction(EXIT_TEXT) {
        public void actionPerformed(final ActionEvent e) {
            ControlerPanel.this.mediator.exit();
        }
    };

    private AbstractButton toggleButton   = new JButton(this.startAction);

    public ControlerPanel(final IState pMediator) {
        this.mediator = pMediator;
        this.add(new JLabel("[S]..start/pause    "));
        this.add(this.toggleButton);
        this.add(new JButton(this.saveAction));
        this.add(new JButton(this.restoreAction));
        this.add(new JButton(this.resetAction));
        this.add(new JLabel("    [Escape]..exit"));
        this.setEmpty();
        // now register KeyBindings
        this.getActionMap().put(EXIT_TEXT, this.exitAction);
        this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
                EXIT_TEXT); // for fast exiting from the app
        this.getActionMap().put(STEP_TEXT, this.stepAction);
        this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_T, 0),
                STEP_TEXT); // for stepping in about one second intervals
        this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0),
                TOGGLE_COMMAND); // for toggling running/paused
    }

    private void setEmpty() {
        this.startAction.setEnabled(false);
        this.pauseAction.setEnabled(false);
        this.stepAction.setEnabled(false);
        this.saveAction.setEnabled(false);
        this.restoreAction.setEnabled(true);
        this.resetAction.setEnabled(false);
        changeToggleAction(this.startAction);
    }

    public final void setPaused() {
        this.startAction.setEnabled(true);
        this.pauseAction.setEnabled(true);
        this.stepAction.setEnabled(true);
        this.saveAction.setEnabled(true);
        this.restoreAction.setEnabled(true);
        this.resetAction.setEnabled(true);
        changeToggleAction(this.startAction);
    }

    public final void setRunning() {
        this.startAction.setEnabled(true);
        this.pauseAction.setEnabled(true);
        this.stepAction.setEnabled(false);
        this.saveAction.setEnabled(false);
        this.restoreAction.setEnabled(false);
        this.resetAction.setEnabled(false);
        changeToggleAction(this.pauseAction);
    }

    private void changeToggleAction(final Action a) {
        this.toggleButton.setAction(a);
        this.getActionMap().put(TOGGLE_COMMAND, a);
        this.toggleButton.requestFocusInWindow();
    }

}

