// handles turning actions into CMovementRequests and setting player state
// for the local player

#ifndef __G4PLAYERINPUT_H__
#define __G4PLAYERINPUT_H__

#pragma once

#include "IActionMapManager.h"
#include "IPlayerInput.h"

class CPlayerG4;
struct SPlayerStats;

class CPlayerInputG4 : public IPlayerInput, public IActionListener
{
public:
	// Allow OnAction handlers to be bound to action names at the same location as the binding of the names to input keys.
	friend class CGameG4;

	CPlayerInputG4( CPlayerG4 * pPlayer );
	~CPlayerInputG4();

	// IActionListener
	virtual void OnAction( const ActionId& action, int activationMode, float value );
	// ~IActionListener

	// IPlayerInput
	virtual void PreUpdate();
	virtual void Update();
	virtual void PostUpdate();

	virtual void SetState( const SSerializedPlayerInput& input );
	virtual void GetState( SSerializedPlayerInput& input );

	virtual void Reset();
	// ~IPlayerInput

	bool IsClient();

protected:
	// OnAction handlers
	// typedef bool (CPlayerG4::*TPlayerActionMap_OnAction)(const char *actionName, int activationMode, float value);
	bool OnActionMoveStickLR(const char *actionName, int activationMode, float value);
	bool OnActionMoveLeft(const char *actionName, int activationMode, float value);
	bool OnActionMoveRight(const char *actionName, int activationMode, float value);
	bool OnActionMoveUDShared(const char *actionName, int activationMode, float value);
	bool OnActionMoveStickUD(const char *actionName, int activationMode, float value);
	bool OnActionMoveUp(const char *actionName, int activationMode, float value);
	bool OnActionMoveDown(const char *actionName, int activationMode, float value);
	bool OnActionNavStickLR(const char *actionName, int activationMode, float value);
	bool OnActionNavStickUD(const char *actionName, int activationMode, float value);
	bool OnActionNavMouseLR(const char *actionName, int activationMode, float value);
	bool OnActionNavMouseUD(const char *actionName, int activationMode, float value);
	//bool OnActionRotateYaw(const char *actionName, int activationMode, float value);
	//bool OnActionRotatePitch(const char *actionName, int activationMode, float value);
	bool OnActionAttack1(const char *actionName, int activationMode, float value);
	bool OnActionUseOn(const char *actionName, int activationMode, float value);
	bool OnActionUseOff(const char *actionName, int activationMode, float value);
	bool OnActionUse(const char *actionName, int activationMode, float value);
	bool OnActionDev(const char *actionName, int activationMode, float value);
	// Normally called by a handler that needs to change the name of its action before calling script.
	bool OnActionCallScript(const char *actionName, int activationMode, float value);
	// Controller connection/disconnection.
	bool OnActionCtrlConnect(const char *actionName, int activationMode, float value);

	bool OnActionTweak(const char *actionName, int activationMode, float value);

	void SetNewActionName(const char *psName) { m_psNewActionName=psName; }
	const char *GetNewActionName(const char *psCurrentName) { return m_psNewActionName ? m_psNewActionName : psCurrentName; }

private:
	CPlayerG4 * m_pPlayer;
	SPlayerStats * m_pStats;
	const char *m_psNewActionName;	// for dynamic renaming of actions.

	uint32 m_actions;
	Vec3 m_deltaMovement;
	Vec3 m_xi_deltaMovement;
	Ang3 m_deltaRotation;
	Ang3 m_xi_deltaRotation;
	int m_moveKeysPressed;
	float m_deltaPitch;
	float m_deltaPitchOnce;
	bool m_bEnableTweakMap;

	Vec3 m_filteredDeltaMovement;

	EStance FigureOutStance();
	void AdjustMoveKeysPressed( int activationMode );

	void ApplyMovement(Vec3 delta);
	const Vec3 &FilterMovement(const Vec3 &desired);

	// Normalise stick input and apply a sensitivity curve
	float AdjustStickInputHorz(float value);
	// Normalise stick input and apply a sensitivity curve
	float AdjustStickInputVert(float value);

	float WrapAngle180(float yaw);

	void HolsterItem(bool bHolster);
};

#endif // ifndef __G4PLAYERINPUT_H__
