#include "KartenEditor.h"
#include "../../../Global/Initialisierung.h"
#include "../../../Global/Variablen.h"
#include <KSGTDatei.h>

typedef EditorV*( *DllStart )( );

// Inhalt der KartenEditor Klasse aus KartenEditor.h
// Konstruktor
KartenEditor::KartenEditor( Schrift *schrift )
{
    this->schrift = schrift;
    karteRelease = initKnopf( 10, 10, 100, 20, schrift, Knopf::Style::Sichtbar, "Karte Release" );
    shopSeite = initKnopf( 120, 10, 100, 20, schrift, Knopf::Style::Sichtbar, "Shop Seite" );
    beschreibung = initKnopf( 230, 10, 100, 20, schrift, Knopf::Style::Sichtbar, "Beschreibung" );
    teams = initKnopf( 340, 10, 100, 20, schrift, Knopf::Style::Sichtbar, "Teams" );
    dateien = initKnopf( 450, 10, 100, 20, schrift, Knopf::Style::Sichtbar, "Dateien" );
    editor = initKnopf( 560, 10, 100, 20, schrift, Knopf::Style::Sichtbar, "Editor" );
    kaufHistorie = initKnopf( 670, 10, 100, 20, schrift, Knopf::Style::Sichtbar, "Kauf Historie" );
    beenden = initKnopf( 790, 10, 100, 20, schrift, Knopf::Style::Sichtbar, "Beenden" );
    laden = (Animation2D*)ladeAnimation->dublizieren();
    laden->setPosition( 425, 275 );
    laden->setSichtbar( 0 );
    tickVal = 0;
    jetzt = 0;
    releaseF = 0;
    shopSeiteF = 0;
    beschreibungF = 0;
    teamsF = 0;
    dateienF = 0;
    alpha = 0;
    alpha2 = 0;
    sichtbar = 0;
    editorDll = 0;
    editorF = 0;
    dllName = "";
    ref = 1;
}

// Destruktor
KartenEditor::~KartenEditor()
{
    if( run )
    {
        warteAufThread( 5000 );
        if( run )
            ende();
    }
    schrift->release();
    karteRelease->release();
    shopSeite->release();
    beschreibung->release();
    teams->release();
    dateien->release();
    editor->release();
    kaufHistorie->release();
    beenden->release();
    laden->release();
    if( releaseF )
        releaseF->release();
    if( shopSeiteF )
        shopSeiteF->release();
    if( beschreibungF )
        beschreibungF->release();
    if( teamsF )
        teamsF->release();
    if( dateienF )
        dateienF->release();
    if( editorF )
        editorF->release();
    if( editorDll )
        dllDateien->releaseDLL( dllName );
}

// nicht constant
void KartenEditor::thread()
{
    laden->setSichtbar( 1 );
    if( !editorKlient->initEditor() )
    {
        nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
        laden->setSichtbar( 0 );
        run = 0;
        return;
    }
    nachLogin->setEditor( editorF->getThis() );
    aktion = 9;
    laden->setSichtbar( 0 );
    run = 0;
}

void KartenEditor::setKarte( int id )
{
    jetzt = 0;
    hauptScreen->lock();
    if( releaseF )
        releaseF->release();
    if( shopSeiteF )
        shopSeiteF->release();
    if( beschreibungF )
        beschreibungF->release();
    if( teamsF )
        teamsF->release();
    if( editorF )
        editorF->release();
    if( editorDll )
        dllDateien->releaseDLL( dllName );
    releaseF = new KERelease( id, schrift );
    releaseF->setSichtbar( 1, 0 );
    karteRelease->setAlphaFeldFarbe( 0x0000FF00 );
    shopSeite->setAlphaFeldFarbe( 0x5500FF00 );
    beschreibung->setAlphaFeldFarbe( 0x5500FF00 );
    teams->setAlphaFeldFarbe( 0x5500FF00 );
    dateien->setAlphaFeldFarbe( 0x5500FF00 );
    editor->setAlphaFeldFarbe( 0x5500FF00 );
    editor->löscheStyle( Knopf::Style::Erlaubt );
    kaufHistorie->setAlphaFeldFarbe( 0x5500FF00 );
    jetzt = 1;
    shopSeiteF = new KEShopSeite( id, schrift );
    beschreibungF = new KEBeschreibung( id, schrift );
    teamsF = new KETeams( id, schrift );
    dateienF = new KEDateien( id, schrift );
    // Editor laden
    int spielArt = infoKlient->getSpielId( id );
    KSGTDatei *dgt = new KSGTDatei( "data/dg.ksgt" );
    dgt->laden();
    bool sak = 0;
    int dgSId = infoKlient->getDateiGruppeIdVonSpiel( spielArt );
    bool sgf = 0;
    for( int i = 0; i < dgt->getZeilenAnzahl(); i++ )
    {
        if( dgt->zFeld( i, 0 ) && TextZuInt( dgt->zFeld( i, 0 )->getText(), 10 ) == dgSId )
        {
            sgf = 1;
            int lv = dgt->zFeld( i, 2 ) ? TextZuInt( dgt->zFeld( i, 2 )->getText(), 10 ) : 0;
            int ov = infoKlient->getSpielVersion( spielArt );
            if( lv == ov )
            {
                sak = 1;
                break;
            }
        }
    }
    dgt->release();
    if( !sak )
    {
        nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Deine Spiel Version ist nicht aktuell. Sie wird beim nächsten Spielstart aktualisiert. Bis dahin sind nicht alle Editorfunktionen verfügbar." ), new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
        if( !sgf )
        {
            Text *pfad = infoKlient->getDateiGruppePfad( dgSId );
            Text *idT = new Text();
            idT->anhängen( dgSId );
            if( pfad )
            {
                KSGTDatei *dg = new KSGTDatei( "data/dg.ksgt" );
                dg->laden();
                RCArray< Text > *zeile = new RCArray< Text >();
                zeile->add( idT );
                zeile->add( pfad );
                zeile->add( new Text( "0" ) );
                zeile->add( new Text( "0" ) );
                dg->addZeile( 4, zeile );
                zeile->release();
                dg->speichern();
                dg->release();
            }
            else
                idT->release();
        }
    }
    else
    {
        Text pfad = "data/spiele/";
        dllName = "";
        dllName.anhängen( infoKlient->getSpielName( spielArt ) );
        pfad.anhängen( dllName.getText() );
        pfad.anhängen( "/bin/" );
        dllName.anhängen( ".dll" );
        pfad.anhängen( dllName.getText() );
        editorDll = dllDateien->ladeDLL( dllName, pfad );
        if( !editorDll )
        {
            Text *err = new Text( "Fehler beim laden der Dll Datei '" );
            err->anhängen( pfad.getText() );
            err->anhängen( "'. Es stehen nicht alle Editorfunktionen zur verfügung." );
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), err, new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
        }
        else
        {
            DllStart getEditorKlasse = (DllStart)GetProcAddress( editorDll, "getEditor" );
            if( !getEditorKlasse )
            {
                Text *err = new Text( "Der Einstiegspunkt 'getEditor' wurde in der Dll Datei '" );
                err->anhängen( pfad.getText() );
                err->anhängen( "' nicht gefunden. Es stehen nicht alle Editorfunktionen zur verfügung." );
                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), err, new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
            }
            else
            {
                editorF = getEditorKlasse();
                editorF->setSchrift( schrift->getThis() );
                editorF->setKlient( editorKlient->getThis() );
                editorF->setLadeAnimation( (Animation2D*)ladeAnimation->dublizieren() );
                editor->addStyle( Knopf::Style::Sichtbar );
            }
        }
    }
    //-------------------------
    hauptScreen->unlock();
}

void KartenEditor::setSichtbar( bool s )
{
    sichtbar = s;
}

void KartenEditor::doMausEreignis( MausEreignis &me )
{
    if( run )
        return;
    int aktion = 0;
    bool vera = me.verarbeitet;
    karteRelease->doMausEreignis( me );
    if( !vera && me.verarbeitet )
        aktion = 1;
    vera = me.verarbeitet;
    shopSeite->doMausEreignis( me );
    if( !vera && me.verarbeitet )
        aktion = 2;
    vera = me.verarbeitet;
    beschreibung->doMausEreignis( me );
    if( !vera && me.verarbeitet )
        aktion = 3;
    vera = me.verarbeitet;
    teams->doMausEreignis( me );
    if( !vera && me.verarbeitet )
        aktion = 4;
    vera = me.verarbeitet;
    dateien->doMausEreignis( me );
    if( !vera && me.verarbeitet )
        aktion = 5;
    vera = me.verarbeitet;
    editor->doMausEreignis( me );
    if( !vera && me.verarbeitet )
        aktion = 6;
    vera = me.verarbeitet;
    kaufHistorie->doMausEreignis( me );
    if( !vera && me.verarbeitet )
        aktion = 7;
    vera = me.verarbeitet;
    beenden->doMausEreignis( me );
    if( !vera && me.verarbeitet )
        aktion = 8;
    if( me.id == ME_RLinks && aktion )
    {
        switch( aktion )
        {
        case 1: // Release
            if( releaseF && !releaseF->istSichtbar() )
            {
                if( shopSeiteF && shopSeiteF->istSichtbar() )
                {
                    shopSeite->setAlphaFeldFarbe( 0x5500FF00 );
                    releaseF->setSichtbar( 1, 0 );
                    shopSeiteF->setSichtbar( 0, 0 );
                }
                if( beschreibungF && beschreibungF->istSichtbar() )
                {
                    beschreibung->setAlphaFeldFarbe( 0x5500FF00 );
                    releaseF->setSichtbar( 1, 0 );
                    beschreibungF->setSichtbar( 0, 0 );
                }
                if( teamsF && teamsF->istSichtbar() )
                {
                    teams->setAlphaFeldFarbe( 0x5500FF00 );
                    releaseF->setSichtbar( 1, 0 );
                    teamsF->setSichtbar( 0, 0 );
                }
                if( dateienF && dateienF->istSichtbar() )
                {
                    dateien->setAlphaFeldFarbe( 0x5500FF00 );
                    releaseF->setSichtbar( 1, 0 );
                    dateienF->setSichtbar( 0, 0 );
                }
                //-------------
                karteRelease->setAlphaFeldFarbe( 0x0000FF00 );
                jetzt = 1;
            }
            break;
        case 2: // Shop Seite
            if( shopSeiteF && !shopSeiteF->istSichtbar() )
            {
                if( releaseF && releaseF->istSichtbar() )
                {
                    karteRelease->setAlphaFeldFarbe( 0x5500FF00 );
                    shopSeiteF->setSichtbar( 1, 1 );
                    releaseF->setSichtbar( 0, 1 );
                }
                if( beschreibungF && beschreibungF->istSichtbar() )
                {
                    beschreibung->setAlphaFeldFarbe( 0x5500FF00 );
                    shopSeiteF->setSichtbar( 1, 0 );
                    beschreibungF->setSichtbar( 0, 0 );
                }
                if( teamsF && teamsF->istSichtbar() )
                {
                    teams->setAlphaFeldFarbe( 0x5500FF00 );
                    shopSeiteF->setSichtbar( 1, 0 );
                    teamsF->setSichtbar( 0, 0 );
                }
                if( dateienF && dateienF->istSichtbar() )
                {
                    dateien->setAlphaFeldFarbe( 0x5500FF00 );
                    shopSeiteF->setSichtbar( 1, 0 );
                    dateienF->setSichtbar( 0, 0 );
                }
                //---------------
                shopSeite->setAlphaFeldFarbe( 0x0000FF00 );
                jetzt = 2;
            }
            break;
        case 3: // Beschreibung
            if( beschreibungF && !beschreibungF->istSichtbar() )
            {
                if( releaseF && releaseF->istSichtbar() )
                {
                    karteRelease->setAlphaFeldFarbe( 0x5500FF00 );
                    beschreibungF->setSichtbar( 1, 1 );
                    releaseF->setSichtbar( 0, 1 );
                }
                if( shopSeiteF && shopSeiteF->istSichtbar() )
                {
                    shopSeite->setAlphaFeldFarbe( 0x5500FF00 );
                    beschreibungF->setSichtbar( 1, 1 );
                    shopSeiteF->setSichtbar( 0, 1 );
                }
                if( teamsF && teamsF->istSichtbar() )
                {
                    teams->setAlphaFeldFarbe( 0x5500FF00 );
                    beschreibungF->setSichtbar( 1, 0 );
                    teamsF->setSichtbar( 0, 0 );
                }
                if( dateienF && dateienF->istSichtbar() )
                {
                    dateien->setAlphaFeldFarbe( 0x5500FF00 );
                    beschreibungF->setSichtbar( 1, 0 );
                    dateienF->setSichtbar( 0, 0 );
                }
                //---------------
                beschreibung->setAlphaFeldFarbe( 0x0000FF00 );
                jetzt = 3;
            }
            break;
        case 4: // Teams
            if( teamsF && !teamsF->istSichtbar() )
            {
                if( releaseF && releaseF->istSichtbar() )
                {
                    karteRelease->setAlphaFeldFarbe( 0x5500FF00 );
                    teamsF->setSichtbar( 1, 1 );
                    releaseF->setSichtbar( 0, 1 );
                }
                if( shopSeiteF && shopSeiteF->istSichtbar() )
                {
                    shopSeite->setAlphaFeldFarbe( 0x5500FF00 );
                    teamsF->setSichtbar( 1, 1 );
                    shopSeiteF->setSichtbar( 0, 1 );
                }
                if( beschreibungF && beschreibungF->istSichtbar() )
                {
                    beschreibung->setAlphaFeldFarbe( 0x5500FF00 );
                    teamsF->setSichtbar( 1, 1 );
                    beschreibungF->setSichtbar( 0, 1 );
                }
                if( dateienF && dateienF->istSichtbar() )
                {
                    dateien->setAlphaFeldFarbe( 0x5500FF00 );
                    teamsF->setSichtbar( 1, 0 );
                    dateienF->setSichtbar( 0, 0 );
                }
                //---------------
                teams->setAlphaFeldFarbe( 0x0000FF00 );
                jetzt = 4;
            }
            break;
        case 5: // Dateien
            if( dateienF && !dateienF->istSichtbar() )
            {
                if( releaseF && releaseF->istSichtbar() )
                {
                    karteRelease->setAlphaFeldFarbe( 0x5500FF00 );
                    dateienF->setSichtbar( 1, 1 );
                    releaseF->setSichtbar( 0, 1 );
                }
                if( shopSeiteF && shopSeiteF->istSichtbar() )
                {
                    shopSeite->setAlphaFeldFarbe( 0x5500FF00 );
                    dateienF->setSichtbar( 1, 1 );
                    shopSeiteF->setSichtbar( 0, 1 );
                }
                if( beschreibungF && beschreibungF->istSichtbar() )
                {
                    beschreibung->setAlphaFeldFarbe( 0x5500FF00 );
                    dateienF->setSichtbar( 1, 1 );
                    beschreibungF->setSichtbar( 0, 1 );
                }
                if( teamsF && teamsF->istSichtbar() )
                {
                    teams->setAlphaFeldFarbe( 0x5500FF00 );
                    dateienF->setSichtbar( 1, 1 );
                    teamsF->setSichtbar( 0, 1 );
                }
                //---------------
                dateien->setAlphaFeldFarbe( 0x0000FF00 );
                jetzt = 5;
            }
            break;
        case 6: // Editor
            if( editor )
            {
                if( releaseF && releaseF->istSichtbar() )
                {
                    karteRelease->setAlphaFeldFarbe( 0x5500FF00 );
                    dateienF->setSichtbar( 1, 1 );
                    releaseF->setSichtbar( 0, 1 );
                }
                if( shopSeiteF && shopSeiteF->istSichtbar() )
                {
                    shopSeite->setAlphaFeldFarbe( 0x5500FF00 );
                    dateienF->setSichtbar( 1, 1 );
                    shopSeiteF->setSichtbar( 0, 1 );
                }
                if( beschreibungF && beschreibungF->istSichtbar() )
                {
                    beschreibung->setAlphaFeldFarbe( 0x5500FF00 );
                    dateienF->setSichtbar( 1, 1 );
                    beschreibungF->setSichtbar( 0, 1 );
                }
                if( teamsF && teamsF->istSichtbar() )
                {
                    teams->setAlphaFeldFarbe( 0x5500FF00 );
                    dateienF->setSichtbar( 1, 1 );
                    teamsF->setSichtbar( 0, 1 );
                }
                if( dateienF && dateienF->istSichtbar() )
                {
                    dateien->setAlphaFeldFarbe( 0x5500FF00 );
                    teamsF->setSichtbar( 1, 0 );
                    dateienF->setSichtbar( 0, 0 );
                }
                start();
                jetzt = 6;
            }
            break;
        case 7:

            break;
        case 8:
            setSichtbar( 0 );
            break;
        }
    }
    switch( jetzt )
    {
    case 1:
        releaseF->doMausEreignis( me );
        break;
    case 2:
        shopSeiteF->doMausEreignis( me );
        break;
    case 3:
        beschreibungF->doMausEreignis( me );
        break;
    case 4:
        teamsF->doMausEreignis( me );
        break;
    case 5:
        dateienF->doMausEreignis( me );
        break;
    }
}

void KartenEditor::doTastaturEreignis( TastaturEreignis &te )
{
    if( run )
        return;
    switch( jetzt )
    {
    case 1:
        releaseF->doTastaturEreignis( te );
        break;
    case 2:
        shopSeiteF->doTastaturEreignis( te );
        break;
    case 3:
        beschreibungF->doTastaturEreignis( te );
        break;
    case 4:
        teamsF->doTastaturEreignis( te );
        break;
    case 5:
        dateienF->doTastaturEreignis( te );
        break;
    }
}

bool KartenEditor::tick( double zeit )
{
    bool ret = karteRelease->tick( zeit );
    ret |= laden->tick( zeit );
    ret |= shopSeite->tick( zeit );
    ret |= beschreibung->tick( zeit );
    ret |= teams->tick( zeit );
    ret |= dateien->tick( zeit );
    ret |= editor->tick( zeit );
    ret |= kaufHistorie->tick( zeit );
    ret |= beenden->tick( zeit );
    if( releaseF && releaseF->istSichtbar() )
        ret |= releaseF->tick( zeit );
    if( shopSeiteF && shopSeiteF->istSichtbar() )
        ret |= shopSeiteF->tick( zeit );
    if( beschreibungF && beschreibungF->istSichtbar() )
        ret |= beschreibungF->tick( zeit );
    if( teamsF && teamsF->istSichtbar() )
        ret |= teamsF->tick( zeit );
    if( dateienF && dateienF->istSichtbar() )
        ret |= dateienF->tick( zeit );
    tickVal += zeit * 150;
    int val = (int)tickVal;
    if( val < 1 )
        return ret;
    if( sichtbar && run )
    {
        if( alpha != 100 )
        {
            if( alpha > 100 )
            {
                if( alpha - val <= 100 )
                    alpha = 100;
                else
                    alpha -= val;
            }
            if( alpha < 100 )
            {
                if( alpha + val >= 100 )
                    alpha = 100;
                else
                    alpha += val;
            }
        }
        if( alpha2 != 255 )
        {
            if( alpha2 + val >= 255 )
                alpha2 = 255;
            else
                alpha2 += val;
        }
    }
    else
    {
        if( sichtbar && alpha != 255 )
        {
            if( alpha + val >= 255 )
                alpha = 255;
            else
                alpha += val;
        }
        if( !sichtbar && alpha )
        {
            if( alpha - val <= 0 )
                alpha = 0;
            else
                alpha -= val;
        }
        if( alpha2 )
        {
            if( alpha2 - val <= 0 )
                alpha2 = 0;
            else
                alpha2 -= val;
        }
    }
    return ret;
}

void KartenEditor::render( Bild &zRObj )
{
    if( !alpha )
        return;
    zRObj.setAlpha( alpha2 );
    laden->render( zRObj );
    zRObj.releaseAlpha();
    zRObj.setAlpha( alpha );
    karteRelease->render( zRObj );
    shopSeite->render( zRObj );
    beschreibung->render( zRObj );
    teams->render( zRObj );
    dateien->render( zRObj );
    editor->render( zRObj );
    kaufHistorie->render( zRObj );
    beenden->render( zRObj );
    if( releaseF )
        releaseF->render( zRObj );
    if( shopSeiteF )
        shopSeiteF->render( zRObj );
    if( beschreibungF )
        beschreibungF->render( zRObj );
    if( teamsF )
        teamsF->render( zRObj );
    if( dateienF )
        dateienF->render( zRObj );
    zRObj.releaseAlpha();
}

// constant
bool KartenEditor::istSichtbar() const
{
    return sichtbar;
}

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

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