/** \file
 *
 *  Contains the MissionManager class definition.
 *
 *  Copyright (c) 2007,2008,2009 MBARI
 *  MBARI Proprietary Information.  All Rights Reserved
 */

#ifndef MissionManager_H_
#define MissionManager_H_

#include "component/SyncComponent.h"
#include "utils/Mutex.h"

class MissionItem;
class MissionNode;
class UniversalDataWriter;

/** \ingroup missionScript
 *
 *  MissionManager is the computation cycle component that contains the main
 *  mission stack and manages its execution.
 *
 */
class MissionManager : public SyncMissionComponent
{
public:

    /// Private constructor for use only by Aggregate
    MissionManager();

    /// Destructor
    virtual ~MissionManager();

    /// Loads a mission from a file
    MissionItem* loadFromFile( const char* filename );

    /// Loads a mission from a file
    bool runLoadedMission( bool quitAtEnd = false );

    /// Resumes the contained mission stack.
    /// Calls initialize on the mission stack if needed.
    bool resumeLoadedMission();

    /// Runs the contained mission stack.
    /// Calls initialize on the mission stack if needed.
    void run();

    /// Reads the configuration settings.
    void initialize();

    /// Uninitialize the mission stacks.
    void uninitialize();

    /// Display the currently running stack to Syslog
    void logStack();

    /// Returns true if a mission is running
    bool isMissionRunning()
    {
        return startupMissionItem_ == NULL
               && loadedMissionItem_ != NULL && okToRun_;
    }

    /// Returns the currently running mission, or NULL if none (or in startup)
    MissionItem* getRunningMission()
    {
        return isMissionRunning() ? loadedMissionItem_ : NULL;
    }

    /// Returns the filename name of the most recent loaded mission
    const Str& getLoadedMissionFilename()
    {
        return loadedMissionFilename_;
    }

    /// Load a mission node from a file
    static MissionNode* LoadRootNode( const char* filename, bool insert, Logger& logger );

    /// Finds a mission node within a root node
    static MissionNode* FindTopNode( MissionNode* rootNode, Logger& logger );

    /// Logs the mission to the syslog
    static void LogMission( const char *filename, Logger& logger );

    static MissionManager* GetInstance();

protected:

    /// Loads a mission from a file
    MissionItem* missionFromFile( const char* filename );

    MissionItem* loadedMissionItem_;
    Str loadedMissionFilename_;
    bool okToRun_;
    bool quitAtEnd_;
    MissionItem* startupMissionItem_;
    MissionItem* defaultMissionItem_;
    Mutex stackModMutex_;

private:

    // Note that the copy constructor below is private and not given a body.
    // Any attempt to call it will return a compiler error.
    MissionManager( const MissionManager& old ); // disallow copy constructor

    DataReader* sBITRunningReader_;
    DataReader* iBITRunningReader_;

    UniversalDataWriter* missionStartedWriter_;

    /// Uninitialize a mission stack.
    void uninitializeMission( MissionItem* missionItem );

    static MissionManager* Instance_;

};

#endif /*MissionManager_H_*/
