//////////////////////////////////////////////////////////////////////////////
//
// Asura_ServerNode_OrientedNode.cpp
//
// Created by NJD - 12 October 2006
//
// Copyright (C) 2006 Rebellion, All Rights Reserved.
//
//////////////////////////////////////////////////////////////////////////////

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

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

// header
#include "Entity/Locations/OrientedNode/Asura_ServerNode_OrientedNode.h"

// asura
#include "ChunkSystem/Asura_Chunk_Macros.h"
#include "ChunkSystem/Asura_Chunk_Stream.h"
#ifndef ASURA_NO_DEBUG_OUTPUT
#include "Debugging/Asura_DebugLineRender.h"
#endif
#include "Entity/Asura_Entity_Classification.h"

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

//////////////////////////////////////////////////////////////////////////////
//
// Asura_ServerNode_OrientedNode
//
//////////////////////////////////////////////////////////////////////////////

Asura_ServerNode_OrientedNode::Asura_ServerNode_OrientedNode( Asura_Guid uGuid )
: PARENT( uGuid )
, m_xOrientCQF( Asura_Maths::IdentityQuat )
{
    Classification = AsuraEntityClass_OrientedNode;
}

bool Asura_ServerNode_OrientedNode::IsBaseOrDerivativeOf(u_short usClassification) const
{
    if (usClassification == AsuraEntityClass_OrientedNode)
    {
        return true;
    }
    return PARENT::IsBaseOrDerivativeOf(usClassification);
}

#ifndef ASURA_NO_DEBUG_OUTPUT
void Asura_ServerNode_OrientedNode::RenderDebugInfo()
{
	PARENT::RenderDebugInfo();

	if ( !DebugTextPosOnScreen() ) { return; }

	Asura_Quat xOrientQ;
	GetOrientation( xOrientQ );
	Asura_DebugLineRender::AddAxis( GetPosition(), xOrientQ );
}
#endif

#ifdef ASURA_TOOLS
void Asura_ServerNode_OrientedNode::ApplyChangesForTemplateInstance( class Tools_EntityTemplateInstance* pxInstance )
{
    PARENT::ApplyChangesForTemplateInstance(pxInstance);

	Asura_Quat xOrient;
	m_xOrientCQF.ToQuat( xOrient );
	xOrient = pxInstance->TransformQuat( xOrient );
	m_xOrientCQF.FromQuat( xOrient );
}

bool Asura_ServerNode_OrientedNode::CanBeIncludedInTemplate() const 
{
    return ( Classification == AsuraEntityClass_OrientedNode );
}
#endif

void Asura_ServerNode_OrientedNode::CreateFromChunkStream( Asura_Guid uGuid, Asura_Chunk_Stream& xStream )
{
	Asura_ServerNode_OrientedNode* pxObject = new Asura_ServerNode_OrientedNode( uGuid );
	if ( pxObject )
    {
	    pxObject->ReadFromChunkStream( xStream );
    }
}

void Asura_ServerNode_OrientedNode::ReadFromChunkStream( Asura_Chunk_Stream& xStream )
{
	//Version
	int iVersion;
    xStream >> iVersion;

    //Parent
    PARENT::ReadFromChunkStream( xStream );

	//Our data
    if ( iVersion == CURRENT_CHUNK_VERSION )
	{
        xStream >> m_xOrientCQF;
    }
	else if ( iVersion == 0 )
	{
		Asura_Euler_3 xOrientE;
		xStream >> xOrientE;
		Asura_Quat xOrientQ;
		xOrientQ.FromEuler( xOrientE );
		m_xOrientCQF.FromQuat( xOrientQ );
	}
    else
    {
        Asura_Assertf( false, ( "Asura_ServerNode_OrientedNode::InitialiseFromChunkBuffer - unhandled chunk version (%d)", iVersion ) );
    }
}

void Asura_ServerNode_OrientedNode::WriteToChunkStream( Asura_Chunk_Stream& xStream ) const
{
    // (TI - 5.9.2004) - DON'T FORGET TO UPDATE ApplyChangesForTemplateInstance IF YOU CHANGE STUFF.

    // Version
    xStream << static_cast< int >( CURRENT_CHUNK_VERSION );

    // Parent
    PARENT::WriteToChunkStream( xStream );

    // Our data
	xStream << m_xOrientCQF;

    // (TI - 5.9.2004) - DON'T FORGET TO UPDATE ApplyChangesForTemplateInstance IF YOU CHANGE STUFF.
}
