
///////////////////////////////////////////////////////////////////////////////
//
// File   : AVP_Alien_JumpHandler.h
// Author : Andy Tate
// Date   : 4-Sep-2007
//
// Copyright (C) 2007 Rebellion, All Rights Reserved.
//
///////////////////////////////////////////////////////////////////////////////

#ifdef ASURA_USE_PRAGMA_ONCE
	#pragma once
#endif   // ifdef ASURA_USE_PRAGMA_ONCE

#ifndef __AVP_ALIEN_JUMPHANDLER_H__
#define __AVP_ALIEN_JUMPHANDLER_H__

////////////////////////////////////////////////////////////////////////////////
// Include files...
////////////////////////////////////////////////////////////////////////////////

#include "Actor/Vertebrates/AVP_Vertebrate_JumpHandler.h"

#include "Attractors/Asura_Attractor_Data.h"
#include "Core/Asura_Maths.h"


////////////////////////////////////////////////////////////////////////////////
// Forward class declarations...
////////////////////////////////////////////////////////////////////////////////

class Asura_Attractor_Compiled;

class AVP_ClientActor_Alien;
class AVP_ClientActor_Vertebrate;


////////////////////////////////////////////////////////////////////////////////
// Class declaration...
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Class        : AVP_Alien_JumpHandler
// Author       : Andy Tate
// Date         : 4-Sep-2007
//
// Description  : Class to handle interactions for Aliens.
////////////////////////////////////////////////////////////////////////////////

class AVP_Alien_JumpHandler : public AVP_Vertebrate_JumpHandler
{
public:
	// Public enumerated types...
	enum AlienJumpType
	{
		JT_NORMAL,

		JT_UNDEFINED,

		JT_JUMP_CONCAVE_90_FLOOR_TO_WALL,
		JT_JUMP_CONCAVE_90_WALL_TO_FLOOR,
		JT_JUMP_CONCAVE_90_CEILING_TO_WALL,
		JT_JUMP_CONCAVE_90_WALL_TO_CEILING,
		JT_JUMP_CONCAVE_90_WALL_TO_WALL,

		JT_JUMP_180_FLOOR_TO_CEILING,
		JT_JUMP_180_CEILING_TO_FLOOR,
		JT_JUMP_180_WALL_TO_WALL,

		JT_JUMP_ALONG_SURFACE,

		JT_DROP,

		JT_ENTER_VENT,
		JT_DUCT_SURFACE_SWITCH,

		NUM_ALIEN_JT
	};

	// Public functions...
	AVP_Alien_JumpHandler(AVP_ClientActor_Vertebrate& xOwner);
//	virtual ~AVP_Alien_JumpHandler();

	// Virtual manipulation functions...
	virtual void	Update(void);
	virtual void	Render(void) const;

	virtual bool	HandleJump(const float fJumpValue);

	// Accessor functions...
	AlienJumpType	GetJumpType(void) const					{ return static_cast< AlienJumpType >( m_uJumpType ); }

	const Asura_Vector_3&	GetJumpDestinationNormal(void) const	{ return(m_xJumpDestinationNormal); }
	const Asura_Vector_3&	GetJumpDestinationPosition(void) const	{ return(m_xJumpDestinationPosition); }

	static Asura_Hash_ID SendJumpMoveStartMessage( const Asura_Guid uOwnerGuid, const u_int uJumpType, const Asura_Vector_3& xTargetPosition, const Asura_Vector_3& xTargetNormal );
	static Asura_Hash_ID SendVentMoveStartMessage( const Asura_Guid uOwnerGuid,
												   const Asura_Vector_3& xBeginPosition, const Asura_Matrix_3x3& xBeginOri,
												   const Asura_Vector_3& xFinalPosition, const Asura_Matrix_3x3& xFinalOri,
												   Asura_Hash_ID uBeginAnimHash, Asura_Hash_ID uFinalAnimHash );
	static Asura_Hash_ID SendVentMoveStartMessage( const Asura_Guid uOwnerGuid,
												   const Asura_Vector_3& xBeginPosition, const Asura_Matrix_3x3& xBeginOri,
												   const Asura_Vector_3& xFinalPosition, const Asura_Matrix_3x3& xFinalOri );

	static void CalculateTargetOrientation(const AlienJumpType eType, const AVP_ClientActor_Vertebrate& xVert, const Asura_Vector_3& xTargetNormal, Asura_AMatrix3x3& xTargetOrientation);

	static void CreateConsoleVars();

protected:
	// Protected variables...
	Asura_Vector_3	m_xJumpDestinationNormal;	// The normal at the destination position over which a jump takes place.
	Asura_Vector_3	m_xJumpDestinationPosition;	// The destination position over which a jump takes place.

	Asura_Guid		m_uJumpTargetGuid;			// The GUID of the jump-target.
	float			m_fJumpDestinationDistance;	// The distance to the jump-destination.

	// Protected functions...
	AlienJumpType	CalculateJumpType(const Asura_Vector_3& xStartNormal, const Asura_Vector_3& xEndNormal) const;

	bool		CheckForJumpType(void);

private:
	static void TestDuctAttractors_Callback(void* pData, const Asura_Attractor_Compiled* const pxAttractor);

	// Private typedefs...
	typedef AVP_Vertebrate_JumpHandler PARENT;

	// Private variables...
	float				m_fMaxLOSRange;								// The maximum range for LOS tests.

#if !defined(ASURA_NO_DEBUG_OUTPUT)
	u_int				m_uJumpDestinationFaceIndex;				// The index of face of the destination triangle.

	static const u_int	s_auJumpTypeDebugColours[NUM_ALIEN_JT];	// Array of colours used for debugging surface-interactions.
#endif	// !defined(ASURA_NO_DEBUG_OUTPUT)

	struct DuctAttractorCallbackData
	{
		const Asura_Vector_3& m_xCurrentAttractorNormal;
		const Asura_Vector_3& m_xCurrentPosition;
		u_int m_uNewAttractor;
		Asura_Vector_3 m_xPosOnNewAttractor;
		Asura_Vector_3 m_xNewAttractorNormal;

		DuctAttractorCallbackData(const Asura_Vector_3& xCurrentAttractorNormal, const Asura_Vector_3& xCurrentPosition)
			: m_xCurrentAttractorNormal(xCurrentAttractorNormal)
			, m_xCurrentPosition(xCurrentPosition)
			, m_uNewAttractor(uASURA_ATTRACTOR_ID_NONE)
			, m_xPosOnNewAttractor(Asura_Maths::ZeroVector3)
			, m_xNewAttractorNormal(0.0f, 1.0f, 0.0f)
		{
		}
	};

	// Private functions...
	AVP_Alien_JumpHandler(void);
	AVP_Alien_JumpHandler(const AVP_Alien_JumpHandler& xOther);

	AVP_Alien_JumpHandler&	operator=(const AVP_Alien_JumpHandler& xOther);
};   // End of class 'AVP_Alien_JumpHandler'.


#endif   // ifndef __AVP_ALIEN_JUMPHANDLER_H__


/// End of file. ///
