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

#pragma once

#include "glmSDKAPI.h"

#include "glmAbstractDynamicsBehavior.h"
#include "glmRagdollEntityComponent_PhysX.h"

namespace glm
{
    class GLM_SDK_API PhysicalizeBehavior : public AbstractDynamicsBehavior
    {
    public:
        class PerEntityData
        {
        public:
            Time _targetBlendingDuration;
            Time _currentBlendingDuration;

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

            inline PerEntityData();
        };

        bool _physicalize;
        int _physicalizeMode; //PhysicsMode::Value
        bool _lockPostureOnStop;

        DriveParameters _orientationDriveParameters;
        DriveParameters _positionDriveParameters;
        float _entityMaxDistanceRatio;       //Only used when the pelvis is in PhysicsMode::POSITION_DRIVE
        Time _blendingWithAnimationDuration; //only used when switching from kinematic to anything else, or from anything to kinematic

        bool _useCollisionId;
        int _collisionId;

        bool _useKinematicTarget;
        bool _unphysicalizedChildrenFromAnimation;

    protected: //data
        glm::Array<PerEntityData> _physicalizeBehaviorPerEntityData;

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

        PhysicalizeBehavior();
        virtual ~PhysicalizeBehavior();

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

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

        virtual void doAllocate(BehaviorGraph& graph) override;
        virtual void doDeallocate() override;
        virtual void doResize(BehaviorGraph& graph) override;

        virtual void doStart(int64_t index, BehaviorGraph& graph) override;
        virtual void onRequestStop(int64_t index, BehaviorGraph& graph) override;
        virtual ResultStatus::Value doStop(int64_t index, BehaviorGraph& graph, Time dt) override;

        void setCollisionIdsInKB(int64_t index, BehaviorGraph& graph);
    };

    //-------------------------------------------------------------------------
    inline PhysicalizeBehavior::PerEntityData::PerEntityData()
    {
    }

    //-------------------------------------------------------------------------
    inline PhysicalizeBehavior* PhysicalizeBehavior::create() const
    {
        PhysicalizeBehavior* myNewPhysicalizeBehavior = GLM_NEW(PhysicalizeBehavior, myNewPhysicalizeBehavior, getClassMemoryStatId());
        return myNewPhysicalizeBehavior;
    }
} // namespace glm
