//
// Asura_Entity_PFX_Effect_Data.cpp
//
// Created by KOR - 25/01/2008
//
// Copyright (C) 2008 Rebellion, All Rights Reserved.
//

#include "Core/Asura.h"


// This file's header.
#include "Entity/ParticleGenerator/Asura_Entity_PFX_Effect_Data.h"

// Asura includes
#include "ChunkSystem/Asura_Chunk_Stream.h"
#include "Core/Asura_Spline.h"

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

Asura_Entity_PFX_Effect_Data::Asura_Entity_PFX_Effect_Data()
: m_uEffectTemplateHash(ASURA_HASH_ID_UNSET)
, m_xCollisionPosition(Asura_Maths::ZeroVector3)
, m_xCollisionDirection(Asura_Maths::ZeroVector3)
, m_fMinRetriggerTime(0.f)
, m_fMaxRetriggerTime(0.f)
, m_pxSpline(NULL)
, m_uFlags(0)
{
}

Asura_Entity_PFX_Effect_Data::~Asura_Entity_PFX_Effect_Data()
{
	delete m_pxSpline;
}

Asura_Entity_PFX_Effect_Data& Asura_Entity_PFX_Effect_Data::operator = (const Asura_Entity_PFX_Effect_Data& xOriginal)
{
	m_uEffectTemplateHash = xOriginal.m_uEffectTemplateHash;
	m_xCollisionPosition = xOriginal.m_xCollisionPosition;
	m_xCollisionDirection = xOriginal.m_xCollisionDirection;
	m_xSourceVolume = xOriginal.m_xSourceVolume;
	m_fMinRetriggerTime = xOriginal.m_fMinRetriggerTime;
	m_fMaxRetriggerTime = xOriginal.m_fMaxRetriggerTime;
	if(xOriginal.m_pxSpline)
	{
		if(!m_pxSpline)
		{
			m_pxSpline = new Asura_Spline<Asura_Vector_3>();
		}
		m_pxSpline->CopyFrom(xOriginal.m_pxSpline);
	}
	else
	{
		if(m_pxSpline)
		{
			delete m_pxSpline;
			m_pxSpline = NULL;
		}
	}
	m_uFlags = xOriginal.m_uFlags;
	return *this;
}


void Asura_Entity_PFX_Effect_Data::ReadFromChunkStream(Asura_Chunk_Stream& xStream, Asura_Vector_3& xPos, Asura_Matrix_3x3& xOri)
{
	//Extract version number from chunk
	u_int uChunkVersion;
	xStream >> uChunkVersion;
	Asura_Assert(uChunkVersion <= uASURA_ENTITY_PFX_EFFECT_DATA_VERSION, "Unrecognised chunk version");

	xStream >> m_uEffectTemplateHash;
	xStream >> xPos;
	{
		Asura_Comp_Quat_Fast xCompQuat;
		Asura_Quat xTempQuat;
		xStream >> xCompQuat;
		xCompQuat.ToQuat(xTempQuat);
		xTempQuat.ToMatrix(xOri);
	}
	xStream >> m_xCollisionPosition;
	xStream >> m_xCollisionDirection;
	m_xSourceVolume.ReadFromChunkStream(xStream);
	xStream >> m_fMinRetriggerTime;
	xStream >> m_fMaxRetriggerTime;
	xStream >> m_uFlags;

	if(m_bUsesSpline)
	{
		m_pxSpline = new Asura_Spline<Asura_Vector_3>();
		m_pxSpline->ReadFromChunkStream(xStream);
	}
}

void Asura_Entity_PFX_Effect_Data::WriteToChunkStream (Asura_Chunk_Stream& xStream, const Asura_Vector_3& xPos, const Asura_Matrix_3x3& xOri) const
{
	xStream << uASURA_ENTITY_PFX_EFFECT_DATA_VERSION;
	xStream << m_uEffectTemplateHash;
	xStream << xPos;
	{
		Asura_Quat xTempQuat;
		xTempQuat.FromMatrix(xOri);
		xStream << Asura_Comp_Quat_Fast(xTempQuat);
	}
	xStream << m_xCollisionPosition;
	xStream << m_xCollisionDirection;
	m_xSourceVolume.WriteToChunkStream(xStream);

	xStream << m_fMinRetriggerTime;
	xStream << m_fMaxRetriggerTime;

	Asura_WriteToStream_Bitfield_Wrapper<u_int>	xFlagsBitfield (m_uFlags);

	// Create the bitfield...
	xFlagsBitfield.Add(m_bOldActiveFlag,		1);
	xFlagsBitfield.Add(m_bIgnoreModuleLinking,	1);
	xFlagsBitfield.Add(m_bSkyboxEffect,			1);
	xFlagsBitfield.Add(m_bWaterDistorterEffect,	1);
	xFlagsBitfield.Add(m_bUsesSpline,			1);

	xStream << xFlagsBitfield;

	Asura_Assert(!m_bUsesSpline || m_pxSpline, "Flagged to use spline but don't actually have one");
	if(m_bUsesSpline && m_pxSpline)
	{
		m_pxSpline->WriteToChunkStream(xStream);
	}
}

#ifdef ASURA_TOOLS
void Asura_Entity_PFX_Effect_Data::ApplyChangesForTemplateInstance(Tools_EntityTemplateInstance* pxInstance)
{
	m_xCollisionPosition = pxInstance->TransformPosition(m_xCollisionPosition);
	m_xCollisionDirection = m_xCollisionDirection * pxInstance->GetRelativeMatrix();
}
#endif // ASURA_TOOLS



/// End of file. ///
