/***************************************************************************
 *   Copyright (C) 2005 by xavier helluy   *
 *   xavier.helluy@web.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.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Steet, Fifth Floor, Boston, MA 02110-1301, USA.             *
 ***************************************************************************/
#include <kdebug.h>

#include "serverclient.h"


ServerClient::ServerClient()
{
}

ServerClient::~ServerClient()
{
}

bool 	ServerClient::getSignal(QString  str)
{
	QByteArray tmpr;
	readBlockFromSocket(tmpr);
	QString result;
	MarshallingHelper::undoIt(tmpr , result);
	if (! (result == str ) )
	{
		kdDebug() << "ServerClient::getSignal(). Got BAD SIGNAL " << str << " |" 
				<< result << endl;
		return FALSE;
	}
	kdDebug() << "ServerClient::getSignal(). Got GOOD SIGNAL " << str << " |" 
			<< result << endl;
	return TRUE;
}

int 	ServerClient::sendSignal(QString  str)
{
	QByteArray writeData;
	MarshallingHelper::doIt(writeData , str);
	writeBlockToSocket( writeData);
	kdDebug() << "ServerClient::sendSignal() " << str << endl;
	return 1;
}


int  ServerClient::readBlockFromSocket( )
{
	char  Data[100];
	int read = m_socket->readBlock(Data,sizeof(Data));
	return read;
}

int  ServerClient::readBlockFromSocket(  QByteArray &dataArray )
{
	char  Data[100];
	int read = m_socket->readBlock(Data,sizeof(Data));
	QDataStream in(dataArray , IO_WriteOnly);
	in.writeRawBytes(Data, read);
	return read;
}

int  ServerClient::readBlockFromSocket(  QByteArray &dataArray , const int & BlockLength)
{
	//FIXME : one should check for the buffer size.
	char  Data[BlockLength];
	int read = m_socket->readBlock(Data,BlockLength);
	QDataStream in(dataArray , IO_WriteOnly);
	in.writeRawBytes(Data, read);  // FIXME : use sizeof(Data) is safer
	while (read < BlockLength)
	{	
		read += m_socket->readBlock(Data , BlockLength);
		in.writeRawBytes(Data, sizeof(Data));  
		if (read >= BlockLength)
		{	
			kdDebug() << "ServerClient::readBlockFromSocket().Error ReadBlock read to much data" << endl;
			return -1;
		}
	}
	
	return BlockLength;
}

  int  ServerClient::writeBlockToSocket(  const QByteArray &dataArray )
{
	//FIXME : one should check for the buffer size.
	int wrote = m_socket->writeBlock(dataArray.data(), dataArray.size());
	while (wrote < (int)dataArray.size())
		
		wrote += m_socket->writeBlock(dataArray.data() + wrote, dataArray.size() - wrote);
	return wrote;
}

int  ServerClient::writeBlockToSocket( const QByteArray &dataArray ,
				   const int & BlockLength , const uint & QByteArrayStartPosition)
{
	//FIXME : one should check for the buffer size.
	int wrote = m_socket->writeBlock(dataArray.data() + QByteArrayStartPosition , BlockLength);
	while (wrote < (int)BlockLength)
		
		wrote += m_socket->writeBlock(dataArray.data()  + QByteArrayStartPosition + wrote, BlockLength - wrote);
	return wrote;

}


int  ServerClient::BigRawDataServerToCLient( const QByteArray &dataArray ,
					 const int & BufferSize)
{
	int ArraySize           = dataArray.size();  
	int NumTransactions     = ArraySize / BufferSize;
	int LastTransactionSize = ArraySize % BufferSize ;
	kdDebug() << "ServerClient::BigRawDataServerToCLient() DATA: " << ArraySize << " "
			<< NumTransactions << " " << LastTransactionSize << " " 
			<< BufferSize << endl;
	
	//send size of rawdata
	QByteArray tmpArray;
	
	MarshallingHelper::doIt(tmpArray , ArraySize );
	writeBlockToSocket(tmpArray);

	getSignal("I got the data");
	
	//send number of transactions
	MarshallingHelper::doIt(tmpArray ,NumTransactions );
	writeBlockToSocket(tmpArray);
	
	getSignal("I got the data");
	
	//send size of Last Transaction 
	MarshallingHelper::doIt(tmpArray , LastTransactionSize);
	writeBlockToSocket(tmpArray);
	
	getSignal("I got the data");
	
	//send BlockSize
	MarshallingHelper::doIt(tmpArray , BufferSize);
	writeBlockToSocket(tmpArray);
	
	getSignal("I got the data");
	
	//send RawData 
	for (int k= 0;k< NumTransactions;k++)
	{
		writeBlockToSocket(dataArray , BufferSize , k * BufferSize );
		getSignal("I got the data");

	}
	if ( LastTransactionSize >0)
	{
		writeBlockToSocket( dataArray ,LastTransactionSize , NumTransactions * BufferSize );
		getSignal("I got the data");
	}
	return 1;
}

int  ServerClient::BigRawDataClientToServer(  QByteArray &res)
					    
{
	kdDebug() << "ServerClient::BigRawDataClientToServer()" << endl;
	int ArraySize           ;
	int NumTransactions     ;
	int LastTransactionSize ;
	int BufferSize          ;
	//Get size of rawdata : at the beginning I don't know the size but hope the best
	QByteArray getArray ; 
	readBlockFromSocket( getArray);

	MarshallingHelper::undoIt(getArray, ArraySize );
	sendSignal("I got the data");
	
	//Get number of transactions
	readBlockFromSocket( getArray);
	MarshallingHelper::undoIt(getArray, NumTransactions);
	sendSignal("I got the data");

	//Get size of Last Transaction 
	readBlockFromSocket( getArray);
	MarshallingHelper::undoIt(getArray,  LastTransactionSize);
	sendSignal("I got the data");

	//Get BlockSize
	readBlockFromSocket( getArray);
	MarshallingHelper::undoIt(getArray, BufferSize);
	sendSignal("I got the data");

	//Get RawData 
	QByteArray  tmpA;
//	QByteArray  res;
	QByteArray chunk;
	MarshallingHelper::doIt(tmpA,(QString) "Continue");
	QDataStream in(res , IO_WriteOnly);

	for (int k= 0;k< NumTransactions;k++)
	{
		readBlockFromSocket( chunk , BufferSize);
		in.writeRawBytes(chunk , chunk.size());
		//in <<  chunk;
		sendSignal("I got the data");
	}
	if ( LastTransactionSize >0)
	{
		chunk.resize(0);
		readBlockFromSocket( chunk ,LastTransactionSize  );
		in.writeRawBytes(chunk , LastTransactionSize);
		sendSignal("I got the data");
	}
	return 1;
} 



