///////////////////////////////////////////////////////////////////////////////
/// @file deNetWinsock.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 "deNetWinsock.hpp"
#include <WINSOCK2.H>

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

DENET_API int GetWinsockErrorStr( int iError, char * outBuffer )
{
	return strlen( strcpy( outBuffer, "WINSOCK2: ERROR" ) );
}

//-------------------------------------------------------------
// DWORD GetAddr( char * pHost )
//-------------------------------------------------------------
DENET_API DWORD GetAddressFromName( char * pHost )
{
	LPHOSTENT	lpstHost;
	DWORD		dwAddr = INADDR_ANY;

	if( *pHost )
	{
		dwAddr = inet_addr( pHost );

		if( dwAddr == INADDR_NONE )
		{
			lpstHost = gethostbyname( pHost );
			if( lpstHost )
			{
				dwAddr = *((unsigned long FAR *) (lpstHost->h_addr));
			}
			else
			{
				// error
				dwAddr = INADDR_ANY;
			}
		}		
	}

	return dwAddr;
}


//-------------------------------------------------------------
// int GetHostAddressStr( char * outBuff )
//-------------------------------------------------------------
DENET_API int GetHostName( char * outBuff )
{
	char		strHost[32];
	SOCKADDR_IN	addLocal;
	SOCKADDR_IN	addRemote;
	int			iSize = sizeof(SOCKADDR);
	SOCKET		hSocket;
	int			iRet = 0;

	addLocal.sin_addr.s_addr = INADDR_ANY;

	iRet = gethostname( strHost, 32 );

	if( iRet )
	{
		// something went wrong, second strategy
		if( addLocal.sin_addr.s_addr == INADDR_ANY )
		{
			hSocket = socket( AF_INET, SOCK_DGRAM, 0 );

			if( hSocket != INVALID_SOCKET )
			{
				iSize = sizeof(SOCKADDR);
				addRemote.sin_family		= AF_INET;
				addRemote.sin_port			= htons(IPPORT_ECHO);
				addRemote.sin_addr.s_addr	= inet_addr("128.127.50.1");

				iRet = connect( hSocket, (LPSOCKADDR)&addRemote, iSize );

				if( iRet != SOCKET_ERROR )
				{
					getsockname( hSocket, (LPSOCKADDR)&addLocal, (int FAR*)&iSize );
				}

				closesocket( hSocket );
			}
		}

		strcpy( outBuff, inet_ntoa(addLocal.sin_addr) );
		return strlen( outBuff );
	}
	else
	{
		// we got it...
		strcpy( outBuff, strHost );
		return strlen( outBuff );
	}
}

	
//-------------------------------------------------------------
// DWORD GetHostAddress()
//-------------------------------------------------------------
DENET_API DWORD GetHostAddress(void)
{
	char buff[32];
	if( GetHostName( buff ) )
		return GetAddressFromName( buff );
	else
		return 0;
}

//-------------------------------------------------------------
// DWORD GetHostPort()
//-------------------------------------------------------------
DENET_API DWORD GetHostPort(void)
{
	return 0;
}

//-------------------------------------------------------------
// deNetAddress GetHostNetAddress(void)
//-------------------------------------------------------------
DENET_API deNetAddress GetHostNetAddress(void)
{
	deNetAddress	add;
	char			strIP[32];
	char			strName[32];
	in_addr			tmpAddr;
	tmpAddr.s_addr	= GetHostAddress();
	GetHostName( strName );
	strcpy( strIP, inet_ntoa( tmpAddr ) );
	
	// save connection desc
	add = deNetAddress(		GetHostAddress(),
							htons(DN_DEFAULT_PORT),
							strIP,
							strName );

	return add;
}