/***************************************************************************
*                                                                          *
*  Copyright (C) Golaem S.A.  All Rights Reserved.                         *
*                                                                          *
***************************************************************************/

#pragma once

#include "glmAbstractParentBehavior.h"
#include "glmSmartPointer.h"

namespace glm
{
    class GLM_SDK_API ContainerBehaviorOperator : public AbstractParentBehavior
    {
    private:
        glm::PODArray<AbstractBehavior*> _childRunning;
        glm::Array<glm::PODArray<const AbstractBehavior*>> _childrenRun;

        static const unsigned int _initialChildId = 0;
        static const unsigned int _finalChildId = 1;

    public:
        GLM_CLASS_STAT_ID( glm::MemoryStatIds::Simulation)

        ContainerBehaviorOperator();
        virtual ~ContainerBehaviorOperator();

        inline AbstractBehavior* getRunningChild(int64_t index) const;
        inline AbstractBehavior* getInitialChild() const;
        inline AbstractBehavior* getFinalChild() const;

        virtual bool hasChildLooping(const AbstractBehavior* child) const override;

        inline const glm::PODArray<const AbstractBehavior*>& getRunChildren(int64_t index) const;

        virtual void allocate(BehaviorGraph& graph) override;
        virtual void deallocate() override;
        virtual void resize(BehaviorGraph& graph) override;
        virtual void init(BehaviorGraph& graph) override;
        virtual void init(int64_t index, BehaviorGraph& graph) override;
        virtual void finish(int64_t index, BehaviorGraph& graph) override;
        virtual void update(int64_t index, BehaviorGraph& graph, Time dt) override;
        virtual void requestStart(int64_t index, BehaviorGraph& graph) override;
        virtual void requestStop(int64_t index, BehaviorGraph& graph, unsigned int next = _nextInvalidId) override;

        // type checking - value derived from this type
        virtual bool isThisType(const AbstractBehavior* value) const override;

    protected:
        // cloning
        friend class CloneFactory;
        inline virtual ContainerBehaviorOperator* create() const override;
    };

    //-------------------------------------------------------------------------
    inline AbstractBehavior* ContainerBehaviorOperator::getRunningChild(int64_t index) const
    {
        return _childRunning[index];
    }

    //-------------------------------------------------------------------------
    inline AbstractBehavior* ContainerBehaviorOperator::getInitialChild() const
    {
        return getChildren()[_initialChildId];
    }

    //-------------------------------------------------------------------------
    inline AbstractBehavior* ContainerBehaviorOperator::getFinalChild() const
    {
        return getChildren()[_finalChildId];
    }

    //-------------------------------------------------------------------------
    inline const glm::PODArray<const AbstractBehavior*>& ContainerBehaviorOperator::getRunChildren(int64_t index) const
    {
        return _childrenRun[index];
    }

    //-------------------------------------------------------------------------
    inline ContainerBehaviorOperator* ContainerBehaviorOperator::create() const
    {
        ContainerBehaviorOperator* myNewContainerBehaviorOperator = GLM_NEW(ContainerBehaviorOperator, myNewContainerBehaviorOperator, getClassMemoryStatId());
        return myNewContainerBehaviorOperator;
    }

} // namespace glm
