#include "KEBVorschau.h"
#include "../../../../Global/Variablen.h"
#include "../../../../Global/Initialisierung.h"
#include <Datei.h>

void kEBVorschauKSGSAktion( void *p, RCArray< KSGSVariable > *parameter, KSGSVariable **retVal )
{
    if( !p )
        return;
    ( (KEBVorschauKarteScript*)p )->ksgsAktion( parameter, retVal );
}

// Inhalt der KEBVorschauKarteScript Klasse aus KEBVorschau.h
// Konstruktor
KEBVorschauKarteScript::KEBVorschauKarteScript( Schrift *zSchrift, TextFeld *zLog )
    : Thread()
{
    ksgs = dllDateien->ladeDLL( "KSGScript.dll", "data/bin/KSGScript.dll" );
    if( ksgs )
    {
        KSGSGetZeichnung getKSGScript = (KSGSGetZeichnung)GetProcAddress( ksgs, KSGS_START_FUNKTION );
        if( getKSGScript )
        {
            fenster = getKSGScript();
            fenster->setSchriftZ( zSchrift->getThis() );
            fenster->setGröße( 578, 428 );
            fenster->setRückrufParam( this );
            fenster->setRückrufFunktion( kEBVorschauKSGSAktion );
            fenster->setLog( zLog->getThis() );
        }
        else
        {
            fenster = 0;
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
                                                          new Text( "Der Einstiegspunkt '" KSGS_START_FUNKTION "' in der DLL-Datei "
                                                                    "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
                                                          new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
        }
    }
    else
    {
        fenster = 0;
        nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
                                                      new Text( "Die DLL-Datei 'data/bin/KSGScript.dll' konnte nicht geladen werden." ),
                                                      new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
    }
    ram = new LRahmen();
    ram->setGröße( 578, 428 );
    ram->setFarbe( 0xFFFFFFFF );
    pos = Punkt( 120, 10 );
    erlaubt = 1;
    sichtbar = 0;
    alpha = 0;
    aktion = 0;
    ak = 0;
    ref = 1;
}

// Destruktor
KEBVorschauKarteScript::~KEBVorschauKarteScript()
{
    if( fenster )
    {
        fenster->zurücksetzen();
        fenster->release();
    }
    ram->release();
    if( ksgs )
        dllDateien->releaseDLL( "KSGScript.dll" );
}

// nicht constant
void KEBVorschauKarteScript::thread()
{
    sichtbar = 0;
    while( alpha )
        Sleep( 100 );
    if( ak == 1 )
    {
        pfad += "/seite.ksgs";
        if( fenster )
            fenster->setScriptDatei( pfad );
    }
    fenster->neuLaden();
    KSGSGetVariable getKSGSVar = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
    RCArray< KSGSVariable > *params = new RCArray< KSGSVariable >();
    KSGSVariableDef p1;
    p1.typId = KSGS_BOOL;
    p1.wert = erlaubt;
    params->add( getKSGSVar( fenster, &p1 ) );
    KSGSVariable *var = fenster->startFunktion( fenster->getFunktionId( "_set_Erlaubt" ), params );
    if( var )
        var->release();
    sichtbar = 1;
    ak = 0;
    run = 0;
}

void KEBVorschauKarteScript::setErlaubt( bool e )
{
    erlaubt = e;
    KSGSGetVariable getKSGSVar = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
    RCArray< KSGSVariable > *params = new RCArray< KSGSVariable >();
    KSGSVariableDef p1;
    p1.typId = KSGS_BOOL;
    p1.wert = erlaubt;
    params->add( getKSGSVar( fenster, &p1 ) );
    KSGSVariable *var = fenster->startFunktion( fenster->getFunktionId( "_set_Erlaubt" ), params );
    if( var )
        var->release();
}

void KEBVorschauKarteScript::ladeKarteSeite( char *pfad )
{
    if( run )
        warteAufThread( 5000 );
    if( run )
        ende();
    this->pfad = pfad;
    ak = 1;
    start();
}

void KEBVorschauKarteScript::ksgsAktion( RCArray< KSGSVariable > *parameter, KSGSVariable **retVal )
{
}

void KEBVorschauKarteScript::doMausEreignis( MausEreignis &me )
{
    me.mx -= pos.x;
    me.my -= pos.y;
    if( fenster )
        fenster->doMausEreignis( me );
    me.mx += pos.x;
    me.my += pos.y;
}

void KEBVorschauKarteScript::doTastaturEreignis( TastaturEreignis &te )
{
    if( fenster )
        fenster->doTastaturEreignis( te );
}

bool KEBVorschauKarteScript::tick( double zeit )
{
    bool rend = fenster ? fenster->tick( zeit ) : 0;
    if( !sichtbar && alpha > 0 )
    {
        if( alpha - zeit * 150 < 0 )
            alpha = 0;
        else
            alpha -= (unsigned char)( zeit * 150 );
        rend = 1;
    }
    if( sichtbar && alpha < 255 )
    {
        if( alpha + zeit * 150 > 255 )
            alpha = 255;
        else
            alpha += (unsigned char)( zeit * 150 );
        rend = 1;
    }
    return rend;
}

void KEBVorschauKarteScript::render( Bild &zRObj )
{
    if( !zRObj.setDrawOptions( pos.x, pos.y, ram->getBreite(), ram->getHöhe() ) )
        return;
    zRObj.setAlpha( alpha );
    ram->render( zRObj );
    if( fenster )
        fenster->render( zRObj );
    zRObj.releaseAlpha();
    zRObj.releaseDrawOptions();
}

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

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


// Inhalt der KEBVorschau Klasse aus KEBVorschau.h
// Konstruktor
KEBVorschau::KEBVorschau( Schrift *zSchrift )
{
    this->schrift = zSchrift->getThis();
    neu = initKnopf( 10, 10, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Neu starten" );
    beenden = initKnopf( 10, 40, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Beenden" );
    log = initTextFeld( 10, 445, 860, 75, zSchrift, ( TextFeld::Style::TextGebiet | TextFeld::Style::HScroll ) & ~TextFeld::Style::Erlaubt, "Log:\n" );
    script = new KEBVorschauKarteScript( zSchrift, log );
    erlaubt = initKontrollKnopf( 10, 70, 100, 20, zSchrift, KontrollKnopf::Style::Normal | KontrollKnopf::Style::Selected, "Erlaubt" );
    alpha = 0;
    sichtbar = 0;
    tickVal = 0;
    aktion = 0;
    rend = 0;
    ref = 1;
}

// Destruktor
KEBVorschau::~KEBVorschau()
{
    schrift->release();
    script->release();
    neu->release();
    beenden->release();
    log->release();
    erlaubt->release();
}

// nicht constant
int KEBVorschau::getAktion()
{
    int ret = aktion;
    aktion = 0;
    return ret;
}

bool KEBVorschau::ladeKarte()
{
    Text *scr = editorKlient->beschreibungLaden();
    if( !scr )
    {
        nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
        return 0;
    }
    else
    {
        Datei d;
        d.setDatei( "data/tmp/ke/kbv/seite.ksgs" );
        d.erstellen();
        if( !d.öffnen( Datei::Style::schreiben ) )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Fehler beim öffnen der Datei 'data/tmp/ke/kbv/seite.ksgs'" ), new Text( "Ok" ) );
            return 0;
        }
        d.schreibe( scr->getText(), scr->getLänge() );
        d.schließen();
        scr->release();
        script->ladeKarteSeite( "data/tmp/ke/kbv" );
    }
    return 1;
}

void KEBVorschau::setSichtbar( bool sicht )
{
    sichtbar = sicht;
}

void KEBVorschau::doMausEreignis( MausEreignis &me )
{
    if( !sichtbar )
        return;
    script->doMausEreignis( me );
    bool mev = me.verarbeitet;
    neu->doMausEreignis( me );
    if( !mev && me.verarbeitet && me.id == ME_RLinks )
        script->ladeKarteSeite( "data/tmp/ke/kbv" );
    mev = me.verarbeitet;
    beenden->doMausEreignis( me );
    if( !mev && me.verarbeitet && me.id == ME_RLinks )
        aktion = 1;
    log->doMausEreignis( me );
    bool eu = 0;
    bool sel = erlaubt->hatStyle( KontrollKnopf::Style::Selected );
    erlaubt->doMausEreignis( me );
    if( sel != erlaubt->hatStyle( KontrollKnopf::Style::Selected ) )
        script->setErlaubt( erlaubt->hatStyle( KontrollKnopf::Style::Selected ) );
}

void KEBVorschau::doTastaturEreignis( TastaturEreignis &te )
{
    if( !sichtbar )
        return;
    script->doTastaturEreignis( te );
}

bool KEBVorschau::tick( double zeit )
{
    bool ret = script->tick( zeit );
    ret |= neu->tick( zeit );
    ret |= beenden->tick( zeit );
    ret |= log->tick( zeit );
    ret |= erlaubt->tick( zeit );
    tickVal += zeit * 150;
    int val = 0;
    if( tickVal > 1 )
        val = (int)tickVal;
    else
        return ret;
    if( sichtbar && alpha != 255 )
    {
        if( alpha + val > 255 )
            alpha = 255;
        else
            alpha += val;
        ret = 1;
    }
    if( !sichtbar && alpha != 0 )
    {
        if( alpha - val < 0 )
            alpha = 0;
        else
            alpha -= val;
        ret = 1;
    }
    return ret;
}

void KEBVorschau::render( Bild &zRObj )
{
    zRObj.setAlpha( alpha );
    script->render( zRObj );
    neu->render( zRObj );
    beenden->render( zRObj );
    log->render( zRObj );
    erlaubt->render( zRObj );
    zRObj.releaseAlpha();
}

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

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

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