/*************************************************************************
Crytek Source File.
Copyright (C), Crytek Studios, 2001-2005.
-------------------------------------------------------------------------
$Id$
$DateTime$
Description: Implements a standard wheel based vehicle movements

-------------------------------------------------------------------------
History:
- 04:04:2005: Created by Mathieu Pinard

*************************************************************************/
#ifndef __VEHICLEMOVEMENTSTDWHEELED_H__
#define __VEHICLEMOVEMENTSTDWHEELED_H__


#include "Network/NetActionSync.h"
#include "AIMovementCommon.h"
#include "IVehicleSystem.h"
#include "VehicleMovementBase.h"

class CVehiclePartSubPartWheel;


class CVehicleMovementStdWheeled;
class CNetworkMovementStdWheeled
{
public:
	CNetworkMovementStdWheeled();
	CNetworkMovementStdWheeled(CVehicleMovementStdWheeled *pMovement);

	typedef CVehicleMovementStdWheeled * UpdateObjectSink;

	bool operator == (const CNetworkMovementStdWheeled &rhs)
	{
		//return (abs(m_steer-rhs.m_steer)<0.001f) && (abs(m_pedal-rhs.m_pedal)<0.001f) && (m_brake==rhs.m_brake);
		return false;
	};

	bool operator != (const CNetworkMovementStdWheeled &rhs)
	{
		return !this->operator==(rhs);
	};

	void UpdateObject( CVehicleMovementStdWheeled *pMovement );
	void Serialize(TSerialize ser, unsigned aspects);

	static const uint8 CONTROLLED_ASPECT = eEA_GameClientDynamic;

private:
	float m_steer;
	float m_pedal;
	bool	m_brake;
};


class CVehicleMovementStdWheeled
	: public CVehicleMovementBase
{
	friend class CNetworkMovementStdWheeled;
public:
	CVehicleMovementStdWheeled();
	~CVehicleMovementStdWheeled();

	// IVehicleMovement
	virtual bool Init(IVehicle* pVehicle, const SmartScriptTable &table);
	virtual void Reset();
	virtual void Release();
  virtual void PostInit();
	virtual void Physicalize();
    
	virtual void StopEngine();
	virtual void OnEvent(EVehicleMovementEvent event, float value);

	virtual void ProcessMovement(const float deltaTime);
	virtual void Update(const float deltaTime);
  virtual void UpdateSuspension();
  virtual void UpdateSounds(const float deltaTime);

	virtual bool RequestMovement(CMovementRequest& movementRequest);
	virtual void GetMovementState(SMovementState& movementState);

	virtual void Serialize(TSerialize ser, unsigned aspects) {
		if ((ser.GetSerializationTarget() == eST_Network) &&(aspects & eEA_GameClientDynamic))
			m_netActionSync.Serialize(ser, aspects);
	};
	virtual void SetAuthority( bool auth )
	{
		m_netActionSync.CancelReceived();
	};
	// ~IVehicleMovement

protected:
  virtual void InitEnvParticles(){}
  virtual void InitWheeledParticles();
  virtual void LastMinuteInits();
  
  virtual void UpdateEnvParticles(const float deltaTime);
  virtual void UpdateGameTokens(const float deltaTime);
  
protected:

	pe_action_drive m_action;

	float m_engineMaxRPM, m_engineIdleRPM, m_engineShiftDownRPM;
  		 
	float m_steerMax;             // max steering angle in deg
	float m_steerSpeedMin;        // steer speed at v=0
  float m_steerSpeed;           // steer speed at vMaxSteerMax	
	float m_v0SteerMax;           // max steering angle in deg at v=0
  float m_kvSteerMax;           // reduces steer max at vMaxSteerMax
	float m_steerSpeedScaleMin;   // scale for sens at zero vel
  float m_steerSpeedScale;      // scale for sens at vMaxSteerMax
	
	float m_steerRelaxation;      // relaxation speed to center in degrees
  float m_vMaxSteerMax;         // speed at which entire kvSteerMax is substracted from v0SteerMax		
  float m_pedalLimitMax;        // at vMaxSteerMax pedal is clamped to 1-pedalLimitMax

	float m_damageLevel;
	float m_damageMul;

	pe_status_vehicle m_vehicleStatus;	
  float m_rpmTarget;
  float m_rpmRelaxSpeed, m_rpmInterpSpeed;	
  
  int m_currentGear;
	bool m_isBreakingOnIdle;

  float m_suspDampingMin, m_suspDampingMax;
  float m_suspDamping, m_speedSuspUpdated;
  
	// Network related
	CNetActionSync<CNetworkMovementStdWheeled> m_netActionSync;

  pe_params_wheel* m_wheelParams;
  std::vector<CVehiclePartSubPartWheel*> m_wheelParts;


	//------------------------------------------------------------------------------
	// AI related
	// PID controller for speed control.	
	float	m_direction;
	SPID	m_dirPID;
	float	m_steering;
  float m_prevAngle;
  CTimeValue m_lastSteerUpdateTime;

	SmartScriptTable m_wheeledTable;
};


#endif
