/** \file
 *
 *  Contains the DefineBehavior and DefinedBehavior class definitions.
 *
 *  Copyright (c) 2007,2008,2009 MBARI
 *  MBARI Proprietary Information.  All Rights Reserved
 */

#ifndef DEFINEBEHAVIOR_H_
#define DEFINEBEHAVIOR_H_

#include "component/Behavior.h"

class DefinedBehavior;
class Method;
class MethodInfo;
class MissionNode;
class Module;
class ScriptAPI;

/**
 *  Information to create a Setting in a DefinedBehavior.
 *
 *  \ingroup missionScript
 */
class SettingInfo
{
public:
    SettingInfo( const Str& name, const Str& uriPart, DataValue* defaultValue )
        : name_( name ),
          uriPart_( uriPart ),
          defaultValue_( defaultValue )
    {}

    virtual ~SettingInfo()
    {
        if( NULL != defaultValue_ )
        {
            delete defaultValue_;
        }
    }

    const Str& getName()
    {
        return name_;
    }
    const Str& getUriPart()
    {
        return uriPart_;
    }
    DataValue* getDataValue()
    {
        return defaultValue_;
    }

protected:
    const Str name_;
    const Str uriPart_;
    DataValue* defaultValue_;

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



/**
 *  Information to create a DefinedBehavior that is embedded in scripted code within a mission file.
 *
 *  \ingroup missionScript
 */
class DefineBehavior
{
public:
    static DefineBehavior* Instance( MissionNode* node, const Str& itemName, Logger& logger );

    virtual ~DefineBehavior();

    FlexArray<SettingInfo*>& getSettings()
    {
        return settings_;
    }


protected:

    friend class DefinedBehavior;

    /// Protected constructor
    DefineBehavior( const Str& name, ScriptAPI* scriptAPI );

    Str name_;

    ScriptAPI* scriptAPI_;

    FlexArray<SettingInfo*> settings_;

    /// construct method -- called once, with no settings;
    MethodInfo* constructMethod_;

    /// initialize method;
    MethodInfo* initializeMethod_;

    /// run method;
    MethodInfo* runMethod_;

    /// initialize method;
    MethodInfo* uninitializeMethod_;

    /// satisfied method;
    MethodInfo* isSatisfiedMethod_;

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


/**
 *  Behavior that is embedded in scripted code within a mission file.
 *
 *  \ingroup missionScript
 */
class DefinedBehavior: public Behavior
{
public:
    DefinedBehavior( const Str& prefix, DefineBehavior* definition );

    virtual ~DefinedBehavior();

    virtual void initialize();

    virtual void run();

    virtual void uninitialize();

    virtual bool isSatisfied();

    FlexArray<SettingReader*>& getSettings()
    {
        return settings_;
    }

    DefineBehavior* getDefine()
    {
        return define_;
    }

protected:

    DefineBehavior* define_;

    FlexArray<SettingReader*> settings_;

    /// construct method -- called once, with no settings;
    Method* constructMethod_;

    /// initialize method;
    Method* initializeMethod_;

    /// run method;
    Method* runMethod_;

    /// initialize method;
    Method* uninitializeMethod_;

    /// satisfied method;
    Method* isSatisfiedMethod_;

    /// true if the construtMethod_ has been run
    bool constructMethodRun_;

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

#endif /* DEFINEBEHAVIOR_H_ */
