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

#pragma once

#include "glmSDKAPI.h"
#include "glmTrafficEntityComponent.h"
#include <glmIContext.h>
#include <glmSimulation.h>
#include <glmSimuEntityHandle.h>
#include <glmTrafficWorld.h>
#include <glmSet.h>

namespace glm
{
	class GLVisualizationTrafficInterface;

	//-------------------------------------------------------------------------
	class GLM_SDK_API TrafficContext : public IContext
	{
		friend class TrafficEntityComponent;
		friend class GLVisualizationTrafficInterface;

	public:

		GLM_CLASS_STAT_ID( glm::MemoryStatIds::Simulation);

		TrafficContext();

		virtual ~TrafficContext();

		TrafficEntityComponent& getEntityComponent(int typeIndex, int64_t entityIndex);
		TrafficEntityComponent& getEntityComponent(SimuEntityHandle handle);

		static ContextType::Value getStaticContextType() { return IContext::ContextType::TRAFFIC; }

		void setTrafficWorld(TrafficWorld* trafficWorld) { _trafficWorld = trafficWorld; }
		TrafficWorld* getTrafficWorld() { return _trafficWorld; }

	private:

		void registerVehicleOnLane(TrafficEntityComponent& entityComponent, glm::PODArray<int>& roadsToRegister, TrafficElement& trafficElement);
		void updateTrafficElementDistanceToVehicle(TrafficEntityComponent& entityComponent);

		void updateCarsOnRoads(int entityTypeIndex, int64_t entityIndex);

		virtual void doInit() override;
		virtual void doUpdate(Time) override;
		virtual void doUpdateSubset(Time, int updateOrder) override;
		virtual void doFinish() override;
		virtual void setContextType() override;

		virtual bool registeredOnCreateEntityType() override { return true; }
		virtual void onCreateEntityType(int64_t maxCount) override;

		virtual bool registeredOnCreateEntityComponent() override { return true; }
		virtual void onCreateEntityComponent(int entityTypeIndex, int64_t entityIndex) override;

		virtual bool registeredOnInitEntityComponent() override { return true; }
		virtual void onInitEntityComponent(int entityTypeIndex, int64_t entityIndex) override;

		virtual bool registeredOnUpdateEntityComponent() override { return true; }
		virtual void onUpdateEntityComponent(Time dt, int entityTypeIndex, int64_t entityIndex) override;

		virtual bool registeredOnDestroyEntityComponent() override { return true; }
		virtual void onDestroyEntityComponent(int entityTypeIndex, int64_t entityIndex) override;

		GLM_DISALLOW_COPY_AND_ASSIGN(TrafficContext);

		glm::ComponentsArray<TrafficEntityComponent> _components;

		TrafficWorld* _trafficWorld;
	};
	
	//-------------------------------------------------------------------------
	inline TrafficEntityComponent& TrafficContext::getEntityComponent(int typeIndex, int64_t entityIndex)
	{
		return _components.getComponent(typeIndex, entityIndex);
	}

	//-------------------------------------------------------------------------
	inline TrafficEntityComponent& TrafficContext::getEntityComponent(SimuEntityHandle handle)
	{
		return _components.getComponent(handle._typeIndex, handle._index);
	}
}
