#include "KartenLeser.h"
#include <Datei.h>
#include "AccountHistorieDaten.h"
#include <Klient.h>

// Inhalt der KartenLeser Klasse aus KartenLeser.h
// Konstruktor 
KartenLeser::KartenLeser( int karteId, InformationServer *is )
{
	pfad = new Text( "" );
    *pfad += karteId;
    while( DateiExistiert( pfad->getText() ) )
        pfad->append( "_" );
    ref = 1;
    Text ip;
    int port;
    is->zDB()->getKartenServerPortIp( 0, karteId, &port, &ip );
    Klient *klient = new Klient();
    unsigned char key[ 20 ] = { 24, 15, 53, 87, 38, 73, 154, 38, 246, 90, 39, 133, 11, 199, 22, 80, 26, 132, 95, 54 };
    klient->setSendeKey( (char*)key, 20 );
    klient->setEmpfangKey( (char*)key, 20 );
    if( !klient->verbinde( (unsigned short)port, ip ) )
    {
        klient = klient->release();
        return;
    }
    klient->sendeEncrypted( "\x7", 1 );
    char ret = 0;
    klient->getNachrichtEncrypted( &ret, 1 );
    if( ret == 1 )
    {
        klient->sendeEncrypted( (char*)&karteId, 4 );
        klient->getNachrichtEncrypted( &ret, 1 );
        if( ret == 1 )
        {
            int anz = 0;
            klient->getNachrichtEncrypted( (char*)&anz, 4 );
            for( int i = 0; i < anz; i++ )
            {
                unsigned char len = 0;
                klient->getNachrichtEncrypted( (char*)&len, 1 );
                if( !len )
                    continue;
                char *pfa = new char[ len + 1 ];
                pfa[ (int)len ] = 0;
                klient->getNachrichtEncrypted( pfa, len );
                __int64 size = 0;
                klient->getNachrichtEncrypted( (char*)&size, 8 );
                char *buffer = new char[ 2048 ];
                Text pf = pfad->getText();
                pf += "/";
                pf += pfa;
                delete[] pfa;
                Datei d;
                d.setDatei( pf );
                d.erstellen();
                d.open( Datei::Style::schreiben );
                while( size )
                {
                    int l = size >= 2048 ? 2048 : (int)size;
                    klient->getNachricht( buffer, l );
                    d.schreibe( buffer, l );
                    size -= l;
                }
                d.close();
                delete[] buffer;
            }
        }
    }
    if( ret == 3 )
    {
        unsigned char byte = 0;
        klient->getNachrichtEncrypted( (char*)&byte, 1 );
        char *f = new char[ byte + 1 ];
        f[ (int)byte ] = 0;
        klient->getNachrichtEncrypted( f, byte );
        delete[] f;
    }
    klient->sendeEncrypted( "\3", 1 );
    klient->getNachrichtEncrypted( &ret, 1 );
    klient->trenne();
    klient->release();
}

// Destruktor
KartenLeser::~KartenLeser()
{
    DateiRemove( pfad );
}

// nicht constant
bool KartenLeser::ladeSpielerTeamStruktur( SpielerTeamStruktur *sts )
{
	if( !pfad->getLength() )
		return 0;
	Text *pf = new Text( pfad->getText() );
	pf->append( "/sts.ltgd" );
	Datei *datei = new Datei();
	datei->setDatei( pf );
	if( !datei->existiert() || datei->istOrdner() )
	{
		datei->release();
		return 0;
	}
	datei->open( Datei::Style::lesen );
	datei->lese( (char*)&sts->spielerAnzahl, 4 );
	datei->lese( (char*)&sts->teamAnzahl, 4 );
	if( sts->spielerFarbe )
		sts->spielerFarbe->release();
	sts->spielerFarbe = new Array< int >();
	for( int i = 0; i < sts->spielerAnzahl; i++ )
	{
		int farbe = 0;
		datei->lese( (char*)&farbe, 4 );
		sts->spielerFarbe->set( farbe, i );
	}
	if( sts->teamFarbe )
		sts->teamFarbe->release();
	sts->teamFarbe = new Array< int >();
	for( int i = 0; i < sts->teamAnzahl; i++ )
	{
		int farbe = 0;
		datei->lese( (char*)&farbe, 4 );
		sts->teamFarbe->set( farbe, i );
	}
	if( sts->teamName )
		sts->teamName->release();
	sts->teamName = new RCArray< Text >();
	for( int i = 0; i < sts->teamAnzahl; i++ )
	{
		unsigned char len = 0;
		datei->lese( (char*)&len, 1 );
		char *txt = new char[ len + 1 ];
		txt[ (int)len ] = 0;
		datei->lese( txt, len );
		Text *name = new Text( txt );
		delete[] txt;
		sts->teamName->set( name, i );
	}
	if( sts->teamSize )
		sts->teamSize->release();
	sts->teamSize = new Array< int >();
	for( int i = 0; i < sts->teamAnzahl; i++ )
	{
		int size = 0;
		datei->lese( (char*)&size, 4 );
		sts->teamSize->set( size, i );
	}
	datei->close();
	datei->release();
	return 1;
}

// constant
Text *KartenLeser::getPfad() const
{
	return pfad ? pfad->getThis() : 0;
}

Text *KartenLeser::zPfad() const
{
	return pfad;
}

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

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