CDownload* CDownloads::Add(CQueryHit* pHit, BOOL bAddToHead)
{
	CSingleLock pLock( &Transfers.m_pSection, TRUE );
	
	CDownload* pDownload = NULL;
	
	if ( pDownload == NULL && pHit->m_bSHA1 )
		pDownload = FindBySHA1( &pHit->m_pSHA1 );
	if ( pDownload == NULL && pHit->m_bTiger )
		pDownload = FindByTiger( &pHit->m_pTiger );
	if ( pDownload == NULL && pHit->m_bED2K )
		pDownload = FindByED2K( &pHit->m_pED2K );
	
	if ( pDownload != NULL )
	{
		theApp.Message( MSG_DOWNLOAD, IDS_DOWNLOAD_ALREADY, (LPCTSTR)pHit->m_sName );
		
		pDownload->AddSourceHit( pHit );
		pDownload->Resume();
	}
	else
	{
		pDownload = new CDownload();
		pDownload->AddSourceHit( pHit, TRUE );

		if ( bAddToHead ) m_pList.AddHead( pDownload );
		else m_pList.AddTail( pDownload );
		
		theApp.Message( MSG_DOWNLOAD, IDS_DOWNLOAD_ADDED,
			(LPCTSTR)pDownload->GetDisplayName(), pDownload->GetSourceCount() );

		if( pDownload->m_bSHA1 ) pDownload->m_bSHA1Trusted = TRUE;
		else if( pDownload->m_bED2K ) pDownload->m_bED2KTrusted = TRUE;
	}

	pHit->m_bDownload = TRUE;
	
	DownloadGroups.Link( pDownload );
	Transfers.StartThread();

	if ( ( (pDownload->GetSourceCount() == 0 ) || ( pDownload->m_bED2K && ! pDownload->m_bSHA1 ) ) 
	 &&( (GetTryingCount() < Settings.Downloads.MaxFiles ) || ( bAddToHead ) ) )
	{
		pDownload->SetStartTimer();
	}
	
	
	return pDownload;
}
int CDownloads::GetCount(BOOL bActiveOnly) const
{
	if ( ! bActiveOnly ) return m_pList.GetCount();
	
	int nCount = 0;
	
	for ( POSITION pos = GetIterator() ; pos ; )
	{
		CDownload* pDownload = GetNext( pos );
		
		if ( ! pDownload->IsMoving() && ! pDownload->IsPaused() &&
			 pDownload->GetSourceCount( TRUE ) > 0 )
				nCount++;
	}
	
	return nCount;
}
CDownload* CDownloads::Add(CShareazaURL* pURL)
{
	if ( pURL->m_nAction != CShareazaURL::uriDownload &&
		 pURL->m_nAction != CShareazaURL::uriSource ) return NULL;
	
	CSingleLock pLock( &Transfers.m_pSection, TRUE );
	CDownload* pDownload = NULL;
	
	if ( pDownload == NULL && pURL->m_bSHA1 )
		pDownload = FindBySHA1( &pURL->m_pSHA1 );
	if ( pDownload == NULL && pURL->m_bTiger )
		pDownload = FindByTiger( &pURL->m_pTiger );
	if ( pDownload == NULL && pURL->m_bED2K )
		pDownload = FindByED2K( &pURL->m_pED2K );
	if ( pDownload == NULL && pURL->m_bBTH )
		pDownload = FindByBTH( &pURL->m_pBTH );
	
	if ( pDownload != NULL )
	{
		theApp.Message( MSG_DOWNLOAD, IDS_DOWNLOAD_ALREADY,
			(LPCTSTR)pDownload->GetDisplayName() );
		
		if ( pURL->m_sURL.GetLength() ) pDownload->AddSourceURLs( pURL->m_sURL, FALSE );
		
		return pDownload;
	}
	
	pDownload = new CDownload();
	
	if ( pURL->m_bSHA1 )
	{
		pDownload->m_bSHA1			= TRUE;
		pDownload->m_pSHA1			= pURL->m_pSHA1;
		pDownload->m_bSHA1Trusted	= TRUE;
	}
	if ( pURL->m_bTiger )
	{
		pDownload->m_bTiger			= TRUE;
		pDownload->m_pTiger			= pURL->m_pTiger;
		pDownload->m_bTigerTrusted	= TRUE;
	}
	if ( pURL->m_bMD5 )
	{
		pDownload->m_bMD5			= TRUE;
		pDownload->m_pMD5			= pURL->m_pMD5;
		pDownload->m_bMD5Trusted	= TRUE;
	}
	if ( pURL->m_bED2K )
	{
		pDownload->m_bED2K			= TRUE;
		pDownload->m_pED2K			= pURL->m_pED2K;
		pDownload->m_bED2KTrusted	= TRUE;
		pDownload->Share( TRUE );
	}
	if ( pURL->m_bBTH )
	{
		pDownload->m_bBTH			= TRUE;
		pDownload->m_pBTH			= pURL->m_pBTH;
		pDownload->m_bBTHTrusted	= TRUE;
		pDownload->Share( TRUE );
	}
	
	if ( pURL->m_sName.GetLength() )
	{
		pDownload->m_sRemoteName = pURL->m_sName;
	}
	
	if ( pURL->m_bSize )
	{
		pDownload->m_nSize = pURL->m_nSize;
	}
	
	if ( pURL->m_sURL.GetLength() )
	{
		if ( ! pDownload->AddSourceURLs( pURL->m_sURL, FALSE ) )
		{
			if ( pURL->m_nAction == CShareazaURL::uriSource )
			{
				delete pDownload;
				return NULL;
			}
		}
	}
	
	pDownload->SetTorrent( pURL->m_pTorrent );
	
	m_pList.AddTail( pDownload );
	
	theApp.Message( MSG_DOWNLOAD, IDS_DOWNLOAD_ADDED,
		(LPCTSTR)pDownload->GetDisplayName(), pDownload->GetSourceCount() );
	
	if( (  pDownload->m_bBTH && ( GetTryingCount(TRUE)  < Settings.BitTorrent.DownloadTorrents ) ) ||
		( !pDownload->m_bBTH && ( GetTryingCount(FALSE) < Settings.Downloads.MaxFiles ) ) )
	{
		pDownload->SetStartTimer();
		if ( pURL->m_nAction != CShareazaURL::uriSource )
			pDownload->FindMoreSources();
	}
	
	DownloadGroups.Link( pDownload );
	Transfers.StartThread();
	
	return pDownload;
}
CDownload* CDownloads::Add(CMatchFile* pFile, BOOL bAddToHead)
{
	CSingleLock pLock( &Transfers.m_pSection, TRUE );
	
	CDownload* pDownload = NULL;
	
	if ( pDownload == NULL && pFile->m_bSHA1 )
		pDownload = FindBySHA1( &pFile->m_pSHA1 );
	if ( pDownload == NULL && pFile->m_bTiger )
		pDownload = FindByTiger( &pFile->m_pTiger );
	if ( pDownload == NULL && pFile->m_bED2K )
		pDownload = FindByED2K( &pFile->m_pED2K );
	
	if ( pDownload != NULL )
	{
		theApp.Message( MSG_DOWNLOAD, IDS_DOWNLOAD_ALREADY, (LPCTSTR)pFile->m_pHits->m_sName );
		
		for ( CQueryHit* pHit = pFile->m_pHits ; pHit ; pHit = pHit->m_pNext )
		{
			pDownload->AddSourceHit( pHit );

			// Send any reviews to the download, so they can be viewed later
			if ( pHit->m_nRating || ! pHit->m_sComments.IsEmpty() )
			{
				pDownload->AddReview( &pHit->m_pAddress, 2, pHit->m_nRating, pHit->m_sNick, pHit->m_sComments );
			}
		}
		
		pDownload->Resume();
	}
	else
	{
		pDownload = new CDownload();
		if ( bAddToHead ) m_pList.AddHead( pDownload );
		else m_pList.AddTail( pDownload );
		
		if ( pFile->m_pBest != NULL )
		{
			pDownload->AddSourceHit( pFile->m_pBest, TRUE );
		}
		
		for ( CQueryHit* pHit = pFile->m_pHits ; pHit ; pHit = pHit->m_pNext )
		{
			if ( pHit != pFile->m_pBest )
			{
				pDownload->AddSourceHit( pHit, TRUE );
			}

			// Send any reviews to the download, so they can be viewed later
			if ( pHit->m_nRating || ! pHit->m_sComments.IsEmpty() )
			{
				pDownload->AddReview( &pHit->m_pAddress, 2, pHit->m_nRating, pHit->m_sNick, pHit->m_sComments );
			}
		}
		
		theApp.Message( MSG_DOWNLOAD, IDS_DOWNLOAD_ADDED,
			(LPCTSTR)pDownload->GetDisplayName(), pDownload->GetSourceCount() );

		if( pDownload->m_bSHA1 ) pDownload->m_bSHA1Trusted = TRUE;
		else if( pDownload->m_bED2K ) pDownload->m_bED2KTrusted = TRUE;
	}
	
	pFile->m_bDownload = TRUE;
	
	DownloadGroups.Link( pDownload );
	Transfers.StartThread();
	
	if ( ( (pDownload->GetSourceCount() == 0 ) ||
		   ( pDownload->m_bED2K && ! pDownload->m_bSHA1 )) &&
		   (GetTryingCount() < Settings.Downloads.MaxFiles ) )
	{
		pDownload->FindMoreSources();
		pDownload->SetStartTimer();
	}
	
	return pDownload;
}