#pragma warning (disable:4949)
#pragma unmanaged

#ifndef _NB_USE_OLD_ENGINE
	#include "NetBridge_IOCP.h"
#else
	#include "NetBridge_OLDENGINE.h"
#endif

HANDLE			CNetBridge::m_pNetEventHandle[ MAXIMUM_WAIT_OBJECTS ];
DWORD			CNetBridge::m_dwNetHandleIndex	= 0;
CNetBridge*		CNetBridge::m_pNetPoint[ MAXIMUM_WAIT_OBJECTS ];
DWORD			CNetBridge::m_dwEnterTime = 0;

#ifdef DF_PACKET_LOG
	DWORD			CNetBridge::m_dwPacketLog = 0;
#endif


CNetBridge*				CreateNetBridge		()
{
#ifndef _NB_USE_OLD_ENGINE
	CNetBridge* pBridge		= (CNetBridge*)new CNetBridge_IOCP;	
	CNetBridge::m_pNetEventHandle[ CNetBridge::m_dwNetHandleIndex ] = ((CNetBridge_IOCP*)pBridge)->m_hMsgEvent;
	CNetBridge::m_pNetPoint[ CNetBridge::m_dwNetHandleIndex ]		= pBridge;	
#else
	// 根據作業系統不統採取不同的網路核心
	CNetBridge* pBridge		= (CNetBridge*)new CNetBridge_OLDENGINE;
	CNetBridge::m_pNetPoint[ CNetBridge::m_dwNetHandleIndex ] = pBridge;
#endif

	pBridge->Init();
	
	CNetBridge::m_dwNetHandleIndex++;
	return pBridge;
}

void					DeleteNetBridge		( CNetBridge* pBridge )
{ 
	HANDLE	*pHandle = NULL;

	DWORD index = 0;
	while( index < CNetBridge::m_dwNetHandleIndex )
	{
		if( CNetBridge::m_pNetPoint[ index ] == pBridge )
			break;

		index++;
	}

	//index++;

	DWORD dwEndTime = GetTickCount() + 60000;

	while( 1 )
	{
		if( pBridge->Shutdown() == true )
		{
			break;
		}
		else
			CNetBridge::WaitAll( 50 );

		if( GetTickCount() > dwEndTime )
		{			
			break;
		}
	}	

#ifndef _NB_USE_OLD_ENGINE

	while( index < ( CNetBridge::m_dwNetHandleIndex - 1 ) )
	{
		CNetBridge::m_pNetEventHandle[ ( index ) ]	= CNetBridge::m_pNetEventHandle[ ( index + 1 ) ] ;
		CNetBridge::m_pNetPoint[ ( index ) ]		= CNetBridge::m_pNetPoint[ ( index + 1 ) ] ;
        index++;
	}
#else

	while( index < ( CNetBridge::m_dwNetHandleIndex -1 ))
	{
		CNetBridge::m_pNetPoint[ ( index ) ]		= CNetBridge::m_pNetPoint[ ( index + 1 )] ;
	}

#endif

	CNetBridge::m_dwNetHandleIndex--;
	
	delete pBridge; 
}

DWORD	CNetBridge::WaitAll				( DWORD dwTime )
{
			
#ifndef _NB_USE_OLD_ENGINE

	DWORD dwReturn	= WaitForMultipleObjects( CNetBridge::m_dwNetHandleIndex, CNetBridge::m_pNetEventHandle, false, dwTime );
	DWORD dwTimeNow	= GetTickCount();

	if( dwReturn != WAIT_TIMEOUT || dwTimeNow > CNetBridge::m_dwEnterTime )
	{		
		CNetBridge::m_dwEnterTime = GetTickCount() + 100;

		//DWORD dwIndex = dwReturn - WAIT_OBJECT_0;	
		DWORD dwIndex = 0;
		CNetBridge::m_pNetPoint[ dwIndex ]->Flush();

		dwIndex++;
		
		while( dwIndex < CNetBridge::m_dwNetHandleIndex )
		{
			//if( WaitForSingleObject( CNetBridge::m_pNetEventHandle[ dwIndex ], 0 ) != WAIT_TIMEOUT )
			//{
				CNetBridge::m_pNetPoint[ dwIndex ]->Flush();
			//}

			dwIndex++;
		}
	}
	return dwReturn;
#else
		SleepEx( 10, true );

		DWORD dwIndex = 0;
		while( dwIndex < CNetBridge::m_dwNetHandleIndex )
		{
			CNetBridge::m_pNetPoint[ dwIndex ]->Flush();
			dwIndex++;
		}

		return 10;
	
#endif

	
}

DWORD	ConvertIP( const char* pszIP )
{
	u_long IP_ADDRESS;

	if( pszIP != NULL )
	{
		if( strlen( pszIP ) != 0 )
		{

			//測試輸入的IP是IP Address 或是 DNS

			//轉換 IP
			IP_ADDRESS = inet_addr( pszIP ); 

			//測試轉出結果, 若傳回 INADDR_NONE 的話, 表該 IP 可能是 DNS
			if ( IP_ADDRESS == INADDR_NONE ) 
			{
				// Host isn't an IP address, try using DNS
				hostent* HE = gethostbyname( pszIP );

				if ( HE == 0 )
				{
					//Error can't check DNS
					return 0;
				}

				IP_ADDRESS = *((u_long*)HE->h_addr_list[0]);
			}
		}
	}

	return IP_ADDRESS;
}

void ConvertIPtoString	( DWORD dwIP, char* pszIP )
{
	BYTE* pIP = (BYTE*)&dwIP;
	if( pszIP != NULL )
	{
		sprintf( pszIP, "%d.%d.%d.%d", *pIP, *(pIP+1), *(pIP+2), *(pIP+3) );
	}
}


void CNetBridge::Send				( DWORD dwNetID, DWORD dwSize, PVOID pBuffer, DWORD dwPriority, DWORD dwFlag )
{
	_Send( dwNetID, dwSize, pBuffer, dwPriority, dwFlag );

#ifdef DF_PACKET_LOG
	Struct_PacketLog Log;
	Log.dwID			= 0x12345678;
	Log.dwPacketID		= *(DWORD*)pBuffer;
	Log.dwTime			= GetTickCount();
	m_dwPacketLog++;

	_Send( dwNetID, sizeof( Log ), &Log, 0, 0 );
#endif
}
#pragma managed