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

#pragma once

#include "glmSDKAPI.h"

#include "glmAbstractUserBehavior.h"
#include "glmCollisionFilter.h"
#include "glmPhysX.h"

#include "glmMutex.h"

namespace glm
{
    class RagdollEntityComponent_PhysX;

    class GLM_SDK_API CharacterControllerBehavior : public AbstractUserBehavior
    {
        friend class RagdollEntityComponent_PhysX;

    public:
        short _shapeType;
        glm::Vector3 _size;
        float _radius;
        float _height;
        bool _scaleShape;
        glm::Vector3 _positionOffset;

        float _restitution;
        float _staticFriction;
        float _dynamicFriction;

        float _density;
        float _stepOffset;
        float _contactOffset;
        short _climbingMode;
        float _slopeLimit;
        float _invisibleWallHeight;
        float _maxJumpHeight;
        float _scaleCoeff;
        float _volumeGrowth;

        bool _recoverOverlap;
        bool _preciseSweep;

        bool _ccCollide;

    private:
        glm::SpinLock _initMutex;

        physx::PxControllerDesc* _descriptor;
        physx::PxMaterial* _material;
        CollisionFilter* _collisionFilter;

    public:
        CharacterControllerBehavior();
        virtual ~CharacterControllerBehavior();

        void setCollisionFilter(const CollisionFilter& collisionFilter);

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

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

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

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