///////////////////////////////////////////////////////////////////////////////
/// @file dePacket.cpp
///
/// @brief 
///
/// @author trajar
///
/// This file is the intellectual property of Novus Delta, LLC.. Usage of the
/// contents of this file is subject to the Destiny3D Member License which
/// can be found at http://www.destiny3d.com.  Any other usage is prohibited.
///
/// This file is distributed "AS IS" without warranty of any kind.  Novus
/// Delta, LLC. does not guarantee the fitness of the contents of this file
/// for any particular purpose.
///
/// Copyright (C) 2001-2003 Novus Delta, LLC. All Rights Reserved.
///
/// <hr>
///                                 Change History
/// <hr>
///
/// @date Jun 2002
/// @author trajar
/// @remarks Creation
///
///////////////////////////////////////////////////////////////////////////////

#include <WINDOWS.H>
#include "dePacket.hpp"
#include <SEARCH.H>

#ifdef	_DEBUG
 #include	<crtdbg.h> 
 #define new new(_NORMAL_BLOCK,__FILE__, __LINE__)
#endif

_inline int dePacket::ComparePacket( const void * larg, const void * rarg )
{
	const dePacket * l = reinterpret_cast<const dePacket *>( larg );
	const dePacket * r = reinterpret_cast<const dePacket *>( rarg );

	if( (*l) < (*r) )
		return -1;
	else
		return 1;
}

dePacket::dePacket(void) : m_Data(NULL)
{
	m_Header.Flags			= 0;
	m_Header.Type			= 0;
	m_Header.ID				= 0;
	m_Header.Size			= 0;
	m_Header.Recipient		= NULL;
	m_Header.Sender			= NULL;
	m_Header.SubID			= 0;
	m_Header.LocalID		= 0;
}

dePacket::~dePacket(void)
{
	SAFE_DELETE(m_Data);
}

dePacket::dePacket( const BYTE * pData, DWORD dwFlags ) : m_Data(NULL)
{
	// copy header
	memcpy( &m_Header, pData, sizeof( PacketHeader ) );

	deASSERT( m_Header.Size > 0 );
	deASSERT( m_Header.TotalSize > 0 );

	// increment ptr
	pData += sizeof( PacketHeader );

	m_Data = new BYTE[m_Header.Size];
	memcpy( m_Data, pData, m_Header.Size );
}

dePacket::dePacket( const dePacket::PacketHeader& pHeader, const void * pBuff, DWORD dwFlags ) : m_Data(NULL)
{
	m_Header = pHeader;
	
	if( m_Header.Size > 0 )
	{
		m_Data = new BYTE[m_Header.Size];
		memcpy( m_Data, pBuff, m_Header.Size );
	}
	else
		m_Data = NULL;
}

dePacket * dePacket::SortPackets( dePacket * pPackets, int iNumPackets )
{
	qsort( pPackets, iNumPackets, sizeof(dePacket*), dePacket::ComparePacket );
	return pPackets;
}

dePacket * dePacket::ConsolidatePackets( const dePacket * pPackets, int iNumPackets )
{
	dePacket *	packet	= new dePacket();
	BYTE *		data	= NULL;
	int			i		= 0;

	// set up packet header
	packet->m_Header.NetMsgID	= pPackets->m_Header.NetMsgID;
	packet->m_Header.Flags		= pPackets->m_Header.Flags;
	packet->m_Header.ID			= pPackets->m_Header.ID;
	packet->m_Header.LocalID	= pPackets->m_Header.LocalID;
	packet->m_Header.Recipient	= pPackets->m_Header.Recipient;
	packet->m_Header.Sender		= pPackets->m_Header.Sender;
	packet->m_Header.Size		= pPackets->m_Header.TotalSize;
	packet->m_Header.TotalSize	= pPackets->m_Header.TotalSize;
	packet->m_Header.Type		= pPackets->m_Header.Type;
	
	// set up memory
	packet->m_Data	= new BYTE[ packet->m_Header.TotalSize ];

	// set up local variable
	data			= packet->m_Data;
	deASSERT( data );

	for( i=0; i<iNumPackets; i++ )
	{
		// copy packet data into new packet
		memcpy( data, pPackets->GetData(), pPackets->GetHeader().Size );

		// increment local ptr
		data += pPackets->GetHeader().Size;
	}

	return packet;
}

_inline dePacket& dePacket::operator = ( const dePacket& r )
{	
	m_Header = r.m_Header;
	SAFE_DELETE_ARRAY( m_Data );

	if( r.m_Header.Size > 0 )
	{
		m_Data = new BYTE[ r.m_Header.Size ];
		memcpy( m_Data, r.m_Data, r.m_Header.Size );
	}

	return *this;
}