package fr.cemagref.observation.examples.race;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import fr.cemagref.observation.gui.Drawable;
import fr.cemagref.observation.gui.ObserversManagerHandler;
import fr.cemagref.observation.gui.ObserversManagerPanel;
import fr.cemagref.observation.kernel.ObservablesHandler;
import fr.cemagref.observation.kernel.ObservableManager;
import fr.cemagref.observation.kernel.ObserverListener;
import fr.cemagref.observation.observers.jfreechart.TemporalChart;
import fr.cemagref.observation.observers.jfreechart.TemporalMeanChart;
import fr.cemagref.observation.observers.jfreechart.TemporalSerieChart;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Pilot extends JFrame implements ObserversManagerHandler {
    
    private final ObservableManager observableManager;

    public Pilot() {
        super("Observation demo");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // JFreeChart mode
        observableManager = new ObservableManager();
        ObservablesHandler clObservable = observableManager.addObservable(Individual.class);
        TemporalChart chart1 = new TemporalMeanChart(clObservable.getObservableFetcher("remaining distance"));
        clObservable.addObserverListener(chart1);
        TemporalChart chart2 = new TemporalSerieChart(clObservable.getObservableFetcher("remaining distance"));
        //TemporalChart chart2 = new TemporalSerieChart();
        clObservable.addObserverListener(chart2);

        JPanel panel = new JPanel(new BorderLayout());
        JButton button = new JButton("Run");
        button.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                new Thread() {

                    public void run() {
                        runRace(observableManager);
                    }
                }.start();
            }
        });
        panel.add(button, BorderLayout.PAGE_START);
        panel.add(new ObserversManagerPanel(observableManager, this), BorderLayout.CENTER);
        setContentPane(panel);
        pack();
        setVisible(true);
    }

    /**
     * <code>main</code>
     *
     * @param args command line arguments : <ul><li><b>-b :</b> runs in batch mode</li></ul>
     */
    public static void main(String[] args) {
        boolean batch = false;
        // command line arguments parsing
        for (String arg : args) {
            if (arg.equals("-b")) {
                batch = true;
            }
        }
        // observers init
        if (batch) {
            // batch mode
            ObservableManager observableManager = new ObservableManager();
            //ObservableManager.addObservable(Individual.class).addObserverListener(new ConsoleObserver());
            observableManager.addObservable(Race.class).addObserverListener((ObserverListener) new XStream(new DomDriver()).fromXML(
                    "<fr.cemagref.observation.observers.XMLObserver>"
                    + "<sysout>false</sysout>"
                    + "<outputFile>/dev/null</outputFile>"
                    + "</fr.cemagref.observation.observers.XMLObserver>"));
            runRace(observableManager);
        } else {
            new Pilot();

        }
    }

    public static void runRace(ObservableManager observableManager) {
        observableManager.initObservers();
        // Model execution
        Race course = new Race(observableManager, 5, 20);
        while (!course.step()) {
            ;
        }
    }

    public JFrame getHandlingFrame() {
        return this;
    }

    public void showDrawable(Drawable drawable) {
        JFrame frame = new JFrame(drawable.getTitle());
        frame.setContentPane(drawable.getDisplay());
        frame.pack();
        frame.setVisible(true);
    }
}