// Change History:
// 01/09/04 AV Development: Call Stop from destructor to fix bug #57
// 01/08/04 AV Development: Write [MISC] section in macro file on stop
// 01/08/04 AV Development: Add AddProcess func to fix bug #55

// DART Macro Def
#ifndef DDP_MacroDef_H
#define DDP_MacroDef_H

#include "ddp/ddp_port.h"
#include "base/at_types.h"

#include <string>
#include <vector>

class DDP_MacroDef
{
public:
    enum StatusParams { MS_NONE, MS_RECORDING, MS_RUNNING };
private:
    std::string FileName;
    StatusParams Status;

    struct ProcessDef
    {
        ProcessDef() : Count(0) {}
        ProcessDef(const byte * n) : Name(n ? (char *)n : ""), Count(0) {}
        std::string Name;
        uint Count;
    };
    std::vector<ProcessDef> Processes;

    const ProcessDef * find_proc(const byte * n) const;
    ProcessDef * add_proc(const byte * n) { Processes.push_back(ProcessDef(n));
        return &Processes.back(); }
    void write_misc();
    const byte * GetSectionName() const { return (const byte *)"MISC"; }
    
public:
    DDP_MacroDef() : Status(MS_NONE) {}
    // copy
    DDP_MacroDef(const DDP_MacroDef & rhs) :
        FileName(rhs.FileName), Status(rhs.Status) {}
    ~DDP_MacroDef() { Stop(); }
    
    // interface:
    bool Record(const byte * fn)
        { if(!fn) return false;
        Status = MS_RECORDING; FileName = (char *)fn; return true; }
    void Stop();
    bool Run(const byte * fn) { if(!fn) return false;
        Status = MS_RUNNING; FileName = (char *)fn; return true; }

    // copy
    DDP_MacroDef & operator = (const DDP_MacroDef & rhs)
        { FileName = rhs.FileName; Status = rhs.Status; return *this; }
    // compare
    bool operator == (const DDP_MacroDef & rhs)
        { return (Status == rhs.Status) && (FileName == rhs.FileName); }
    // properties:
    StatusParams GetStatus() const { return Status; }
    const byte * GetFileName() const { return (const byte *)FileName.c_str(); }

    uint AddProcess(const byte * process) { if(Status == MS_NONE) return 0;
        ProcessDef * info = (ProcessDef *)find_proc(process);
        if(info) return ++info->Count;
        info = add_proc(process); return info ? ++info->Count : 0; }
};

#endif // DDP_MacroDef_H
 