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

#pragma once

#include "glmSDKAPI.h"

//golaem core includes
#include "glmAbstractTargetProvider.h"
#include <glmAbstractUserBehavior.h>
#include <glmTrafficEntityComponent.h>

namespace glm
{
    class TrafficContext;

    // Traffic behavior, provides a traffic pipeline to an entity.
    class GLM_SDK_API TrafficGotoBehavior : public AbstractUserBehavior
    {
    public:
        class GLM_SDK_API TrafficGotoBehaviorData
        {
        public:
            Vector3 _targetPosition;
            int _uTurnMode;
            bool _alreadySearchedForAPath;

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

            TrafficGotoBehaviorData();
            ~TrafficGotoBehaviorData();
        };

    private:
        TrafficContext* _trafficContext;
        AbstractTargetProvider::SP _targetProvider;
        TrafficEntityComponent::GotoMode::Value _gotoMode;

        glm::Array<TrafficGotoBehaviorData> _trafficBehaviorData;
        float _targetReachedTreshold;
        bool _stopOnTargetReached;

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

        TrafficGotoBehavior();
        virtual ~TrafficGotoBehavior();

        void setTargetReachedTreshold(float treshold);
        void setStopOnTargetReached(bool stopOnTargetReached);

        //void setTargetPosition(int64_t index, const Vector3& targetPosition);
        void setTargetProvider(AbstractTargetProvider* targetProvider); // master version
        AbstractTargetProvider* getTargetProvider() const;

        void setUTurnMode(int64_t index, int uTurnMode);

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

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

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

    private:
        //void clearTrafficData(int64_t index, BehaviorGraph& graph);
    };

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