//
// Asura_ServerEntity_MetaMusicTrigger.cpp
//
// Created by Richard Rice - 23/01/2004
// 
// Copyright (C) 2003 Rebellion, All Rights Reserved.
//


#include "Core/Asura.h"

#if !defined(ASURA_SUPPORT_DYNAMIC_MUSIC_SYSTEM)

#include "Entity/Triggers/Asura_ServerEntity_MetaMusicTrigger.h"

// Engine independent.
#include "ChunkSystem/Asura_Chunk_Macros.h"
#include "ChunkSystem/Asura_Chunk_Stream.h"
#include "Debugging/Asura_Assert.h"
#include "Entity/Asura_Entity_Classification.h"
#include "Network/Asura_Network.h"
#include "Network/Asura_Message.h"
#include "Sound/Asura_MetaMusic_System.h"


#define ASURA_SERVERENTITY_METAMUSICTRIGGER_VERSION_NUMBER 0

Asura_ServerEntity_MetaMusicTrigger::Asura_ServerEntity_MetaMusicTrigger() 
: Asura_ServerEntity_Activatable(true)
{
	Classification = AsuraEntityClass_MetaMusicTrigger;
	m_uTrackID = ASURA_HASH_ID_UNSET;
	m_uFlags = 0;
}

Asura_ServerEntity_MetaMusicTrigger::Asura_ServerEntity_MetaMusicTrigger(Asura_Guid uGuid) 
: Asura_ServerEntity_Activatable(uGuid)
{
	Classification = AsuraEntityClass_MetaMusicTrigger;
	m_uTrackID = ASURA_HASH_ID_UNSET;
	m_uFlags = 0;
}

Asura_ServerEntity_MetaMusicTrigger::Asura_ServerEntity_MetaMusicTrigger(Asura_Guid uGuid,const char*& pcChunkBuffer)
:Asura_ServerEntity_Activatable(uGuid,pcChunkBuffer)
{
	Classification = AsuraEntityClass_MetaMusicTrigger;
	
	//check the version
	int iVersion;
	ASURA_CHUNK_EXTRACT( pcChunkBuffer, iVersion,int);
	Asura_Assert(iVersion <= ASURA_SERVERENTITY_METAMUSICTRIGGER_VERSION_NUMBER, "FATAL ERROR: unknown version number for Asura_ServerEntity_MetaMusicTrigger");

	//read in the rest
	ASURA_CHUNK_EXTRACT( pcChunkBuffer, m_uTrackID, Asura_Hash_ID );
	ASURA_CHUNK_EXTRACT( pcChunkBuffer, m_uFlags, u_int );
}

void Asura_ServerEntity_MetaMusicTrigger::CreateFromChunkBuffer(Asura_Guid uGuid, const char*& pcChunkBuffer)
{
#ifdef TEST_ENTITY_CHUNK_STREAM
	TestStream<Asura_ServerEntity_MetaMusicTrigger>(uGuid, pcChunkBuffer);
#endif
	new Asura_ServerEntity_MetaMusicTrigger(uGuid, pcChunkBuffer);
}


void Asura_ServerEntity_MetaMusicTrigger::OnTrigger()
{
	Asura_ServerEntity_Activatable::OnTrigger();

	if(m_uFlags & ASURA_METAMUSICTRIGGER_FLAG_CHANGETRACK)
	{
		//send a message to the client machines to play the music track
    	Asura_Message* pxMessage = Asura_Network::CreateMessage(ASURA_MSG_METAMUSIC_PLAY,sizeof(Asura_MsgData_MetaMusic_Play));
    	Asura_MsgData_MetaMusic_Play* pxData = (Asura_MsgData_MetaMusic_Play*) pxMessage->GetData();

		pxData->m_uTrackID       = m_uTrackID;
		pxData->m_ucHighPriority = (unsigned char)((m_uFlags & ASURA_METAMUSICTRIGGER_FLAG_HIGHPRIORITY) ? 1 : 0);

    	pxMessage->To   = ASURA_GUID_ALL_CLIENTMACHINES;
    	pxMessage->From = Guid;

    	Asura_Network::Send(pxMessage);

		//if track is being stopped ,return now to prevent any ambient/tension changes restarting it immediately
		if(m_uTrackID == 0) return;
	}
	else if(m_uFlags & ASURA_METAMUSICTRIGGER_FLAG_RESTARTLASTTRACK)
	{
    	Asura_Message* pxMessage = Asura_Network::CreateMessage( ASURA_MSG_METAMUSIC_RESTARTLASTTRACK,
                                                                 sizeof( Asura_MsgData_MetaMusic_Restart ) );
    	Asura_MsgData_MetaMusic_Restart* pxData = (Asura_MsgData_MetaMusic_Restart*) pxMessage->GetData();

        pxData->m_ucHighPriority = (unsigned char)((m_uFlags & ASURA_METAMUSICTRIGGER_FLAG_HIGHPRIORITY) ? 1 : 0);

    	pxMessage->To   = ASURA_GUID_ALL_CLIENTMACHINES;
    	pxMessage->From = Guid;

    	Asura_Network::Send(pxMessage);
	}
	if(m_uFlags & (ASURA_METAMUSICTRIGGER_FLAG_AMBIENT|ASURA_METAMUSICTRIGGER_FLAG_TENSION|ASURA_METAMUSICTRIGGER_FLAG_ACTION))
	{
		//send a message to the client machines to change the state
    	Asura_Message* pxMessage = Asura_Network::CreateMessage(ASURA_MSG_METAMUSIC_CHANGESTATE,sizeof(Asura_MsgData_MetaMusic_ChangeState));
    	Asura_MsgData_MetaMusic_ChangeState* pxData = (Asura_MsgData_MetaMusic_ChangeState*) pxMessage->GetData();

		if(m_uFlags & ASURA_METAMUSICTRIGGER_FLAG_AMBIENT)
		{
			pxData->m_ucState = (unsigned char)ASURA_METAMUSIC_AMBIENT;
		}
		else if(m_uFlags & ASURA_METAMUSICTRIGGER_FLAG_TENSION)
		{
			pxData->m_ucState = (unsigned char)ASURA_METAMUSIC_TENSION;
		}
		else
		{
			pxData->m_ucState = (unsigned char)ASURA_METAMUSIC_ACTION;
		}

        pxData->m_ucHighPriority = (unsigned char)((m_uFlags & ASURA_METAMUSICTRIGGER_FLAG_HIGHPRIORITY) ? 1 : 0);

    	pxMessage->To   = ASURA_GUID_ALL_CLIENTMACHINES;
    	pxMessage->From = Guid;

    	Asura_Network::Send(pxMessage);
	}
	
}



int Asura_ServerEntity_MetaMusicTrigger::GetChunkBufferSize()
{
	return Asura_ServerEntity_Activatable::GetChunkBufferSize()
           +sizeof(int)                 // version
           +sizeof(Asura_Hash_ID)                // music track
		   +sizeof(u_int);				// flags
}

void Asura_ServerEntity_MetaMusicTrigger::FillInChunkBuffer(char*& pcChunkBuffer)
{
	/*
	This entity type can be used in template files , so any changes to FillInChunkBuffer may
	require ApplyChangesForTemplateInstance() to be updated as well.
	Please see the comment at the top of Tools/EntityTemplate/Tools_EntityTemplate_System.h before 
	making any changes.
	RAR 29/04/2004
	*/
	
	Asura_ServerEntity_Activatable::FillInChunkBuffer(pcChunkBuffer);

	int iVersion = ASURA_SERVERENTITY_METAMUSICTRIGGER_VERSION_NUMBER;
	ASURA_CHUNK_FILLANDVERIFY( pcChunkBuffer, iVersion,int);

	ASURA_CHUNK_FILLANDVERIFY( pcChunkBuffer, m_uTrackID, Asura_Hash_ID );
	// Uses bitmask rather than bitfield, so don't bit flip
	ASURA_CHUNK_FILLANDVERIFY( pcChunkBuffer, m_uFlags, u_int);
}

void Asura_ServerEntity_MetaMusicTrigger::WriteToChunkStream(Asura_Chunk_Stream &xStream) const
{
	// Wrong order

	// Parent...
	Asura_ServerEntity_Activatable::WriteToChunkStream( xStream );

	// Version...
	int iVersion = ASURA_SERVERENTITY_METAMUSICTRIGGER_VERSION_NUMBER;
	xStream << iVersion;

	// Child...
	xStream << m_uTrackID;
	xStream << m_uFlags;
}

void Asura_ServerEntity_MetaMusicTrigger::ReadFromChunkStream(Asura_Chunk_Stream &xStream)
{
	// Wrong order

	// Parent...
	Asura_ServerEntity_Activatable::ReadFromChunkStream( xStream );

	// Version...
	int iVersion = 0;
	xStream >> iVersion;
	Asura_Assert(iVersion <= ASURA_SERVERENTITY_METAMUSICTRIGGER_VERSION_NUMBER, "FATAL ERROR: unknown version number for Asura_ServerEntity_MetaMusicTrigger");

	// Child...
	xStream >> m_uTrackID;
	xStream >> m_uFlags;
}
#endif	//!defined(ASURA_SUPPORT_DYNAMIC_MUSIC_SYSTEM)
