//////////////////////////////////////////////////////////////////////////////
//
// AVP_ClientActor_Vehicle.cpp
//
// Copyright (c) 2007 Rebellion. All rights reserved.
//
//////////////////////////////////////////////////////////////////////////////

// I N C L U D E S ///////////////////////////////////////////////////////////

#include "Core/Asura.h"

// This file's header.
#include "Entity/PhysicalObject/Actor/Vehicles/AVP_ClientActor_Vehicle.h"

// Engine independent.
#include "Animation/Asura_Animation.h"
#include "Animation/Asura_AnimationAttachment.h"
#include "Core/Asura_Timers.h"
#include "Entity/Asura_PosAndOriInterpolator.h"
#include "Entity/Ragdoll/Asura_ClientEntity_Ragdoll.h"
#include "Interface/Asura_CommandConsole.h"
#include "Network/Asura_Message.h"
#include "Network/Asura_Network.h"
#include "Network/Asura_Player.h"
#include "Physics/Asura_Physics.h"
#include "Rendering/Asura_Render.h"
#include "Shapes/Asura_Shapes.h"
#include "SpecialFX/PFX/Asura_PFX_System.h"
#include "SpecialFX/PFX/Asura_PFX_Entity_Effect.h"
#include "Core/AVP_Game_Core.h"

// Project independent.
#include "Actor/AVP_Actor_AnimationHandler.h"
#include "Actor/AVP_Actor_CameraHandler.h"
#include "Actor/AVP_Actor_HUDHandler.h"
#include "Actor/AVP_Actor_InputHandler.h"

#include "Actor/Vertebrates/Human/AVP_Human_Description.h"
#include "Animation/AVP_AnimFlags.h"
#include "Core/AVP_Settings.h"
#include "Entity/Triggers/AVP_ClientEntity_InteractionTrigger.h"
#include "Entity/AVP_Entity_Classification.h"
#include "Entity/AVP_Messages.h"
#include "Entity/PhysicalObject/Actor/AVP_Actor_Messages.h"
#include "Inventory/AVP_Inventory_System.h"
#include "Moves/AVP_Movement_System.h"
#include "Moves/AVP_Moves.h"


// C L A S S   I M P L E M E N T A T I O N S /////////////////////////////////

Asura_Hashed_List<AVP_ClientActor_Vehicle> AVP_ClientActor_Vehicle::s_xList;

AVP_ClientActor_Vehicle::AVP_ClientActor_Vehicle(const u_short usFlagsToIgnore)
: PARENT(usFlagsToIgnore)
{
	Classification = AVP_ENTITYCLASS_VEHICLE;

	s_xList.AddToList( this );
}

AVP_ClientActor_Vehicle::~AVP_ClientActor_Vehicle( void ) 
{
	s_xList.RemoveFromList(this);
}

bool AVP_ClientActor_Vehicle::HandleMessage( const Asura_Message* pxMessage )
{
	switch ( pxMessage->GetMsgID() )
    {
        case ASURA_MSG_CLIENTUPDATE:
        {
            const AVP_Message_Actor_ClientUpdate* pxData = static_cast< const AVP_Message_Actor_ClientUpdate* >( pxMessage->GetData() );

            // If we are inactive and now receiving a client update this means we are becoming active.
            // We should go visible and teleport to this first pos/ori so we don't zip across the level.
            if(!IsEntityActive())
			{
                Asura_Matrix_3x3 xOrientMatrix;
                pxData->m_xOrientation.ToMatrix( xOrientMatrix );
                TeleportTo( pxData->m_xPosition, xOrientMatrix );
            }

            ProcessClientUpdate( pxData, pxMessage->GetSentTime() );
            return true;
        }

        case ASURA_MSG_AXON_GS2_ANIM_SEQUENCE_DATA:
        {
            const Axon_Gamescene_AnimSequenceData* pxData = static_cast< const Axon_Gamescene_AnimSequenceData* >( pxMessage->GetData() );
            if ( m_pxAnimationHandler ) { m_pxAnimationHandler->HandleGamesceneAnimSequenceData( *pxData ); }
            return true;
        }

        case AVP_MSGID_REQUEST_ANIMATION:
        {
            const AVP_Message_Actor_RequestAnimation* pxData = static_cast< const AVP_Message_Actor_RequestAnimation* >( pxMessage->GetData() );
            if ( m_pxAnimationHandler ) { m_pxAnimationHandler->HandleAnimationRequest( *pxData ); }
            return true;
        }

        default:
        {
            return PARENT::HandleMessage( pxMessage );
        }
    }
}

void AVP_ClientActor_Vehicle::ProcessClientUpdate(const AVP_Message_Actor_ClientUpdate* pxData, float fServerTime, bool bProcessPosAndOri /*= true*/)
{
#ifndef ASURA_NO_NETWORK_LAG_COMPENSATION
	const bool bAllowPosAndOrientationProcessing = bProcessPosAndOri && (m_pxPosAndOriInterpolator != NULL);
#else // #ifndef ASURA_NO_NETWORK_LAG_COMPENSATION
	const bool bAllowPosAndOrientationProcessing = bProcessPosAndOri;
#endif // #ifndef ASURA_NO_NETWORK_LAG_COMPENSATION

	// Call the base-class...
	PARENT::ProcessClientUpdate(pxData, fServerTime, bAllowPosAndOrientationProcessing);
}

/// End of file. ///
