//==========================================================================
//  AIDA Detector description implementation 
//--------------------------------------------------------------------------
// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
// All rights reserved.
//
// For the licensing terms see $DD4hepINSTALL/LICENSE.
// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
//
// Author     : M.Frank
//
//==========================================================================
#ifndef DDG4_GEANT4UIMANAGER_H
#define DDG4_GEANT4UIMANAGER_H

// Framework include files
#include <DDG4/Geant4Call.h>
#include <DDG4/Geant4Action.h>

/// Forward declarations
class G4VisManager;
class G4UImanager;
class G4UIExecutive;


/// Namespace for the AIDA detector description toolkit
namespace dd4hep {

  /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit
  namespace sim {

    /// Standard UI interface implementation with configuration using property options
    /** The {\tt{Geant4UIManager}} is a component attached to the {\tt{Geant4Kernel}} object.
     *
     *  All properties of all {\tt{Geant4Action}} instances may be exported to
     *  Geant4 messengers and {\em{may}} hence be accessible directly from the Geant4
     *  prompt. To export properties from any action, call the {\tt{enableUI()}}
     *  method of the action.
     *
     *  Please note: 
     *
     *  Any type of commands may be put together, but the overall execution order
     *  is as follows:
     *  1. Execution of the visualization setup (Property: SetupVIS)
     *  2. Execution of the user interface setup (Property: SetupUI)
     *  3. Execution of the macro file list (Property: Macros)
     *  4. Execution of the command list (Property: Commands)
     *
     *
     * \author  M.Frank
     * \version 1.0
     */
    class Geant4UIManager : public Geant4Action, virtual public Geant4Call   {
    protected:
      /// Name of the default session type (="cmd")
      std::string m_sessionType;
      /// Property: Name of the UI macro file
      std::string m_uiSetup;
      /// Property: Name of the visualization macro file
      std::string m_visSetup;
      /// Property: List of commands to be executed when the Geant4Kernel gets configured
      std::vector<std::string> m_configureCommands;
      /// Property: List of commands to be executed when the Geant4Kernel gets initialized
      std::vector<std::string> m_initializeCommands;
      /// Property: List of commands to be executed when the Geant4Kernel gets terminated
      std::vector<std::string> m_terminateCommands;
      /// Property: List of commands to be executed BEFORE running
      std::vector<std::string> m_preRunCommands;
      /// Property: List of commands to be executed AFTER running
      std::vector<std::string> m_postRunCommands;
      /// Property: Array of commands to be chained
      std::vector<std::string> m_macros;
      /// Property: New prompt if the user wants to change it. (Default is do nothing)
      std::string m_prompt;
      /// Property: Flag to instantiate Vis manager (default=false, unless m_visSetup set)
      bool        m_haveVis;
      /// Property: Flag to instantiate UI (default=true)
      bool        m_haveUI;
      /// Reference to Geant4 visualtion manager
      G4VisManager* m_vis;
      /// Reference to Geant4 UI manager
      G4UIExecutive*  m_ui;

    public:
      /// Initializing constructor
      Geant4UIManager(Geant4Context* context, const std::string& name);
      /// Default destructor
      virtual ~Geant4UIManager();

      /// Configure the object. Callback registered to the Geant4Kernel.
      void configure();
      /// Initialize the object. Callback registered to the Geant4Kernel.
      void initialize();
      /// Callback on terminate. Callback registered to the Geant4Kernel.
      void terminate();

      /// Install command control messenger to write GDML file from command prompt.
      void installCommandMessenger();
      /// Start visualization
      G4VisManager* startVis();
      /// Start UI
      G4UIExecutive* startUI();
      /// Start manager & session
      void start();
      /// Stop and release resources
      void stop();
      /// Force exiting this process without calling atexit handlers
      void forceExit();
      /// Regularly exiting this process without calling atexit handlers
      void regularExit();
      /// Apply single command
      void applyCommand(const std::string& command);
      /// Run UI
      virtual void operator()(void* param);
    };

  }    // End namespace sim
}      // End namespace dd4hep
#endif // DDG4_GEANT4UIMANAGER_H
