/***************************************************************************
                          csearchsocket.cpp  -  description
                             -------------------
    begin                : Thu May 27 2004
    copyright            : (C) 2004 by Mathias Küster
    email                : mathen@users.berlios.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "csearchsocket.h"

#include <stdio.h>

#include "dclib.h"
#include "core/cstring.h"
#include "cmessagehandler.h"

#include "dcobject.h"

/** */
CSearchSocket::CSearchSocket() : CSocket( estUDP )
{
	m_pCallback = 0;
	
	/*
	 * It's only for 1 packet but this is what
	 * is was when this was a CConnection.
	 */
	m_Buffer.SetSize(50*1024);
}

/** */
CSearchSocket::~CSearchSocket()
{
	SetCallBackFunction(0);
}

/** */
eConnectState CSearchSocket::Connect( CString Host, int Port, bool iAsync )
{
	m_SearchSocketMutex.Lock();
	
	const eConnectState res = CSocket::Connect( Host, Port, iAsync );
	
	m_SearchSocketMutex.UnLock();
	
	return res;
}

/** */
int CSearchSocket::Disconnect()
{
	m_SearchSocketMutex.Lock();
	
	const int res = CSocket::Disconnect();
	
	m_SearchSocketMutex.UnLock();
	
	return res;
}

/** */
void CSearchSocket::Receive( int maxpackets )
{
	m_SearchSocketMutex.Lock();
	
	int p, err, len;
	eDCMessage type;
	CDCMessage * Object;
	CMessageHandler * MessageHandler = 0;
	CString s;

	for ( int packets = 0; packets < maxpackets; ++packets )
	{
		len = Read( (char*)m_Buffer.Data(), m_Buffer.Size(), 0, 1 );
		
		if ( len <= 0 )
		{
			break;
		}
		
		s.Set( (const char*) m_Buffer.Data(), len );
		
		/* add '|' for parser, only old dclib did not terminate search results? */
		s += '|';
		
		/* add traffic control */
		CSocket::m_Traffic.AddTraffic(ettCONTROLRX,len);
		
		p = 0;
		Object = 0;
		
		if ( !MessageHandler )
		{
			MessageHandler = new CMessageHandler();
		}
		
		while( (type=MessageHandler->Parse(&s,p,&Object)) != DC_MESSAGE_PARSE_ERROR )
		{
			switch (type)
			{
				case DC_MESSAGE_SEARCHRESULT:
				{
					if ( Object )
					{
						((CMessageSearchResult*) Object)->m_sSrcIP = GetResolvedIP();
					}
					
					break;
				}
				
				default:
				{
					// remove message
					delete Object;
					Object = 0;
					break;
				}
			}
			
			if ( Object )
			{
				err = -1;
				
				if ( m_pCallback )
				{
					err = m_pCallback->notify( (CMessageSearchResult*) Object );
				}
				
				if ( err == -1 )
				{
					printf("CSearchSocket::HandleMessage: CallBack failed (state)...\n");
					delete Object;
				}
			}
		}
	}
	
	delete MessageHandler;
	
	m_SearchSocketMutex.UnLock();
}
