UINT ConnectionModuleThreadProc(LPVOID pParam)
{
//	UINT i;
	// Init message window handle
	HWND hwnd=(HWND)pParam;

	// Init the message data structure and send it
	CCriticalSection critical_section;
	ConnectionModuleThreadData thread_data;
	ConnectionModuleStatusData status_data;
//	vector<SupernodeHost> connect_hosts;
	vector<SOCKET> accepted_sockets;

	// Create the sockets for this module
	ConnectionSockets sockets;
	sockets.m_dlg_hwnd = hwnd;
	memcpy(&thread_data.m_reserved_events[0],&sockets.m_events[0],sizeof(WSAEVENT)*5);
	thread_data.p_status_data=&status_data;
	thread_data.p_accepted_sockets=&accepted_sockets;
//	thread_data.p_connect_hosts=&connect_hosts;
//	SendMessage(hwnd,WM_INIT_THREAD_DATA,(WPARAM)&critical_section,(LPARAM)&thread_data);
	PostMessage(hwnd,WM_INIT_THREAD_DATA,(WPARAM)&critical_section,(LPARAM)&thread_data);
//	sockets.p_file_sharing_manager = thread_data.p_file_sharing_manager;

	int num_reserved_events=sockets.ReturnNumberOfReservedEvents();

	WSANETWORKEVENTS events;	// what the fired event data was

	DWORD num_events=sockets.ReturnNumberOfEvents();	// 64
	BOOL wait_all=FALSE;
	DWORD timeout=WSA_INFINITE;
	BOOL alertable=FALSE;
	DWORD event;	// which event fired

	TorrentFile torrent;
	int listening_port;
	
	// Seed random number generator
	srand((unsigned)time(NULL));

	while(1)
	{
		event=WSAWaitForMultipleEvents(num_events,&sockets.m_events[0],wait_all,timeout,alertable);
		
		char buf[16];
		_itoa(event,buf,10);
		
		if(event==WSA_WAIT_FAILED)
		{
			::MessageBox(NULL,"Wait Failed.","Error",MB_OK);
			break;
		}

		// Check to see if this is the kill thread event (reserved event 0)
		if(event==0)
		{
			WSAResetEvent(sockets.m_events[event]);	// reset event
			break;
		}

		// Process all the items in the process queue and cancel all the transfers in the cancel queue
		if(event==1)
		{
			// Temp variables
//			vector<SupernodeHost> tmp_connect_hosts;
			
			// Copy the critical data to the temp variables
			CSingleLock singleLock(&critical_section);
			singleLock.Lock();
			if(singleLock.IsLocked())
			{
				WSAResetEvent(sockets.m_events[event]);	// reset event
				torrent = thread_data.m_torrent;
				listening_port = thread_data.m_port;
			
/*
				if(accepted_sockets.size()>0)
				{
					for(int i=0;i<(int)accepted_sockets.size();i++)
					{
						sockets.AddNewClient(accepted_sockets[i]);
					}
					accepted_sockets.clear();
				}
*/


			// connect to the trackers
				sockets.InitTorrent(torrent);
				sockets.RegisterWithTracker(&torrent, listening_port);
			// Start spitting out sockets here, it'll be fun.
				PeerList * peers = torrent.GetPeers();
				int peercount = peers->GetCount();
			// temp KLUDGE for debug testing if we have more than 50 peers just use 50
			
				if (peercount > 55)
				{
					peercount = 55;
				}
			
				for(int i = 0;i < peercount ;i++)
				{
				//DEBUG connecting to everyone for the test
	//			if (peers->IsSeed())
					if (peers != NULL)
					{
						char * connectip = new char[strlen(peers->GetIP().c_str())];
						while (peers != NULL)
						{

							strcpy(connectip,peers->GetIP().c_str());
							if ((strstr(connectip,"38.118.151")==NULL)&&(strstr(connectip,"204.9.116")==NULL)&&(strstr(connectip,"38.118.154")==NULL))
							{
								break;
							}
							else
							{
								peers = peers->GetNext();
							}
						}
						if (peers != NULL)
						{
							bool is_seed = peers->IsSeed();
							sockets.MakeNewConnection(connectip,atoi(peers->GetPort().c_str()), is_seed);
							peers = peers->GetNext();	
						}
					//connectsocket->Connect(connectip,atoi(peers[i].GetPort().c_str()));
					//mv_sockets.push_back(connectsocket);
					//delete [] connectip;  // This is deleted elsewhere
					//break;  // just testing one for now
					}
					char msg[1024+1];
					sprintf(msg,"peercount = %d i = %d, getting next peer",peercount,i);
					CFile logfile;
					/*
					if (logfile.Open("BTConnectionModuleLog.txt",CFile::modeCreate|CFile::modeWrite|CFile::modeNoTruncate|CFile::shareDenyWrite)== TRUE)
					{
						logfile.SeekToEnd();
						logfile.Write(msg, (unsigned int)strlen(msg));
						logfile.Write("\r\n",2);
						logfile.Close();
					}
					*/

					sprintf(msg,"Got next peer");
					/*
					if (logfile.Open("BTConnectionModuleLog.txt",CFile::modeCreate|CFile::modeWrite|CFile::modeNoTruncate|CFile::shareDenyWrite)== TRUE)
					{
						logfile.SeekToEnd();
						logfile.Write(msg, (unsigned int)strlen(msg));
						logfile.Write("\r\n",2);
						logfile.Close();
					}
					*/
				}

				singleLock.Unlock();
			}
			
			/*
			// Call the functions, passing the temp data
			if(tmp_connect_hosts.size()>0)
			{
				//if(!thread_data.m_disconnect_to_hosts)
				//	sockets.ConnectToHosts(tmp_connect_hosts);
			}
			if(thread_data.m_reconnect_to_hosts)
			{
				//thread_data.m_reconnect_to_hosts = false;
				//sockets.ReConnectAll();
			}
			if(thread_data.m_disconnect_to_hosts)
			{
				//sockets.ReConnectAll();
			}
*/
		}

		// The Timer has fired send keep alive messages
		if(event==2)
		{
		
			//LogMess("Timer Fired Message received");
			CSingleLock singleLock(&critical_section);
			singleLock.Lock();
			if(singleLock.IsLocked())
			{
				//LogMess("Timer Fired Message Lock");
				WSAResetEvent(sockets.m_events[event]);	// reset event
				
				int num_connected = sockets.CheckNumberOfConnections();

				if (num_connected > 0)
				{
					sockets.KeepConnectionsAlive();
				}
				else
				{
					PostMessage(hwnd,WM_KILL_MODULE	,(WPARAM)&critical_section,(LPARAM)&thread_data);
				}
				singleLock.Unlock();
				//LogMess("Timer Fired Message UnLocked");
			}

		}
		/*
		if(event==2)
		{
			// Extract the status data from the sockets as temp data
			//ConnectionModuleStatusData tmp_status_data=sockets.ReportStatus();

			CSingleLock singleLock(&critical_section);
			singleLock.Lock();
			if(singleLock.IsLocked())
			{
				WSAResetEvent(sockets.m_events[event]);	// reset event
				
				//status_data=tmp_status_data;	 // copy the temp data
				sockets.ReportStatus(status_data);

				singleLock.Unlock();
			}
			
			PostMessage(hwnd,WM_STATUS_READY,0,0);
		}
*/
		// Event 3
		
		if(event==3)
		{
			CSingleLock singleLock(&critical_section);
			singleLock.Lock();
			if(singleLock.IsLocked())
			{
				WSAResetEvent(sockets.m_events[event]);	// reset event

				accepted_sockets = *thread_data.p_accepted_sockets;
				if(accepted_sockets.size()>0)
				{
					for(int i=0;i<(int)accepted_sockets.size();i++)
					{
						sockets.AddNewClient(accepted_sockets[i]);
					}
					accepted_sockets.clear();
				}
				
				singleLock.Unlock();
			}


		}
/*
//			vector<VendorCount> *tmp_vendor_counts=sockets.ReturnVendorCounts();

			CSingleLock singleLock(&critical_section);
			singleLock.Lock();
			if(singleLock.IsLocked())
			{
				WSAResetEvent(sockets.m_events[event]);	// reset event

				// Do nothing else

				singleLock.Unlock();
			}

//			PostMessage(hwnd,WM_VENDOR_COUNTS_READY,(WPARAM)tmp_vendor_counts,(LPARAM)0);
		}
		*/
		// Else it is a socket event
		if(event>3)
		{
			WSAResetEvent(sockets.m_events[event]);	// reset event

			int index=event-num_reserved_events;
			
			events=sockets.m_sockets[index].ReturnNetworkEvents();
			
			if(events.lNetworkEvents & FD_CONNECT)
			{
				sockets.m_sockets[index].OnConnect(events.iErrorCode[FD_CONNECT_BIT]);
			}
			if(events.lNetworkEvents & FD_READ)
			{
				while (sockets.m_sockets[index].OnReceive(events.iErrorCode[FD_READ_BIT]));
			}
			if(events.lNetworkEvents & FD_WRITE)
			{
				sockets.m_sockets[index].OnSend(events.iErrorCode[FD_WRITE_BIT]);
			}
			if(events.lNetworkEvents & FD_CLOSE)
			{
				sockets.m_sockets[index].OnClose(events.iErrorCode[FD_CLOSE_BIT]);
			}
			if(events.lNetworkEvents & FD_ACCEPT)
			{
				sockets.m_sockets[index].OnAccept(events.iErrorCode[FD_ACCEPT_BIT]);
			}
		}
	}
	TRACE("Terminating ConnectionModuleThreadProc\n");
	return 0;	// exit the thread
}