#include "SpielServerKlient.h"
#include <Datei.h>

// Inhalt der SpielServerKlient Klasse aus SpielServerKlient.h
// Konstruktor
SpielServerKlient::SpielServerKlient()
{
	k = new Klient();
	unsigned char key[ 20 ] = { 148, 52, 231, 50, 20, 138, 243, 178, 149, 24, 69, 60, 68, 116, 10, 161, 178, 148, 32, 212 };
	k->setSendeKey( (char*)key, 20 );
	k->setEmpfangKey( (char*)key, 20 );
	fehler = new Text();
	verbunden = 0;
	ref = 1;
}

// Destruktor
SpielServerKlient::~SpielServerKlient()
{
	if( verbunden )
		trenne();
	k->release();
	fehler->release();
}

// privat
bool SpielServerKlient::verbinde( short port, char *ip )
{
	if( verbunden )
		trenne();
	if( k->verbinde( port, ip ) )
	{
		verbunden = 1;
		return 1;
	}
	return 0;
}

bool SpielServerKlient::trenne()
{
	k->sendeEncrypted( "\3", 1 );
	char ret = 0;
	k->getNachrichtEncrypted( &ret, 1 );
	k->trenne();
	verbunden = 0;
	return 1;
}

// nicht constant
bool SpielServerKlient::downloadSpielHistorie( short port, char *ip, int spiel, char *gpf )
{
	if( !verbinde( port, ip ) )
	{
		fehler->setText( "Fehler beim verbinden mit Spiel Server." );
		return 0;
	}
	k->sendeEncrypted( "\xB", 1 );
	unsigned char ret = 0;
	k->getNachrichtEncrypted( (char*)&ret, 1 );
	if( ret == 1 )
	{
		k->sendeEncrypted( (char*)&spiel, 4 );
		k->getNachrichtEncrypted( (char*)&ret, 1 );
		if( ret == 1 )
		{
			Text *pfad = new Text( gpf );
			pfad->ersetzen( '\\', '/' );
			if( pfad->getText()[ pfad->getLength() - 1 ] != '/' )
				pfad->append( "/" );
			pfad->append( spiel );
			pfad->append( "/" );
			k->getNachrichtEncrypted( (char*)&ret, 1 );
			while( ret )
			{
				char *pf = new char[ ret + 1 ];
				pf[ (int)ret ] = 0;
				k->getNachrichtEncrypted( pf, ret );
				__int64 gr = 0;
				k->getNachrichtEncrypted( (char*)&gr, 8 );
				Datei *d = new Datei();
				d->setDatei( Text( pfad->getText() ) += pf );
				d->erstellen();
				d->open( Datei::Style::schreiben );
				char *bytes = new char[ 2048 ];
				while( gr )
				{
					short len = gr > 2048 ? 2048 : (short)gr;
					k->getNachricht( bytes, len );
					d->schreibe( bytes, len );
					gr -= len;
				}
				delete[] bytes;
				d->close();
				d->release();
				delete[] pf;
				k->getNachrichtEncrypted( (char*)&ret, 1 );
			}
			pfad->release();
		}
	}
	if( ret == 3 )
	{
		*fehler = "Fehler, Spielserver rückgabe: ";
		k->getNachrichtEncrypted( (char*)&ret, 1 );
		char *err = new char[ ret + 1 ];
		err[ (int)ret ] = 0;
		k->getNachrichtEncrypted( err, ret );
		*fehler += err;
		delete[] err;
		return 0;
	}
	return 1;
}

// constant
Text *SpielServerKlient::getLetzterFehler() const
{
	return fehler->getThis();
}

Text *SpielServerKlient::zLetzterFehler() const
{
	return fehler;
}

// Reference Counting
SpielServerKlient *SpielServerKlient::getThis()
{
	ref++;
	return this;
}

SpielServerKlient *SpielServerKlient::release()
{
	ref--;
	if( !ref )
		delete this;
	return 0;
}