/** \file
 *
 *  Contains the LuaNode class definition.
 *
 *  Copyright (c) 2007,2008,2009 MBARI
 *  MBARI Proprietary Information.  All Rights Reserved
 *
 */
#ifndef LUANODE_H_
#define LUANODE_H_

#include "LuaAPI.h"
#include "missionScript/ScriptNode.h"
#include "utils/FastMap.h"
#include "utils/FlexArray.h"

class DataReader;
class DataValue;
class DataWriter;

/**
 * Implements ScriptNode for the LuaAPI
 *
 *  \ingroup lua
 */
class LuaNode : public ScriptNode
{
public:

    /// Destructor
    virtual ~LuaNode();

    /// Returns true if the node contains child nodes
    virtual bool hasChildNodes() const;

    /// Returns the child node, by name, or NULL if none.
    virtual LuaNode* getNamedNode( const Str& nodeName );

    /// Returns a new child node than can contain other nodes
    virtual LuaNode* newChildNode( const Str& nodeName );

    /// Returns a new child node that is a function
    virtual LuaNode* newChildFunction( const Str& functionName,
                                       const Str& functionBody, Logger& logger );

    /// Returns the number of indexed (array, or list-like) nodes
    /// Returns 0 is this is not a table.
    virtual int getNodeCount( const Str& nodeName ) const;

    /// Returns the indexed (array, or list-like) node at the zero-based index, or NULL if none.
    virtual LuaNode* getIndexedNode( unsigned int index );

    /// Returns the parent node, or NULL if this is the root.
    virtual LuaNode* getParentNode() const;

    /// Returns the index of the node, -1 if named
    virtual int getIndex() const
    {
        return index_;
    }

    /// Returns the name of the node, undefined if indexed
    virtual const Str& getName() const
    {
        return name_;
    }

    /// Sets readTo to the value of the node, as a boolean
    /// Returns true if read success
    virtual bool readBool( bool& readTo ) const;

    /// Sets readTo to the value of the node, as a double
    /// Returns true if read success
    virtual bool readDouble( double& readTo ) const;

    /// Sets readTo to the value of the node, unsigned char string
    /// Returns true if read success
    virtual bool readString( Str& readTo ) const;

    /// If the node contains a dataValue, materialize such a dataValue
    /// Uses the Unit + value paradigm
    virtual DataValue* asNewDataValue();

    /// Attempt to execute the function contained in this node.
    virtual bool execute( FlexArray<DataReader*>& inputs, FlexArray<SettingReader*>& settings,
                          FlexArray<DataWriter*>& outputs, FlexArray<const Unit*>& outUnits, Logger& logger );

    /// Attempt to execute the function contained in this node, returning
    /// only a single boolean value.
    virtual bool execute( FlexArray<DataReader*>& inputs, FlexArray<SettingReader*>& settings,
                          bool& boolOutput, Logger& logger );

    /// Attempt to execute the function contained in this node, with no inputs and no return value
    virtual bool execute( Logger& logger );

    /// Returns a string representation of this node, with its ancestors,
    /// separated by "." characters.
    virtual Str toString() const;

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

    friend class LuaAPI;

    /// Private root node constructor, available to LuaAPI too
    LuaNode();

    /// Private "index" constructor, available to LuaAPI too
    LuaNode( LuaNode* parentNode, int index );

    /// Private "name" constructor, available to LuaAPI too
    LuaNode( LuaNode* parentNode, const Str& name );

    /// Open this node
    bool open() const;

    /// Close this node
    void close() const;

    /// True if this is the root element.
    inline bool isRoot() const
    {
        return parentNode_ == NULL;
    }
    /// Parent node
    LuaNode* parentNode_;

    /// The index of this node
    int index_;

    /// The name of this node
    Str name_;

    /// Map of named elements
    FastMap<const Str, LuaNode*>* childMap_;

    /// Array of numbered elements
    FlexArray<LuaNode*>* childList_;
};

#endif /* LUANODE_H_ */
