// src/simulation_controller.hh - Copyright 2005, 2006, University
//               of Padova, dept. of Pure and Applied
//               Mathematics
//
// This file is part of SGPEMv2.
//
// This is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// SGPEMv2 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with SGPEMv2. If not, see http://www.gnu.org/licenses/.


#ifndef SIMULATION_CONTROLLER_HH
#define SIMULATION_CONTROLLER_HH 1

#include "sgpemv2/simulation_observer.hh"

#include <gtkmm/toolbutton.h>
#include <gtkmm/action.h>
#include <gtkmm/builder.h>

namespace sgpem
{

  class SimulationController;


  /** \brief Helper class for controlling the simulation via callback
   * from the GUI
   */
  class SimulationController : public SimulationObserver
  {
  public:
    SimulationController(Simulation& simulation, Glib::RefPtr<Gtk::Builder> main_window);
    virtual ~SimulationController();
    
    /** \brief Update sensitivities of toolbar buttons and menu items 
     * watching the state of the ::Simulation 
     */
    void update(const Simulation& simulation);
    
  private:

    /** \brief Called when the "Play" action is requested 
     *  
     * Modifies toolbar buttons and menu items sensitivities
     */
    void on_simulation_run();

    /** \brief Called when the "Pause" action is requested 
     *  
     * Modifies toolbar buttons and menu items sensitivities
     */
    void on_simulation_pause();

    /** \brief Called when the "Stop" action is requested 
     *  
     * Modifies toolbar buttons and menu items sensitivities
     */
    void on_simulation_stop();

    /** \brief Calls Simulation::run() and manage possibly raised exceptions
     *  
     * This function is called every Simulation::get_speed() milliseconds by
     * ::on_simulation_run(), and performs a single step of the simulation.
     * Manages all exceptions that could be raised by Simulation::run(), displaying
     * meaningful(?) error messages if shit happens.
     */
    bool run_simulation_adaptor();

    Simulation&      _sim;
    bool             _break_requested;

    Gtk::ToolButton* _toolbt_start;
    Gtk::ToolButton* _toolbt_pause;
    Gtk::ToolButton* _toolbt_stop;

    Glib::RefPtr<Gtk::Action>  _action_start;
    Glib::RefPtr<Gtk::Action>  _action_pause;
    Glib::RefPtr<Gtk::Action>  _action_stop;
  };

} //~ namespace sgpem

#endif //~ SIMULATION_CONTROLLER_HH

