//////////////////////////////////////////////////////////////////////////////
//
// AVP_ServerEntity_InteractInvisiSwitch.h
//
// Created by CAH 25/02/2009
//
// Copyright (c) 2009 Rebellion. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////////
// INCLUDES

// CORE
#include "Core/Asura.h"

// PERSONAL
#include "Entity/PhysicalObject/Interact/InvisiSwitch/AVP_ServerEntity_InteractInvisiSwitch.h"

// ASURA
#include "Entity/Asura_StaticMessage_System.h"

// TOOLS
#ifdef ASURA_TOOLS
#include "EntityTemplate/Tools_EntityTemplate_System.h"
#endif

// AVP
#include "Entity/AVP_Entity_Classification.h"
#include "Entity/AVP_Messages.h"
#include "Entity/PhysicalObject/Actor/AVP_Actor_Messages.h"
#include "Entity/PhysicalObject/Actor/AVP_ServerEntity_Actor.h"
#include "Entity/PhysicalObject/Interact/InvisiSwitch/AVP_ClientEntity_InteractInvisiSwitch.h"
#include "Entity/PhysicalObject/Interact/InvisiSwitch/AVP_Messages_InteractInvisiSwitch.h"

#include "Entity/AVP_Entity_EventIDs.h"

//////////////////////////////////////////////////////////////////////////////
// STATIC AND GLOBAL DECLARATIONS

Asura_Hashed_List<AVP_ServerEntity_InteractInvisiSwitch> AVP_ServerEntity_InteractInvisiSwitch::s_xList;

static const u_int	g_uCurrentChunkVersion	 = 0;

//////////////////////////////////////////////////////////////////////////////
// CLASS FUNCTIONS
// AVP_ServerEntity_InteractInvisiSwitch

////////////////////////////////////////////////////////////////////////////////
// Function     : AVP_ServerEntity_InteractInvisiSwitch - Constructor
// Author       : Callum Hope CAH
// Date         : 25/02/09
// Scope		: Protected
////////////////////////////////////////////////////////////////////////////////

AVP_ServerEntity_InteractInvisiSwitch::AVP_ServerEntity_InteractInvisiSwitch( Asura_Guid uGuid ) 
: Asura_Entity_Server( uGuid )
, PARENT( uGuid )
{
	Classification = AVP_ENTITYCLASS_INTERACT_SENTRYGUN_INVISISWITCH;

	s_xList.AddToList(this);
}

////////////////////////////////////////////////////////////////////////////////
// Function     : AVP_ServerEntity_InteractInvisiSwitch - Destructor
// Author       : Callum Hope CAH
// Date         : 25/02/09
// Scope		: Protected
////////////////////////////////////////////////////////////////////////////////

AVP_ServerEntity_InteractInvisiSwitch::~AVP_ServerEntity_InteractInvisiSwitch()
{
	s_xList.RemoveFromList(this);
}

////////////////////////////////////////////////////////////////////////////////
// Function     : AVP_ServerEntity_InteractInvisiSwitch::ReadFromChunkStream
// Author       : Callum Hope CAH
// Date         : 25/02/09
// Scope		: Virtual Public
//
// Desc			: Standard read from chunk stream to load files function. 
////////////////////////////////////////////////////////////////////////////////

void AVP_ServerEntity_InteractInvisiSwitch::ReadFromChunkStream( Asura_Chunk_Stream& xStream )
{
	int iCurrentChunkVersion;

	xStream >> iCurrentChunkVersion;

	PARENT::ReadFromChunkStream( xStream );

	switch ( iCurrentChunkVersion )
	{
		//////////////////////////////////////
		case g_uCurrentChunkVersion :
		//////////////////////////////////////
		{
			break;
		}
		//////////////////////////////////////
		default :
		//////////////////////////////////////
		{
			Asura_Assertf( false, ( "Unknown chunk version (%d) in AVP_ServerEntity_InteractInvisiSwitch", iCurrentChunkVersion ) );
			break;
		}
	}
}

////////////////////////////////////////////////////////////////////////////////
// Function     : AVP_ServerEntity_InteractInvisiSwitch::WriteToChunkStream
// Author       : Callum Hope CAH
// Date         : 25/02/09
// Scope		: Virtual Public
//
// Desc			: Standard write to chunk stream to save files function
////////////////////////////////////////////////////////////////////////////////

void AVP_ServerEntity_InteractInvisiSwitch::WriteToChunkStream( Asura_Chunk_Stream& xStream ) const
{
	xStream << g_uCurrentChunkVersion;

	PARENT::WriteToChunkStream( xStream );
}

////////////////////////////////////////////////////////////////////////////////
// Function     : AVP_ServerEntity_InteractInvisiSwitch::MakeCreateMessage
// Author       : Callum Hope CAH
// Date         : 25/02/09
// Scope		: Virtual Public
//
// Desc			: Makes a create messge for the client entity AVP_ClientEntity_InteractInvisiSwitch and sends it. 
////////////////////////////////////////////////////////////////////////////////

void AVP_ServerEntity_InteractInvisiSwitch::MakeCreateMessage( Asura_Guid uRequestingClient, bool bSendGuaranteed /*= false*/ )
{
	Asura_Message* pxMessage = Asura_Network::CreateMessage(ASURA_MSG_CLIENTCREATE, sizeof( AVP_Message_InteractInvisiSwitch_ClientCreate ), GetClassification() );
	if( pxMessage )
	{
		AVP_Message_InteractInvisiSwitch_ClientCreate* pxData = static_cast<AVP_Message_InteractInvisiSwitch_ClientCreate*>( pxMessage->GetData() );
		pxData->FillInteractionObject(this);

		pxMessage->SetToGuid( ASURA_GUID_MY_CLIENT_ENTITIES );
		pxMessage->SetFromGuid( GetGuid() );
		if (bSendGuaranteed)
		{
			pxMessage->UseGuaranteedDelivery();
		}
		Asura_Network::SendToSpecificMachine( pxMessage, uRequestingClient );
	}
}

////////////////////////////////////////////////////////////////////////////////
// Function     : AVP_ServerEntity_InteractInvisiSwitch::HandleMessage
// Author       : Callum Hope CAH
// Date         : 25/02/09
// Scope		: Virtual Public
//
// Desc			: Handles all messages sent to "this"
////////////////////////////////////////////////////////////////////////////////

bool AVP_ServerEntity_InteractInvisiSwitch::HandleMessage( const Asura_Message* pxMsg )
{
	switch ( pxMsg->GetMsgID() )
	{
		//////////////////////////////////////
		case AVP_MSGID_REQUEST_INTERACTION:
		//////////////////////////////////////
		{
			const AVP_Message_Actor_RequestInteraction*	pxData = static_cast<const AVP_Message_Actor_RequestInteraction*>( pxMsg->GetData() );
			if ( pxData )
			{
				Asura_Assert( pxData->GetInteractionType() == AVP_INTERACTION_TYPE_DEFAULT, "AVP_ServerEntity_InteractInvisiSwitch::HandleMessage\n Interaction objects only handle default interactions" );
				
				if( pxData->GetInteractionMoveType() ==  AVP_Message_Actor_RequestInteraction::INTERACTION_INTIATED )
				{
					AVP_ServerEntity_Actor* pxActor = AVP_ServerEntity_Actor::FindEntity( pxData->GetActorGuid() );
					
					if( pxActor )
					{
						switch( pxActor->GetClassification() )
						{
							//////////////////////////////////////
							case ( AVP_ENTITYCLASS_MARINE ):
							//////////////////////////////////////
							{
								if ( m_bOn )
								{
									OnTurnOff();
								}
								else
								{
									OnTurnOn();
								}

								SendMessagesForEvent( AVP_ENTITY_EVENT_MARINE_INTERACT );
								break;
							}
							//////////////////////////////////////
							case ( AVP_ENTITYCLASS_PREDATOR ):
							//////////////////////////////////////
							{
								// By calling this we are essentially just using the animations system set in place for interactable object.
								OnTurnOff();

								SendMessagesForEvent( AVP_ENTITY_EVENT_PREDATOR_INTERACT );
								break;
							}
							//////////////////////////////////////
							case ( AVP_ENTITYCLASS_ALIEN ):
							//////////////////////////////////////
							{
								// By calling this we are essentially just using the animations system set in place for interactable object. 
								OnTurnOff();

								SendMessagesForEvent( AVP_ENTITY_EVENT_ALIEN_INTERACT );
								break;
							}
						}
						Asura_Network::Forward( pxMsg, ASURA_GUID_MY_CLIENT_ENTITIES, GetGuid() );
						return true;
					}
				}
			}
			else
			{
				Asura_Assert( false, "AVP_ServerEntity_InteractInvisiSwitch::HandleMessage\n A message has been passed with no data" );
				return false;
			}
			return false;
		}
		//////////////////////////////////////
		case ASURA_MSG_SWITCHOFF:
		//////////////////////////////////////
		{
			// handle this here as its used by the sentry gun templates. 
			// no need to go to parent as all that does is send an interaction message with no 'From' GUID. So its handled above and does nothing. 
			if( m_bOn )
			{
				OnTurnOff();
			}
			return true;
		}
		//////////////////////////////////////
		case ASURA_MSG_SWITCHON:
		//////////////////////////////////////
		{
			// handle this here as its used by the sentry gun templates. 
			// no need to go to parent as all that does is send an interaction message with no 'From' GUID. So its handled above and does nothing. 
			if( ! m_bOn )
			{
				OnTurnOn();
			}
			return true;
		}
		//////////////////////////////////////
		case AVP_MSGID_SENTRYGUN_SWITCH_PLAYANIMATION:
		//////////////////////////////////////
		{
			Asura_Network::Forward( pxMsg, ASURA_GUID_MY_CLIENT_ENTITIES, GetGuid() );
			return true;
		}
		//////////////////////////////////////
		default:
		//////////////////////////////////////
		{
			return PARENT::HandleMessage(pxMsg);
		}
	}
}

////////////////////////////////////////////////////////////////////////////////
// Function     : AVP_ServerEntity_InteractInvisiSwitch::PostLoadInitialise
// Author       : Callum Hope CAH
// Date         : 26/02/09
// Scope		: Virtual Public
//
// Desc			: Implementation of virtual inherited function. 
////////////////////////////////////////////////////////////////////////////////

void AVP_ServerEntity_InteractInvisiSwitch::PostLoadInitialise()
{
	PARENT::PostLoadInitialise();
}

////////////////////////////////////////////////////////////////////////////////
// Function     : AVP_ServerEntity_InteractInvisiSwitch::CreateFromTools
// Author       : Callum Hope CAH
// Date         : 26/02/09
// Scope		: Static Public ( if ASURA_TOOLS )
//
// Desc			: Creates a server entity from the toosl interface
////////////////////////////////////////////////////////////////////////////////

#ifdef ASURA_TOOLS
void AVP_ServerEntity_InteractInvisiSwitch::CreateFromTools(Asura_Guid uGuid)
{
	new AVP_ServerEntity_InteractInvisiSwitch( uGuid );
}
#endif // ASURA_TOOLS

////////////////////////////////////////////////////////////////////////////////
// Function     : AVP_ServerEntity_InteractInvisiSwitch::CanBeIncludedInTemplate
// Author       : Callum Hope CAH
// Date         : 26/02/09
// Scope		: Virtual Public ( if ASURA_TOOLS )
//
// Desc			: Simple Return function, here so that "Entity/AVP_Entity_Classification.h" doesnt have to be in the header. 
////////////////////////////////////////////////////////////////////////////////

#ifdef ASURA_TOOLS
bool AVP_ServerEntity_InteractInvisiSwitch::CanBeIncludedInTemplate() const
{
	return ( GetClassification() == AVP_ENTITYCLASS_INTERACT_SENTRYGUN_INVISISWITCH );
}
#endif // ASURA_TOOLS

////////////////////////////////////////////////////////////////////////////////
// Function     : AVP_ServerEntity_InteractInvisiSwitch::ApplyChangesForTemplateInstance
// Author       : Callum Hope CAH
// Date         : 26/02/09
// Scope		: Virtual Public ( if ASURA_TOOLS )
//
// Desc			: Tools interface function to change the data stored in the server entity when needed. 
////////////////////////////////////////////////////////////////////////////////

#ifdef ASURA_TOOLS
void AVP_ServerEntity_InteractInvisiSwitch::ApplyChangesForTemplateInstance( Tools_EntityTemplateInstance* pxInstance )
{
	PARENT::ApplyChangesForTemplateInstance( pxInstance );
}
#endif // ASURA_TOOLS

