#include "EditorKlient.h"
#include <Klient.h>
#include "../Karte/EditorKarte.h"

using namespace Network;
using namespace Editor;

SpielerTeamStruktur::SpielerTeamStruktur()
{
    spielerAnzahl = 0;
    teamAnzahl = 0;
    spielerFarbe = new Array< int >();
    teamFarbe = new Array< int >();
    teamName = new RCArray< Text >();
    teamSize = new Array< int >();
    ref = 1;
}

SpielerTeamStruktur::~SpielerTeamStruktur()
{
    spielerFarbe->release();
    teamFarbe->release();
    teamName->release();
    teamSize->release();
}

SpielerTeamStrukturV *SpielerTeamStruktur::getThis()
{
    ref++;
    return this;
}

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


// Inhalt der EditorKlient Klasse aus EditorKlient.h
// Konstruktor
//  k: Der zu verwendende Klient
EditorKlient::EditorKlient( KSGClient::EditorServerClient *k )
{
    klient = k;
    ref = 1;
}

// Destruktor
EditorKlient::~EditorKlient()
{
    klient->release();
}

// Initialisiert den Server
//  return: 1, falls erfolgreich
//          2, falls bereits eine Sitzung existiert
//          0, sonnst
int EditorKlient::init()
{
    Network::Klient *k = klient->beginEditorMessage();
    if( !k )
    {
        error = klient->getLetzterFehler();
        return 0;
    }
    error = "";
    k->sendeEncrypted( "\x0", 1 );
    char ret;
    k->getNachrichtEncrypted( &ret, 1 );
    if( ret == 1 )
        k->getNachrichtEncrypted( &ret, 1 );
    if( ret == 3 )
    {
        unsigned char l = 0;
        k->getNachrichtEncrypted( (char*)&l, 1 );
        char *err = new char[ l + 1 ];
        err[ l ] = 0;
        k->getNachrichtEncrypted( err, l );
        error = err;
        delete[] err;
        ret = 0;
    }
    klient->endEditorMessage();
    return ret;
}

// Verwirft die vorhandene Sitzung und erstellt eine neue
bool EditorKlient::sitzungVerwerfen()
{
    Network::Klient *k = klient->beginEditorMessage();
    if( !k )
    {
        error = klient->getLetzterFehler();
        return 0;
    }
    error = "";
    char ret;
    k->sendeEncrypted( "\x1", 1 );
    k->getNachrichtEncrypted( &ret, 1 );
    if( ret == 3 )
    {
        unsigned char l = 0;
        k->getNachrichtEncrypted( (char*)&l, 1 );
        char *err = new char[ l + 1 ];
        err[ l ] = 0;
        k->getNachrichtEncrypted( err, l );
        error = err;
        delete[] err;
        ret = 0;
    }
    klient->endEditorMessage();
    return ret == 1;
}

// Speichert Sitzung und beendet Editor
bool EditorKlient::sitzungBeenden()
{
    Network::Klient *k = klient->beginEditorMessage();
    if( !k )
    {
        error = klient->getLetzterFehler();
        return 0;
    }
    error = "";
    char ret;
    k->sendeEncrypted( "\x2", 1 );
    k->getNachrichtEncrypted( &ret, 1 );
    if( ret == 3 )
    {
        unsigned char l = 0;
        k->getNachrichtEncrypted( (char*)&l, 1 );
        char *err = new char[ l + 1 ];
        err[ l ] = 0;
        k->getNachrichtEncrypted( err, l );
        error = err;
        delete[] err;
        ret = 0;
    }
    klient->endEditorMessage();
    return ret == 1;
}

bool EditorKlient::saveTeam( const TeamDaten *team )
{
    Network::Klient *k = klient->beginEditorMessage();
    if( !k )
    {
        error = klient->getLetzterFehler();
        return 0;
    }
    error = "";
    char ret;
    k->sendeEncrypted( "\x7", 1 );
    k->getNachrichtEncrypted( &ret, 1 );
    if( ret == 1 )
    {
        k->sendeEncrypted( (char*)&team->id, 4 );
        k->sendeEncrypted( (char*)&team->maxPunkte, 4 );
        k->sendeEncrypted( (char*)&team->beschleunigung, 8 );
        k->sendeEncrypted( (char*)&team->maxStabilit�t, 4 );
        k->sendeEncrypted( (char*)&team->maxEnergie, 4 );
        k->sendeEncrypted( (char*)&team->reparatur, 8 );
        k->sendeEncrypted( (char*)&team->akkuLeistung, 8 );
        k->sendeEncrypted( (char*)&team->laserIntensit�t, 4 );
        k->sendeEncrypted( (char*)&team->laserEffizienz, 4 );
        k->sendeEncrypted( (char*)&team->laserTempo, 4 );
        k->sendeEncrypted( (char*)&team->wendigkeit, 8 );
        k->sendeEncrypted( (char*)&team->antriebEffizienz, 8 );
        k->sendeEncrypted( (char*)&team->energieSchild, 8 );
        k->sendeEncrypted( (char*)&team->energieSchildEffizienz, 8 );
        k->sendeEncrypted( (char*)&team->punkte, 4 );
        k->getNachrichtEncrypted( &ret, 1 );
    }
    if( ret == 3 )
    {
        unsigned char l = 0;
        k->getNachrichtEncrypted( (char*)&l, 1 );
        char *err = new char[ l + 1 ];
        err[ l ] = 0;
        k->getNachrichtEncrypted( err, l );
        error = err;
        delete[] err;
        ret = 0;
    }
    klient->endEditorMessage();
    return ret == 1;
}

bool EditorKlient::saveSpieler( const SpielerDaten *spieler )
{
    Network::Klient *k = klient->beginEditorMessage();
    if( !k )
    {
        error = klient->getLetzterFehler();
        return 0;
    }
    error = "";
    char ret;
    k->sendeEncrypted( "\x6", 1 );
    k->getNachrichtEncrypted( &ret, 1 );
    if( ret == 1 )
    {
        k->sendeEncrypted( (char*)&spieler->id, 4 );
        k->sendeEncrypted( (char*)&spieler->pos.x, 4 );
        k->sendeEncrypted( (char*)&spieler->pos.y, 4 );
        k->sendeEncrypted( (char*)&spieler->rot, 8 );
        k->sendeEncrypted( (char*)&spieler->beschleunigung, 8 );
        k->sendeEncrypted( (char*)&spieler->maxStabilit�t, 4 );
        k->sendeEncrypted( (char*)&spieler->maxEnergie, 4 );
        k->sendeEncrypted( (char*)&spieler->reparatur, 8 );
        k->sendeEncrypted( (char*)&spieler->akkuLeistung, 8 );
        k->sendeEncrypted( (char*)&spieler->laserIntensit�t, 4 );
        k->sendeEncrypted( (char*)&spieler->laserEffizienz, 4 );
        k->sendeEncrypted( (char*)&spieler->laserTempo, 4 );
        k->sendeEncrypted( (char*)&spieler->wendigkeit, 8 );
        k->sendeEncrypted( (char*)&spieler->antriebEffizienz, 8 );
        k->sendeEncrypted( (char*)&spieler->energieSchild, 8 );
        k->sendeEncrypted( (char*)&spieler->energieSchildEffizienz, 8 );
        k->sendeEncrypted( (char*)&spieler->netzwerk, 4 );
        k->sendeEncrypted( (char*)&spieler->skillPunkte, 4 );
        k->sendeEncrypted( (char*)&spieler->m2d, 4 );
        k->sendeEncrypted( (char*)&spieler->bild, 4 );
        k->getNachrichtEncrypted( &ret, 1 );
    }
    if( ret == 3 )
    {
        unsigned char l = 0;
        k->getNachrichtEncrypted( (char*)&l, 1 );
        char *err = new char[ l + 1 ];
        err[ l ] = 0;
        k->getNachrichtEncrypted( err, l );
        error = err;
        delete[] err;
        ret = 0;
    }
    klient->endEditorMessage();
    return ret == 1;
}

bool EditorKlient::saveObjekt( const ObjektDaten *objekt )
{
    Network::Klient *k = klient->beginEditorMessage();
    if( !k )
    {
        error = klient->getLetzterFehler();
        return 0;
    }
    error = "";
    char ret;
    k->sendeEncrypted( "\x8", 1 );
    k->getNachrichtEncrypted( &ret, 1 );
    if( ret == 1 )
    {
        k->sendeEncrypted( (char*)&objekt->pos.x, 4 );
        k->sendeEncrypted( (char*)&objekt->pos.y, 4 );
        k->sendeEncrypted( (char*)&objekt->id, 4 );
        k->sendeEncrypted( (char*)&objekt->m2d, 4 );
        k->sendeEncrypted( (char*)&objekt->bild, 4 );
        k->sendeEncrypted( (char*)&objekt->style, 4 );
        k->sendeEncrypted( (char*)&objekt->maxStabilit�t, 4 );
        k->sendeEncrypted( (char*)&objekt->maxEnergie, 4 );
        k->sendeEncrypted( (char*)&objekt->energieRadius, 4 );
        k->sendeEncrypted( (char*)&objekt->reparatur, 8 );
        k->sendeEncrypted( (char*)&objekt->akkuLeistung, 8 );
        k->sendeEncrypted( (char*)&objekt->team, 1 );
        k->getNachrichtEncrypted( &ret, 1 );
    }
    if( ret == 3 )
    {
        unsigned char l = 0;
        k->getNachrichtEncrypted( (char*)&l, 1 );
        char *err = new char[ l + 1 ];
        err[ l ] = 0;
        k->getNachrichtEncrypted( err, l );
        error = err;
        delete[] err;
        ret = 0;
    }
    klient->endEditorMessage();
    return ret == 1;
}

bool EditorKlient::deleteObjekt( int id )
{
    Network::Klient *k = klient->beginEditorMessage();
    if( !k )
    {
        error = klient->getLetzterFehler();
        return 0;
    }
    error = "";
    char ret;
    k->sendeEncrypted( "\x9", 1 );
    k->getNachrichtEncrypted( &ret, 1 );
    if( ret == 1 )
    {
        k->sendeEncrypted( (char*)&id, 4 );
        k->getNachrichtEncrypted( &ret, 1 );
    }
    if( ret == 3 )
    {
        unsigned char l = 0;
        k->getNachrichtEncrypted( (char*)&l, 1 );
        char *err = new char[ l + 1 ];
        err[ l ] = 0;
        k->getNachrichtEncrypted( err, l );
        error = err;
        delete[] err;
        ret = 0;
    }
    klient->endEditorMessage();
    return ret == 1;
}

bool EditorKlient::loadSpieler( Array< SpielerDaten* > &spieler )
{
    Network::Klient *k = klient->beginEditorMessage();
    if( !k )
    {
        error = klient->getLetzterFehler();
        return 0;
    }
    error = "";
    char ret;
    k->sendeEncrypted( "\x3", 1 );
    k->getNachrichtEncrypted( &ret, 1 );
    if( ret == 1 )
    {
        int anz = 0;
        k->getNachrichtEncrypted( (char*)&anz, 4 );
        for( int i = 0; i < anz; i++ )
        {
            SpielerDaten *player = new SpielerDaten();
            k->getNachrichtEncrypted( (char*)&player->id, 4 );
            k->getNachrichtEncrypted( (char*)&player->pos.x, 4 );
            k->getNachrichtEncrypted( (char*)&player->pos.y, 4 );
            k->getNachrichtEncrypted( (char*)&player->rot, 8 );
            k->getNachrichtEncrypted( (char*)&player->beschleunigung, 8 );
            k->getNachrichtEncrypted( (char*)&player->maxStabilit�t, 4 );
            k->getNachrichtEncrypted( (char*)&player->maxEnergie, 4 );
            k->getNachrichtEncrypted( (char*)&player->reparatur, 8 );
            k->getNachrichtEncrypted( (char*)&player->akkuLeistung, 8 );
            k->getNachrichtEncrypted( (char*)&player->laserIntensit�t, 4 );
            k->getNachrichtEncrypted( (char*)&player->laserEffizienz, 4 );
            k->getNachrichtEncrypted( (char*)&player->laserTempo, 4 );
            k->getNachrichtEncrypted( (char*)&player->wendigkeit, 8 );
            k->getNachrichtEncrypted( (char*)&player->antriebEffizienz, 8 );
            k->getNachrichtEncrypted( (char*)&player->energieSchild, 8 );
            k->getNachrichtEncrypted( (char*)&player->energieSchildEffizienz, 8 );
            k->getNachrichtEncrypted( (char*)&player->netzwerk, 4 );
            k->getNachrichtEncrypted( (char*)&player->skillPunkte, 4 );
            k->getNachrichtEncrypted( (char*)&player->m2d, 4 );
            k->getNachrichtEncrypted( (char*)&player->bild, 4 );
            spieler.add( player );
        }
    }
    if( ret == 3 )
    {
        unsigned char l = 0;
        k->getNachrichtEncrypted( (char*)&l, 1 );
        char *err = new char[ l + 1 ];
        err[ l ] = 0;
        k->getNachrichtEncrypted( err, l );
        error = err;
        delete[] err;
        ret = 0;
    }
    klient->endEditorMessage();
    return ret == 1;
}

bool EditorKlient::loadTeams( Array< TeamDaten* > &teams )
{
    Network::Klient *k = klient->beginEditorMessage();
    if( !k )
    {
        error = klient->getLetzterFehler();
        return 0;
    }
    error = "";
    char ret;
    k->sendeEncrypted( "\x4", 1 );
    k->getNachrichtEncrypted( &ret, 1 );
    if( ret == 1 )
    {
        int anz = 0;
        k->getNachrichtEncrypted( (char*)&anz, 4 );
        for( int i = 0; i < anz; i++ )
        {
            TeamDaten *team = new TeamDaten();
            k->getNachrichtEncrypted( (char*)&team->id, 4 );
            k->getNachrichtEncrypted( (char*)&team->maxPunkte, 4 );
            k->getNachrichtEncrypted( (char*)&team->beschleunigung, 8 );
            k->getNachrichtEncrypted( (char*)&team->maxStabilit�t, 4 );
            k->getNachrichtEncrypted( (char*)&team->maxEnergie, 4 );
            k->getNachrichtEncrypted( (char*)&team->reparatur, 8 );
            k->getNachrichtEncrypted( (char*)&team->akkuLeistung, 8 );
            k->getNachrichtEncrypted( (char*)&team->laserIntensit�t, 4 );
            k->getNachrichtEncrypted( (char*)&team->laserEffizienz, 4 );
            k->getNachrichtEncrypted( (char*)&team->laserTempo, 4 );
            k->getNachrichtEncrypted( (char*)&team->wendigkeit, 8 );
            k->getNachrichtEncrypted( (char*)&team->antriebEffizienz, 8 );
            k->getNachrichtEncrypted( (char*)&team->energieSchild, 8 );
            k->getNachrichtEncrypted( (char*)&team->energieSchildEffizienz, 8 );
            k->getNachrichtEncrypted( (char*)&team->punkte, 4 );
            teams.add( team );
        }
    }
    if( ret == 3 )
    {
        unsigned char l = 0;
        k->getNachrichtEncrypted( (char*)&l, 1 );
        char *err = new char[ l + 1 ];
        err[ l ] = 0;
        k->getNachrichtEncrypted( err, l );
        error = err;
        delete[] err;
        ret = 0;
    }
    klient->endEditorMessage();
    return ret == 1;
}

bool EditorKlient::loadObjekte( Array< ObjektDaten* > &objekte )
{
    Network::Klient *k = klient->beginEditorMessage();
    if( !k )
    {
        error = klient->getLetzterFehler();
        return 0;
    }
    error = "";
    char ret;
    k->sendeEncrypted( "\x5", 1 );
    k->getNachrichtEncrypted( &ret, 1 );
    if( ret == 1 )
    {
        int anz = 0;
        k->getNachrichtEncrypted( (char*)&anz, 4 );
        for( int i = 0; i < anz; i++ )
        {
            ObjektDaten *objekt = new ObjektDaten();
            k->getNachrichtEncrypted( (char*)&objekt->pos.x, 4 );
            k->getNachrichtEncrypted( (char*)&objekt->pos.y, 4 );
            k->getNachrichtEncrypted( (char*)&objekt->id, 4 );
            k->getNachrichtEncrypted( (char*)&objekt->m2d, 4 );
            k->getNachrichtEncrypted( (char*)&objekt->bild, 4 );
            k->getNachrichtEncrypted( (char*)&objekt->style, 4 );
            k->getNachrichtEncrypted( (char*)&objekt->maxStabilit�t, 4 );
            k->getNachrichtEncrypted( (char*)&objekt->maxEnergie, 4 );
            k->getNachrichtEncrypted( (char*)&objekt->energieRadius, 4 );
            k->getNachrichtEncrypted( (char*)&objekt->reparatur, 8 );
            k->getNachrichtEncrypted( (char*)&objekt->akkuLeistung, 8 );
            k->getNachrichtEncrypted( (char*)&objekt->team, 1 );
            objekte.add( objekt );
        }
    }
    if( ret == 3 )
    {
        unsigned char l = 0;
        k->getNachrichtEncrypted( (char*)&l, 1 );
        char *err = new char[ l + 1 ];
        err[ l ] = 0;
        k->getNachrichtEncrypted( err, l );
        error = err;
        delete[] err;
        ret = 0;
    }
    klient->endEditorMessage();
    return ret == 1;
}

// L�dt die Spieler Team Struktur
bool EditorKlient::getSpielerTeamStruktur( SpielerTeamStrukturV *sts )
{
    return klient->ladeTeamDaten( sts );
}

// Gibt den Letzten Fehler zur�ck
char *EditorKlient::getLastError() const
{
    return error;
}

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

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