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

#pragma once

#include "glmAbstractBehavior.h"

namespace glm
{
    class BehaviorGraph;
    class ContainerBehaviorOperator;

    class GLM_SDK_API AbstractParentBehavior : public AbstractBehavior
    {
    public:
        static const unsigned int _childInvalidId;

    private:
        glm::Array<AbstractBehavior*> _children;

        friend class AbstractGraphicalParentBehaviorNode;

    public:
        GLM_ABSTRACTCLASS_STAT_ID( glm::MemoryStatIds::Simulation)

        virtual ~AbstractParentBehavior();

        // Hierarchy
        inline const glm::Array<AbstractBehavior*>& getChildren() const;
        virtual unsigned int addChild(AbstractBehavior* child);
        virtual void removeChild(unsigned int child);
        virtual bool hasChildLooping(const AbstractBehavior* child) const = 0;

        // Allocation and default processing
        virtual void allocate(BehaviorGraph& graph) override;
        virtual void deallocate() override;
        virtual void resize(BehaviorGraph& graph) override;
        virtual void init(BehaviorGraph& graph) override;
        virtual void finish(BehaviorGraph& graph) override;
        virtual void init(int64_t index, BehaviorGraph& graph) override;
        virtual void finish(int64_t index, BehaviorGraph& graph) override;

        // type checking
        virtual bool isThisType(const AbstractBehavior* value) const override;

    protected:
        AbstractParentBehavior();
        // cloning
        friend class CloneFactory;
        virtual void cloneImpl(AbstractBehavior* clone, CloneFactory* factory) const override;
        virtual AbstractParentBehavior* create() const override = 0;

    private:
        void deleteChildren();
    };

    //-------------------------------------------------------------------------
    const glm::Array<AbstractBehavior*>& AbstractParentBehavior::getChildren() const
    {
        return _children;
    }
} // namespace glm
