/*
	Lan Wars.
	Copyright (c) 2009, Darragh Coy.
	All rights reserved.
	Original work(s), source code & author(s) details available at: http://www.darraghcoy.com

	Redistribution and use in source and binary forms, with or without modification, are permitted 
	provided that the following conditions are met:

		* 	Redistributions of source code must retain the above copyright notice, this list of 
			conditions and the following disclaimer.
		* 	Redistributions in binary form must reproduce the above copyright notice, this list of 
			conditions and the following disclaimer in the documentation.
		* 	Neither the name of the author nor the names of contributors may be used to endorse or 
			promote products derived from this software without specific prior written permission.
		* 	The use of any third party libraries, modules or data files provided with the source 
			form of the program must follow and respect the individual licensing terms of these 
			components. You do not have permission to modify or circumvent the licensing terms for 
			provided third party components unless the third party licenses specifically allow this. 
			If you do not agree to the terms of provided third party components then you do not have 
			permission to use them in your derived work(s).
		* 	The terms of this license do not apply to separate (but related) distributions if supplied 
			by the author(s), only to the contents of this source distribution, derived works, and the 
			binaries produced by either modified or unmodified versions of the source code. The terms 
			of this license do not also apply to any third party libraries or components provided with 
			the source distribution. Such third party elements are licensed under their own separate 
			agreements.

	THIS SOFTWARE IS PROVIDED BY DARRAGH COY ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 
	BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
	ARE DISCLAIMED. IN NO EVENT SHALL DARRAGH COY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
	EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
	OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
	OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
	IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef GAME_ENEMY_H
#define GAME_ENEMY_H

//=====================================================================================================================
//=====================================================================================================================

#include "GameObjects\GameCharacter.h"

//=====================================================================================================================
//=====================================================================================================================

namespace Game
{
	//=================================================================================================================
	//=================================================================================================================

	class AIController;
	class GamePlayer;

	//=================================================================================================================
	/// @brief		This class represents all humanly controlled players of the game.
	//=================================================================================================================

	class GameEnemy : public GameCharacter
	{
		public:
		
			//=========================================================================================================
			// Constants
			//=========================================================================================================
			
				/// Width of the enemy's bounding ellipse
				
				static const float COLLISION_WIDTH;
				
				/// Half height of the enemy's bounding ellipse
				
				static const float COLLISION_HEIGHT;			
				
				/// Maximum health for an enemy
				
				static const float MAX_HEALTH;
				
				/// Starting health at spawn
				
				static const float START_HEALTH;
				
				/// Movement speed of the enemy 
				
				static const float MOVE_SPEED;

				/// Amount of friction to apply to built up force if on the ground
				
				static const float FORCE_FRICTION;
				
				/// Time the enemy takes to die fully
				
				static const float DEATH_TIME;
				
			//=========================================================================================================
			// Functions
			//=========================================================================================================
			
				/// Constructor. Creates the game enemy.
				
				GameEnemy
				(
					const Vec3f &	position								, 
					float			y_rot									, 
					unsigned		net_id = NetObject::NET_ID_INVALID 
				);

				/// Destructor.

				~GameEnemy();
				
				//=====================================================================================================
				/// @brief		Tells the object to announce it's type name: this is the type name without the 
				///				Game:: namespace
				/// @returns	The type name of the object.
				//=====================================================================================================
				
				virtual const char * GetTypeName() const { return "GameEnemy"; }
				
				/// Update function. called once for every frame. 
				
				virtual void OnUpdate( float time_delta );

				/// Network send function. Called on each net object by the GameSession object as required. 
				
				virtual bool NetSend( GamePacket & packet , SendContext context );
				
				/// Network receive function. Called on each net object by the GameSession object as required. 
				
				virtual bool NetReceive( GamePacket & packet , ReceiveContext context );

				/// Draws the character
				
				virtual void OnDraw( Camera3D * c );

				/// Returns the amount of health the enemy has
				
				inline float GetHealth() const { return m_health; }
				
				/// Sets the amount of health the enemy has
				
				void SetHealth( float health );
				
				/// Called when the enemy is removed from the game
				
				virtual void OnGameRemoved();

				/// Server only: Alerts the AI of noise from the given player

				void NoiseAlert( GamePlayer * player );

				/// Server only: Alerts the AI of damage from the given player

				void DamageAlert( GamePlayer * player );

		private:
		
			//=========================================================================================================
			// Constants
			//=========================================================================================================
				
				/// Base running animation speed
				
				static const float RUNNING_ANIM_SPEED;
				
				/// Speed that the death animation plays at
				
				static const float DEATH_ANIM_SPEED;
		
			//=========================================================================================================
			// Functions
			//=========================================================================================================

				/// Does network sending for an object on the server to the client, where the client has no control over the object

				void NetSendRemote( GamePacket & packet );
				
				/// Does network sending for an object on the server to the client, where the client controls this object
				
				void NetSendServer( GamePacket & packet );
				
				/// Does network receiving for a remotely controlled object on the client.
				
				bool NetReceiveRemote( GamePacket & packet );
				
				/// Does an update on the client for this object that is controlled remotely
				
				void UpdateRemote( float time_delta );
				
				/// Does an update on the server for this object
				
				void UpdateServer( float time_delta );
				
				/// Animates the enemy's sprite:
				
				void Animate( float time_delta );
		
			//=========================================================================================================
			// Variables
			//=========================================================================================================						
				
				/// Health of the enemy
				
				float m_health;

				/// For remotely controlled objects on the client: true if we were previously in scope
				
				bool m_in_scope_previously;
				
				/// Time left in death state: used on server for respawns, on client for death animation
				
				float m_death_time_left;
				
				/// Previous position of the enemy: used on the server only for animation 
				
				Vec3f m_previous_pos;
				
				/// True if the enemy was previously dead: used on the server for animation
				
				bool m_previously_dead;

				/// Server only: controller for the AI
				
				AIController * m_ai_controller;
	};
};

#endif 
