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

#pragma once

#include "glmSDKAPI.h"
#include "glmPODArray.h"
#include "glmVector3.h"
#include "glmDeque.h"

namespace glm
{
	class TrafficWorld;

	//-------------------------------------------------------------------------
	// class to determine an exact position in traffic : road index, side, lane, abscissa
	class GLM_SDK_API PositionInRoadData
	{
	public:
		PositionInRoadData();

		Vector3 getPositionOnLane(const TrafficWorld& trafficWorld) const;
		Vector3 getDirectionOnLane(const TrafficWorld& trafficWorld) const;

		Vector3 getPositionOnLane(const TrafficWorld& trafficWorld, float abscissa) const;
		Vector3 getDirectionOnLane(const TrafficWorld& trafficWorld, float abscissa) const;

		Vector3 getPositionOnLaneWithSwitch(const TrafficWorld& trafficWorld);

		Vector3 getLaneStart(const TrafficWorld& trafficWorld) const;
		Vector3 getLaneEnd(const TrafficWorld& trafficWorld) const;

		// those methods runs on specific lanes to advance, instead of road center, distance goes positive in laneDirection
		float addDistanceOnLane(const TrafficWorld& trafficWorld, float abscissa, float distance);

		// this returns the distance on the specific lane instead of road center, in lane direction
		float getDistanceToAbscissaOnLane(const TrafficWorld& trafficWorld, float otherRoadCenterAbscissa) const;
		float driveOnLane(const TrafficWorld& trafficWorld, float distanceOnLane) const;

		float getDistanceBeforeCrossingOnLane(const TrafficWorld& trafficWorld) const;
		float getDistanceFromPreviousCrossingOnLane(const TrafficWorld& trafficWorld) const;

		bool isForward() const;
		bool isBackward() const;

		int32_t _roadIndex;
		int _laneDirection;       // 0 = forward, 1 = backward
		int _laneIndexFromCenter; // 0 = innermost lane
		float _roadCenterAbscissa;      // if no active crossing only, 0 to length

		// runtime helpers:
		int32_t _nextCrossing; // avoids recomputing if we are backward or forward before finding the right next crossing
		float _nextTurnAngle;
		float _startCrossingAbscissa;
		float _endCrossingAbscissa;
		glm::PODArray<int> _possibleLanes; // when we have a target, can use thoses _laneIndexFromCenter values to reach the correct lane

		bool _forbidSwitch;
		float _requestedLaneChangeCurrentOffset; // default to 0, initialized to -1 or 1 when changing of lane, float offset added on _laneIndexFromCenter
		float _laneChangeCurrentOffset; // default to 0, initialized to -1 or 1 when changing of lane, float offset added on _laneIndexFromCenter
		
		float _currentRightNoise; // multiplied by roadCenter right vector to get absolute noise value

		bool _turningLeft;
		bool _turningRight;
	};
}
