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

#ifndef MISSIONSTATELOGGER_H_
#define MISSIONSTATELOGGER_H_

#include "data/ElementURI.h"
#include "io/MappedIOStream.h"
#include "logger/Logger.h"
#include "utils/FastMap.h"
#include "utils/FlexArray.h"
#include "utils/Str.h"

#include <dirent.h>

#ifndef __APPLE_CC__
#define DIRENT_CONST const
#else
#define DIRENT_CONST
#endif

class MissionItem;

/**
 *  Serializes and unserializes mission state to allow missions to be resumed.
 *
 *  \ingroup logging
 */
class MissionStateLogger
{
public:

    static void SetActive( const CodedStr& name, MissionItem* active );

    static void SetActive( const CodedStr& name, unsigned short activeCode );

    static void SetRepeatIndex( const CodedStr& name, int repeatIndex );

    static Str* GetActive( const CodedStr& aggregateName, int& repeatIndex );

    static void ShowMissionState( Logger& logger );

    static void LogArgWrite( const ElementURI& uri, DataValue* dataValue );

    static void ClearStates();

    static void NewResume( Str loadedMissionFilename, Logger& logger );

    static void NewRun( Str loadedMissionFilename );

private:
    /// Private Constructor for singleton
    MissionStateLogger( );

    struct StateInfo
    {
    public:
        StateInfo()
            : nameCode_(),
              repeat_( 0 ),
              pos_( ( unsigned int ) - 1 )
        {}
        unsigned short nameCode_;
        int repeat_;
        size_t pos_;
    };

    class StreamEntry
    {
    public:
        StreamEntry()
            : pos_( ( unsigned int ) - 1 )
        {}
        ~StreamEntry()
        {}
        size_t pos_;
        union
        {
            int intValue_;
            float floatValue_;
        };
    };

    static MappedIOStream* CurrentStream_;

    /// Makes sure that CurrentStream_ is deleted on shutdown
    class StaticDestructor
    {
    public:
        ~StaticDestructor();
    };

    /// Static instance of StaticDestructor
    static MissionStateLogger::StaticDestructor StaticDestructor_;

    static FlexArray<MissionStateLogger::StreamEntry*> StreamEntries_;

    static int StreamSize_;

    static FlexArray<MissionStateLogger::StateInfo*> States_;

    static Str FilterArg_;

    /// Helper function for Supervisor::GetLatestLogFilename()
    static int Filter( DIRENT_CONST struct dirent* dirEntry );

    static void ConfigureFilterArg( Str loadedMissionFilename );
};

#endif /*MISSIONSTATELOGGER_H_*/
