#include "KEDateien.h"
#include <Schrift.h>
#include <Text.h>
#include "../../../../Global/Variablen.h"
#include "../../../../Global/Initialisierung.h"
#include "KEDModel2DEditor.h"
#include "WAVDatei.h"
#include <Globals.h>

typedef GSL::GSLDateiV *( *GetGSLDatei )( );

// Inahlt der KEDateien Klasse aus KEDateien.h
// Konstruktor
KEDateien::KEDateien( int karte, Schrift *zSchrift )
    : Thread()
{
    schrift = zSchrift->getThis();
    Text *kName = infoClient->getKarteName( karte );
    Text titel = kName ? kName->getText() : "<Karte>";
    titel += " - Dateien";
    if( kName )
        kName->release();
    fenster = initFenster( 10, 40, 880, 550, zSchrift, Fenster::Style::Sichtbar | Fenster::Style::Titel | Fenster::Style::TitelBuffered | Fenster::Style::Erlaubt | Fenster::Style::Rahmen, titel );
    editor = new KEDEditor( zSchrift );
    laden = (Animation2D*)ladeAnimation->dublizieren();
    laden->setPosition( 425, 275 );
    laden->setSichtbar( 0 );
    fenster->addMember( editor->getThis() );
    fort = initFBalken( 375, 350, 150, 20, zSchrift, FBalken::Style::normal );
    animation = 0;
    tickVal = 0;
    sichtbar = 0;
    rechts = 0;
    xStart = 0;
    breite = 0;
    aktion = 0;
    this->karte = karte;
    alpha = 255;
}

// Destruktor
KEDateien::~KEDateien()
{
    fenster->release();
    editor->release();
    laden->release();
    fort->release();
    schrift->release();
}

// nicht constant
void KEDateien::setSichtbar( bool s, bool vr )
{
    animation = 1;
    sichtbar = s;
    rechts = vr;
    if( sichtbar )
    {
        if( vr )
        {
            xStart = 900;
            breite = 0;
        }
        else
        {
            xStart = 0;
            breite = 0;
        }
        if( !run )
        {
            aktion = 0;
            start();
        }
    }
    else
        editor->setSichtbar( 0 );
}

void KEDateien::thread()
{
    laden->setSichtbar( 1 );
    switch( aktion )
    {
    case 0: // Init
    {
        RCArray< Text > *list = new RCArray< Text >();
        int anz = editorClient->deGetDateiListe( list );
        if( anz < 0 )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
            list->release();
            break;
        }
        editor->setDateiListe( list );
        break;
    }
    case 1: // Neue Datei
    {
        if( !editorClient->deNeueDatei( (char)editor->getNeuDateiTyp(), editor->zNeuDateiName() ) )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
            break;
        }
        RCArray< Text > *list = new RCArray< Text >();
        int anz = editorClient->deGetDateiListe( list );
        if( anz < 0 )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
            list->release();
            break;
        }
        editor->setDateiListe( list );
        break;
    }
    case 2: // Datei Ausw�hlen
    {
        Text *zName = editor->zDateiAuswahl();
        if( zName->hat( ".ltdb" ) )
        {
            RCArray< Text > *list = new RCArray< Text >();
            int anz = editorClient->deGetBildListe( zName, list );
            if( anz < 0 )
            {
                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
                list->release();
                break;
            }
            editor->setBildListe( list );
        }
        else if( zName->hat( ".gsl" ) )
        {
            RCArray< Text > *list = new RCArray< Text >();
            int anz = editorClient->deGetSoundListe( zName, list );
            if( anz < 0 )
            {
                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
                list->release();
                break;
            }
            editor->setSoundListe( list );
        }
        else if( zName->hat( ".m2" ) )
        {
            RCArray< Text > *list = new RCArray< Text >();
            int anz = editorClient->deGetModelListe( zName, list );
            if( anz < 0 )
            {
                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
                list->release();
                break;
            }
            editor->setModel2dListe( list );
        }
        else
        {
            if( !editorClient->deOrdner�ffnen( zName ) )
            {
                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
                break;
            }
            RCArray< Text > *list = new RCArray< Text >();
            int anz = editorClient->deGetDateiListe( list );
            if( anz < 0 )
            {
                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
                list->release();
                break;
            }
            editor->setDateiListe( list );
        }
        break;;
    }
    case 3: // Datei L�schen
    {
        Text p( "." );
        if( ( editor->zDateiAuswahl() && !editorClient->deDateiL�schen( editor->zDateiAuswahl() ) ) || ( !editor->zDateiAuswahl() && !editorClient->deDateiL�schen( &p ) ) )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
            break;
        }
        RCArray< Text > *list = new RCArray< Text >();
        int anz = editorClient->deGetDateiListe( list );
        if( anz < 0 )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
            list->release();
            break;
        }
        editor->setDateiListe( list );
        break;
    }
    case 4: // Bild Ausw�hlen
    {
        Bild *b = editorClient->deBildLaden( editor->zDateiAuswahl(), editor->zBildAuswahl(), fort );
        if( !b )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
            break;
        }
        editor->setBild( b );
        break;
    }
    case 5: // Bild L�schen
    {
        if( !editorClient->deBildL�schen( editor->zDateiAuswahl(), editor->zBildAuswahl() ) )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
            break;
        }
        RCArray< Text > *list = new RCArray< Text >();
        int anz = editorClient->deGetBildListe( editor->zDateiAuswahl(), list );
        if( anz < 0 )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
            list->release();
            break;
        }
        editor->setBildListe( list );
        break;
    }
    case 6: // Bild Importieren
    {
        Text *pfad = editor->zBildImportPfad();
        pfad->ersetzen( "\\", "/" );
        Text *n = pfad->getTeilText( pfad->positionVon( "/", pfad->anzahlVon( "/" ) - 1 ) + 1 );
        Text name = n->getText();
        n->release();
        Text *err = new Text();
        Bild *b = ladeBild( pfad->getText(), err );
        if( !b )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), err, new Text( "Ok" ) );
            break;
        }
        err->release();
        if( !editorClient->deBildSpeichern( editor->zDateiAuswahl(), &name, b, fort ) )
        {
            b->release();
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
            break;
        }
        b->release();
        RCArray< Text > *list = new RCArray< Text >();
        int anz = editorClient->deGetBildListe( editor->zDateiAuswahl(), list );
        if( anz < 0 )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
            list->release();
            break;
        }
        editor->setBildListe( list );
        break;
    }
    case 7: // Model Ausw�hlen
    {
        Model2DData *d = editorClient->deModelLaden( editor->zDateiAuswahl(), editor->zModel2dAuswahl(), fort );
        if( !d )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
            break;
        }
        editor->setModel2d( d );
        break;
    }
    case 8: // Model L�schen
    {
        if( !editorClient->deModelL�schen( editor->zDateiAuswahl(), editor->zModel2dAuswahl() ) )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
            break;
        }
        RCArray< Text > *list = new RCArray< Text >();
        int anz = editorClient->deGetModelListe( editor->zDateiAuswahl(), list );
        if( anz < 0 )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
            list->release();
            break;
        }
        editor->setModel2dListe( list );
        break;
    }
    case 9: // Model speichern
    {
        Model2DData *m = editor->getModelData();
        if( !editorClient->deModelSpeichern( editor->zDateiAuswahl(), editor->zModel2dAuswahl(), m, fort ) )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
            m->release();
            break;
        }
        editor->setModel2d( m );
        break;
    }
    case 10: // Neues Model
    {
        Model2DData *m = new Model2DData();
        m->erstelleModell( new Array< Polygon2D >() );
        if( !editorClient->deModelSpeichern( editor->zDateiAuswahl(), editor->zNeuModelName(), m, fort ) )
        {
            m->release();
            break;
        }
        m->release();
        RCArray< Text > *list = new RCArray< Text >();
        int anz = editorClient->deGetModelListe( editor->zDateiAuswahl(), list );
        if( anz < 0 )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
            list->release();
            break;
        }
        editor->setModel2dListe( list );
        break;
    }
    case 11: // Sound Abspielen
    {
        HMODULE dll = Framework::getDLLRegister()->ladeDLL( "GSL.dll", "data/bin/GSL.dll" );
        if( dll )
        {
            GetGSLDatei getGSLDatei = (GetGSLDatei)GetProcAddress( dll, "getGSLDatei" );
            if( getGSLDatei )
            {
                GSL::GSLDateiV *gsld = getGSLDatei();
                GSL::GSLSoundV *s = editorClient->deSoundLaden( gsld, editor->zDateiAuswahl(), editor->zSoundAuswahl(), fort );
                if( !s )
                {
                    nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
                    break;
                }
                editor->setSound( s );
            }
            else
                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Der Einstiegspunkt 'getGSLDatei' in der DLL Datei 'data/bin/GSL.dll' konnte nicht gefunden werden." ), new Text( "Ok" ) );
        }
        else
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Die DLL Datei 'data/bin/GSL.dll' konnte nicht gefunden werden." ), new Text( "Ok" ) );
        break;
    }
    case 12: // Sound L�schen
    {
        if( !editorClient->deSoundL�schen( editor->zDateiAuswahl(), editor->zSoundAuswahl() ) )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
            break;
        }
        RCArray< Text > *list = new RCArray< Text >();
        int anz = editorClient->deGetSoundListe( editor->zDateiAuswahl(), list );
        if( anz < 0 )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
            list->release();
            break;
        }
        editor->setSoundListe( list );
        break;
    }
    case 13: // Sound Importieren
    {
        Text *pfad = editor->zSoundImportPfad();
        pfad->ersetzen( "\\", "/" );
        Text *n = pfad->getTeilText( pfad->positionVon( "/", pfad->anzahlVon( "/" ) - 1 ) + 1 );
        Text name = n->getText();
        name.remove( ".wav" );
        n->release();
        WAVDatei *s = new WAVDatei();
        if( !s->lade( pfad->getText() ) )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Fehler beim Lesen der Ausgew�hlten Datei." ), new Text( "Ok" ) );
            s->release();
            break;
        }
        if( !editorClient->deSoundSpeichern( editor->zDateiAuswahl(), &name, s, fort ) )
        {
            s->release();
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
            break;
        }
        s->release();
        RCArray< Text > *list = new RCArray< Text >();
        int anz = editorClient->deGetSoundListe( editor->zDateiAuswahl(), list );
        if( anz < 0 )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorClient->getLetzterFehler() ), new Text( "Ok" ) );
            list->release();
            break;
        }
        editor->setSoundListe( list );
        break;
    }
    }
    laden->setSichtbar( 0 );
    run = 0;
    fort->reset();
}

void KEDateien::doMausEreignis( MausEreignis &me )
{
    if( !run )
        fenster->doMausEreignis( me );
}

void KEDateien::doTastaturEreignis( TastaturEreignis &te )
{
    if( !run )
        fenster->doTastaturEreignis( te );
}

bool KEDateien::tick( double z )
{
    fort->tick( z );
    aktion = editor->getAktion();
    if( aktion && !run )
        start();
    bool ret = laden->tick( z );
    tickVal += z * 150;
    int val = (int)tickVal;
    tickVal -= val;
    if( val )
    {
        if( run && alpha > 100 )
        {
            if( alpha - val < 100 )
                alpha = 100;
            else
                alpha -= val;
            ret = 1;
        }
        if( sichtbar && !run && alpha != 255 )
        {
            if( alpha + val > 255 )
                alpha = 255;
            else
                alpha += val;
            ret = 1;
        }
        val *= 3;
        if( sichtbar )
        {
            if( alpha < 100 )
            {
                if( alpha + val > 100 )
                    alpha = 100;
                else
                    alpha += val;
                ret = 1;
            }
            if( xStart != 0 || breite != 900 )
            {
                if( rechts )
                {
                    if( xStart - val <= 0 )
                    {
                        xStart = 0;
                        breite = 900;
                        animation = 0;
                        editor->setSichtbar( 1 );
                    }
                    else
                    {
                        xStart -= val;
                        breite += val;
                    }
                }
                else
                {
                    if( breite + val >= 900 )
                    {
                        breite = 900;
                        animation = 0;
                        editor->setSichtbar( 1 );
                    }
                    else
                        breite += val;
                }
                ret = 1;
            }
        }
        else
        {
            if( breite != 0 )
            {
                if( rechts )
                {
                    if( breite - val <= 0 )
                    {
                        breite = 0;
                        animation = 0;
                    }
                    else
                        breite -= val;
                }
                else
                {
                    if( breite - val <= 0 )
                    {
                        breite = 0;
                        xStart = 900;
                        animation = 0;
                    }
                    else
                    {
                        breite -= val;
                        xStart += val;
                    }
                }
                ret = 1;
            }
        }
    }
    return ret || fenster->tick( z );
}

void KEDateien::render( Bild &zRObj )
{
    if( !zRObj.setDrawOptions( xStart, 0, breite, 600 ) )
        return;
    zRObj.setAlpha( alpha );
    fenster->render( zRObj );
    zRObj.releaseAlpha();
    laden->render( zRObj );
    if( fort->getAktionAnzahl() && run )
        fort->render( zRObj );
    zRObj.releaseDrawOptions();
}

// constant
bool KEDateien::istSichtbar() const
{
    return sichtbar || animation;
}

// l�scht das objekt wenn es nicht mehr gebraucht wird und beendet den Thread
Thread *KEDateien::release()
{
    if( ref == 2 && run )
    {
        warteAufThread( 5000 );
        if( run )
            ende();
    }
    return Thread::release();
}