#include "BroadReceiver.h"



BroadReceiver::BroadReceiver( LoggingMgr *lm, RSSClientDialog *rcd )
{
	m_pLogger = lm;
	m_pRssDialog = rcd;
	m_bRequested = false;
	broadcastPort = 8005;
	ServPort = 8006;
	
}



BroadReceiver::SetupSocket( void )
{
	if ((sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0 )
	{
		m_pLogger->PrintOut( "socket creation failed" );
		SleepTillDeath( );
	}

	memset( &broadcastAddr, 0, sizeof( broadcastAddr));
	broadcastAddr.sin_family = AF_INET;
	broadcastAddr.sin_addr.s_addr = htonl( INADDR_ANY );
	broadcastAddr.sin_port = htons( broadcastPort );

	if ( bind( sock, (struct sockaddr *) &broadcastAddr, sizeof( broadcastAddr )) < 0 )
	{
		m_pLogger->PrintOut( "couldn't bind socket" );
		SleepTillDeath( );
	}
	
	m_pLogger->PrintOut( "broadcast receive socket created, initialized, and bound successfully" );
}








BroadReceiver::SetupSendSocket( void )
{
	if ((s_sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0 )
	{
		m_pLogger->PrintOut( "socket creation failed" );
		SleepTillDeath( );
	}

	memset( &ServAddr, 0, sizeof( ServAddr));
	ServAddr.sin_family = AF_INET;
	ServAddr.sin_addr.s_addr = inet_addr( "127.0.0.1" );
	ServAddr.sin_port = htons( ServPort );

	m_pLogger->PrintOut( "sending socket created and initialized successfully" );

}











BroadReceiver::BeginReceive( void )
{
	char *buf;
	bool didstart = false;

	struct sockaddr_in fromAddr;
	memset( &fromAddr,0,sizeof( fromAddr ));
	int fromSize = sizeof( fromAddr );


	if ( (buf = (char *)malloc( sizeof( char ) * BUFLEN )) == NULL )
	{
		m_pLogger->PrintOut( "error malloc'ing buffer for hostname");
		SleepTillDeath( );
	}
	memset( buf,0,sizeof(buf));
	
	gethostname( buf, BUFLEN );





	m_pLogger->PrintOut( "going into receive/send loop..." );
	
	for( EVER ){	
		
		if ((recvStringLen = recvfrom( sock, recvString, MAXRECVSTRING,0,(struct sockaddr *)&fromAddr,&fromSize)) < 0 )
		{
			m_pLogger->PrintOut( "receiving failed" );
			SleepTillDeath( );
		
		}

		recvString[ recvStringLen ] = '\0';
		
		
		switch( atoi( recvString )) // handle Server protocol requests
		{
			case BROAD_CLIENTREQUEST:
				if ( m_bRequested != true )
				{
					m_pLogger->PrintOut( QString("Received server help request from ") + QString(inet_ntoa(fromAddr.sin_addr)));

					if ( sendto( s_sock, buf, strlen( buf ),0,(struct sockaddr *) &ServAddr,
						sizeof( ServAddr )) != (int)strlen( buf ))
						SleepTillDeath( );
					m_pLogger->PrintOut( buf );
					m_pLogger->PrintOut( "Successfully sent server local IP address" );
					m_bRequested = true;
				}//if
				break;
		
			case BROAD_STARTAUTO:
				m_pLogger->PrintOut("case startauto found");
				if( didstart != true )
				{
				m_nThreadArraySize = m_pRssDialog->getSliderValue( );
				AllocateThreadArray( m_nThreadArraySize );
				InitThreadArray( );
				RunThreadArray( );
				//FreeThreadArray( );
				didstart = true;
				}
				break;

			default:
				m_pLogger->PrintOut( "client received unknown server command" );
				break;

		}//switch
		
		
	}//for	

	free( buf );
}



BroadReceiver::AllocateThreadArray( int size )
{
	if ( (ThreadArray = (RunExeThread **)malloc( sizeof( RunExeThread ) * size )) == NULL)
	{
		m_pLogger->PrintOut( "Error Allocating Thread Array" );
		SleepTillDeath( );
	}
	
}


BroadReceiver::InitThreadArray( void )
{
	int i;
	for( i = 0; i< m_nThreadArraySize ; i++ )
	{
		ThreadArray[i] = new RunExeThread( i, m_pLogger );
	}
}



BroadReceiver::RunThreadArray( void )
{
	int i;
	for ( i = 0; i< m_nThreadArraySize ; i++ )
	{
		ThreadArray[i]->start( );
	}
}

BroadReceiver::FreeThreadArray( void )
{
	int i;
	for( i = 0; i< m_nThreadArraySize ; i++ )
	{
		delete ThreadArray[i];
	}

	free( ThreadArray );
}





BroadReceiver::StartWinsock( void )
{
	wVersionRequested = MAKEWORD(2, 0);   /* Request Winsock v2.0 */
    
	if ( WSAStartup( wVersionRequested, &wsaData ) != 0 )
	{
		m_pLogger->PrintOut( "Error starting Winsock" );
		SleepTillDeath( );
	
	}
	m_pLogger->PrintOut( "Winsock DLL loaded successfully" );
}


BroadReceiver::ShutdownWinsock( void )
{
	closesocket( sock );
	WSACleanup( );
	m_pLogger->PrintOut( "winsock now closed" );
	SleepTillDeath( );
}





BroadReceiver::SleepTillDeath( void )
{
	m_pLogger->PrintOut( "FATAL ERROR: now pausing forever (please kill me)" );
	for( EVER )
	{
		Sleep( 10000 ); 
	}
}
