#include "KartenKaufen.h"
#include <Rahmen.h>
#include <Punkt.h>
#include "../../../Global/Initialisierung.h"
#include "../../../Global/Variablen.h"
#include <DateiSystem.h>
#include <AlphaFeld.h>
#include <KSGTDatei.h>

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

// Inhalt der KartenKaufenAuswahl Klasse aus KartenKaufen.h
// Konstruktor
KartenKaufenAuswahl::KartenKaufenAuswahl( Schrift *zSchrift )
{
    karteId = 0;
    alpha = 0;
    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->setSize( 555, 380 );
            fenster->setR�ckrufParam( this );
            fenster->setR�ckrufFunktion( KarteKaufenKSGSAktion );
        }
        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 );
        }
    }
    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 );
    }
    ram = new LRahmen();
    ram->setSize( 555, 380 );
    ram->setFarbe( 0xFFFFFFFF );
    laden = ( Framework::Animation2D* )ladeAnimation->dublizieren();
    laden->setPosition( 252, 165 );
    laden->setSichtbar( 0 );
    pos = Punkt( 220, 10 );
    aktion = 0;
    ref = 1;
}

// Destruktor
KartenKaufenAuswahl::~KartenKaufenAuswahl()
{
    if( run )
        warteAufThread( 2000 );
    if( run )
        ende();
    if( fenster )
    {
        fenster->zur�cksetzen();
        fenster->release();
    }
    ram->release();
    laden->release();
    if( ksgs )
        dllDateien->releaseDLL( "KSGScript.dll" );
}

// nicht constant
void KartenKaufenAuswahl::ladeKarteSeite( int id )
{
    if( run )
        warteAufThread( 2000 );
    if( run )
        return;
    karteId = id;
    aktion = 1;
    start();
}

void KartenKaufenAuswahl::reset()
{
    if( run )
        warteAufThread( 2000 );
    if( run )
        return;
    aktion = 0;
    start();
}

void KartenKaufenAuswahl::thread()
{
    laden->setSichtbar( 1 );
    if( !aktion || karteId )
    {
        while( alpha )
            Sleep( 100 );
        if( !aktion )
            karteId = 0;
        if( fenster )
            fenster->zur�cksetzen();
    }
    if( aktion )
    {
        while( alpha )
            Sleep( 100 );
        if( !shopClient )
            shopClient = mainClient->createShopServerClient();
        if( shopClient && shopClient->verbinde() )
        {
            shopClient->ladeKarteSeite( karteId );
            shopClient->trenne( 0 );
        }
        Text *pfad = new Text( "data/tmp/shop/kaufen/karten/" );
        pfad->append( karteId );
        pfad->append( "/seite.ksgs" );
        if( fenster )
        {
            fenster->setScriptDatei( pfad );
            fenster->neuLaden();
        }
    }
    laden->setSichtbar( 0 );
    run = 0;
}

void KartenKaufenAuswahl::ksgsAktion( RCArray< KSGSVariable > *parameter, KSGSVariable **retVal )
{
    KSGSVariable *befehl = parameter->z( 0 );
    if( !befehl )
        return;
    Text *b = befehl->getText();
    if( !b )
        return;
    if( b->istGleich( "GetBesitzStatus" ) )
    {
        int besitz = 0;
        if( !shopClient )
            shopClient = mainClient->createShopServerClient();
        if( shopClient && shopClient->verbinde() )
        {
            besitz = shopClient->getKarteBesitzStatus( karteId );
            shopClient->trenne( 0 );
        }
        KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
        if( getKSGSVariable )
        {
            KSGSVariableDef def = { KSGS_INT, 0, 3, ( Text() += besitz ).getText() };
            *retVal = getKSGSVariable( fenster, &def );
        }
        else
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
                                                          new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
                                                                    "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
                                                          new Text( "Ok" ), 0 );
        }
        b->release();
        return;
    }
    if( b->istGleich( "GetPreis" ) )
    {
        KSGSVariable *version = parameter->z( 1 );
        if( !version )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
                                                          new Text( "Auf dieser Seite befindet sich ein Fehler im KSG-Script. "
                                                                    "Sie k�nnte eventuell nicht richtig funktionieren." ),
                                                          new Text( "Ok" ), 0 );
        }
        else
        {
            bool testVersion = !version->getInt();
            int preis = 0;
            if( !shopClient )
                shopClient = mainClient->createShopServerClient();
            if( shopClient && shopClient->verbinde() )
            {
                preis = shopClient->getKartePreis( karteId, testVersion );
                shopClient->trenne( 0 );
            }
            KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
            if( getKSGSVariable )
            {
                KSGSVariableDef def = { KSGS_INT, 0, 3, ( Text() += preis ).getText() };
                *retVal = getKSGSVariable( fenster, &def );
            }
            else
            {
                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
                                                              new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
                                                                        "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
                                                              new Text( "Ok" ), 0 );
            }
        }
        b->release();
        return;
    }
    if( b->istGleich( "GetTestVersionVerbleibend" ) )
    {
        int verbleibend = 0;
        if( !shopClient )
            shopClient = mainClient->createShopServerClient();
        if( shopClient && shopClient->verbinde() )
        {
            verbleibend = shopClient->getKarteTestversion( karteId );
            shopClient->trenne( 0 );
        }
        KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
        if( getKSGSVariable )
        {
            KSGSVariableDef def = { KSGS_INT, 0, 3, ( Text() += verbleibend ).getText() };
            *retVal = getKSGSVariable( fenster, &def );
        }
        else
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
                                                          new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
                                                                    "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
                                                          new Text( "Ok" ), 0 );
        }
        b->release();
        return;
    }
    if( b->istGleich( "GetErwerbbarStatus" ) )
    {
        int erwerbbar = 0;
        if( !shopClient )
            shopClient = mainClient->createShopServerClient();
        if( shopClient && shopClient->verbinde() )
        {
            erwerbbar = shopClient->istKarteErwerbbar( karteId );
            shopClient->trenne( 0 );
        }
        KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
        if( getKSGSVariable )
        {
            KSGSVariableDef def = { KSGS_INT, 0, 3, ( Text() += erwerbbar ).getText() };
            *retVal = getKSGSVariable( fenster, &def );
        }
        else
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
                                                          new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
                                                                    "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
                                                          new Text( "Ok" ), 0 );
        }
        b->release();
        return;
    }
    if( b->istGleich( "GetKupfer" ) )
    {
        int kupfer = infoClient->getKupfer();
        KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
        if( getKSGSVariable )
        {
            KSGSVariableDef def = { KSGS_INT, 0, 3, ( Text() += kupfer ).getText() };
            *retVal = getKSGSVariable( fenster, &def );
        }
        else
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
                                                          new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
                                                                    "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
                                                          new Text( "Ok" ), 0 );
        }
        b->release();
        return;
    }
    if( b->istGleich( "Kaufen" ) )
    {
        KSGSVariable *version = parameter->z( 1 );
        if( !version )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
                                                          new Text( "Auf dieser Seite befindet sich ein Fehler im KSG-Script. "
                                                                    "Sie k�nnte eventuell nicht richtig funktionieren." ),
                                                          new Text( "Ok" ), 0 );
        }
        else
        {
            bool testVersion = !version->getInt();
            if( !shopClient )
                shopClient = mainClient->createShopServerClient();
            if( shopClient && shopClient->verbinde() )
            {
                if( !shopClient->karteErwerben( karteId, testVersion ) )
                {
                    nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
                                                                  new Text( shopClient->getLetzterFehler() ),
                                                                  new Text( "Ok" ), 0 );
                }
                shopClient->trenne( 0 );
            }
            else if( shopClient )
            {
                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
                                                              new Text( shopClient->getLetzterFehler() ),
                                                              new Text( "Ok" ), 0 );
            }
            else
            {
                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
                                                              new Text( mainClient->getLetzterFehler() ),
                                                              new Text( "Ok" ), 0 );
            }
            if( run )
                warteAufThread( 2000 );
            if( run )
            {
                b->release();
                return;
            }
            aktion = 1;
            start();
        }
        b->release();
        return;
    }
    if( b->istGleich( "GetBild" ) )
    {
        KSGSVariable *pfad = parameter->z( 1 );
        KSGSVariable *name = parameter->z( 2 );
        if( !pfad || !name )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
                                                          new Text( "Auf dieser Seite befindet sich ein Fehler im KSG-Script. "
                                                                    "Sie k�nnte eventuell nicht richtig funktionieren." ),
                                                          new Text( "Ok" ), 0 );
        }
        else
        {
            Text *pf = pfad->getText();
            Text *n = name->getText();
            if( !pf || !n )
            {
                nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
                                                              new Text( "Auf dieser Seite befindet sich ein Fehler im KSG-Script. "
                                                                        "Sie k�nnte eventuell nicht richtig funktionieren." ),
                                                              new Text( "Ok" ), 0 );
            }
            else
            {
                KSGSGetVariable getKSGSVariable = (KSGSGetVariable)GetProcAddress( ksgs, KSGS_VARIABLE_FUNKTION );
                if( getKSGSVariable )
                {
                    int p = n->positionVon( ".ltdb/" );
                    if( p < 0 )
                        p = 0;
                    else
                        p += 6;
                    Bild *b = bilder->get( *n );
                    if( !b )
                    {
                        LTDBDatei *dat = new LTDBDatei();
                        dat->setDatei( pf->getThis() );
                        dat->leseDaten( 0 );
                        b = dat->laden( 0, n->getTeilText( p, n->getLength() ) );
                        dat->release();
                        if( b )
                            bilder->add( *n, b->getThis() );
                    }
                    if( b )
                    {
                        KSGSVariableDef def = { KSGS_BILD, 0, 3, "" };
                        KSGSVariable *ret = getKSGSVariable( fenster, &def );
                        KSGSSetBild setKSGSBild = (KSGSSetBild)GetProcAddress( ksgs, KSGS_SET_BILD_FUNKTION );
                        if( !setKSGSBild )
                        {
                            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
                                                                          new Text( "Der Einstiegspunkt '" KSGS_SET_BILD_FUNKTION "' in der DLL-Datei "
                                                                                    "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
                                                                          new Text( "Ok" ), 0 );
                            b->release();
                        }
                        else
                            setKSGSBild( ret, b );
                        *retVal = ret;
                    }
                }
                else
                {
                    nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
                                                                  new Text( "Der Einstiegspunkt '" KSGS_VARIABLE_FUNKTION "' in der DLL-Datei "
                                                                            "'data/bin/KSGScript.dll' konnte nicht gefunden werden." ),
                                                                  new Text( "Ok" ), 0 );
                }
            }
            if( pf )
                pf->release();
            if( n )
                n->release();
        }
        b->release();
        return;
    }
}

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

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

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

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

// constant

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

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


// Inhalt der KartenKaufenListeEintrag Klasse aus KartenKaufen.h
// Konstruktor
KartenKaufenListeEintrag::KartenKaufenListeEintrag( int id, Schrift *schrift )
{
    karteId = id;
    ausw�hlen = initKnopf( 173, 73, 22, 22, 0, 0, "" );
    ausw�hlen->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Rahmen | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
    ausw�hlen->setHintergrundBildZ( bilder->get( "shop.ltdb/weiter.png" ) );
    initToolTip( ausw�hlen, "Karte ausw�hlen.", schrift, hauptScreen );
    ausw�hlen->setRahmenBreite( 1 );
    LTDBDatei *datei = new LTDBDatei();
    Text *bdpf = new Text( "data/tmp/shop/kaufen/karten/" );
    bdpf->append( id );
    bdpf->append( "/titelbg.ltdb" );
    datei->setDatei( bdpf );
    hintergrund = datei->laden( 0, new Text( "auswbg.jpg" ) );
    datei->release();
    ausgew�hlt = new AlphaFeld();
    ausgew�hlt->setPosition( 1, 1 );
    ausgew�hlt->setSize( 198, 98 );
    ausgew�hlt->setFarbe( 0x0000FF00 );
    ausgew�hlt->setStrength( 10 );
    ram = new LRahmen();
    ram->setSize( 200, 100 );
    ram->setFarbe( 0xFFFFFFFF );
    ausw = 0;
    rend = 0;
    ref = 1;
}

// Destruktor
KartenKaufenListeEintrag::~KartenKaufenListeEintrag()
{
    ausw�hlen->release();
    if( hintergrund )
        hintergrund->release();
    ausgew�hlt->release();
    ram->release();
}

// nicht constant
void KartenKaufenListeEintrag::resetAuswahl()
{
    ausw = 0;
}

bool KartenKaufenListeEintrag::doMausEreignis( MausEreignis &me )
{
    bool vera = me.verarbeitet;
    ausw�hlen->doMausEreignis( me );
    if( !vera && me.verarbeitet && me.id == ME_RLinks )
    {
        ausw = 1;
        return 1;
    }
    return 0;
}

bool KartenKaufenListeEintrag::tick( double zeit )
{
    rend |= ausgew�hlt->tick( zeit );
    rend |= ausw�hlen->tick( zeit );
    int a = ( ausgew�hlt->getFarbe() >> 24 ) & 0xFF;
    if( ausw && a < 255 )
    {
        if( a + 150 * zeit > 255 )
            a = 255;
        else
            a += (int)( zeit * 150 );
        ausgew�hlt->setFarbe( ( ( a << 24 ) & 0xFF000000 ) | ( ausgew�hlt->getFarbe() & 0xFFFFFF ) );
        rend = 1;
    }
    if( !ausw && a > 0 )
    {
        if( a - 150 * zeit < 0 )
            a = 0;
        else
            a += (int)( zeit * 150 );
        ausgew�hlt->setFarbe( ( ( a << 24 ) & 0xFF000000 ) | ( ausgew�hlt->getFarbe() & 0xFFFFFF ) );
        rend = 1;
    }
    bool ret = rend;
    rend = 0;
    return ret;
}

void KartenKaufenListeEintrag::render( int yOff, Bild &zRObj )
{
    if( !zRObj.setDrawOptions( 0, yOff, 200, 100 ) )
        return;
    ram->render( zRObj );
    if( hintergrund )
        zRObj.drawBild( 1, 1, 198, 98, *hintergrund );
    ausgew�hlt->render( zRObj );
    ausw�hlen->render( zRObj );
    zRObj.releaseDrawOptions();
}

// constant
int KartenKaufenListeEintrag::getKarteId() const
{
    return karteId;
}

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

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


// Inhalt der KartenKaufenListe Klasse aus KartenKaufen.h
// Konstruktor
KartenKaufenListe::KartenKaufenListe( Schrift *schrift )
{
    s = schrift;
    pos = Punkt( 5, 55 );
    ram = new LRahmen();
    ram->setSize( 215, 380 );
    ram->setFarbe( 0xFFFFFFFF );
    eintr�ge = new RCArray< KartenKaufenListeEintrag >();
    vScroll = new VScrollBar();
    vScroll->setKlickScroll( 10 );
    vScroll->update( 0, 380 );
    rend = 0;
    ref = 1;
}

// Destruktor
KartenKaufenListe::~KartenKaufenListe()
{
    s->release();
    ram->release();
    eintr�ge->release();
    vScroll->release();
}

// nicht constant
void KartenKaufenListe::ladeKarten( Array< int > *karten )
{
    leeren();
    int anz = karten->getEintragAnzahl();
    shopClient = mainClient->createShopServerClient();
    if( shopClient && shopClient->verbinde() )
    {
        for( int i = 0; i < anz; i++ )
        {
            if( shopClient->ladeKarteTitel( karten->hat( i ) ? karten->get( i ) : 0 ) )
                eintr�ge->add( new KartenKaufenListeEintrag( karten->hat( i ) ? karten->get( i ) : 0, s->getThis() ) );
        }
        shopClient->trenne( 0 );
    }
    vScroll->update( anz * 100, 380 );
    rend = 1;
}

void KartenKaufenListe::leeren()
{
    cs.lock();
    eintr�ge->leeren();
    cs.unlock();
    vScroll->update( 0, 380 );
    rend = 1;
}

int KartenKaufenListe::doMausEreignis( MausEreignis &me )
{
    int mx = me.mx;
    int my = me.my;
    me.mx -= pos.x;
    me.my -= pos.y;
    vScroll->doMausMessage( 200, 0, 15, 380, me );
    me.my += vScroll->getScroll();
    int ret = 0;
    cs.lock();
    int anz = eintr�ge->getEintragAnzahl();
    for( int i = 0; i < anz; i++ )
    {
        if( eintr�ge->z( i )->doMausEreignis( me ) )
            ret = eintr�ge->z( i )->getKarteId();
        me.my += 100;
    }
    if( ret )
    {
        for( int i = 0; i < anz; i++ )
        {
            if( eintr�ge->z( i )->getKarteId() != ret )
                eintr�ge->z( i )->resetAuswahl();
        }
    }
    cs.unlock();
    me.mx = mx;
    me.my = my;
    return ret;
}

bool KartenKaufenListe::tick( double zeit )
{
    rend |= vScroll->getRend();
    cs.lock();
    int anz = eintr�ge->getEintragAnzahl();
    for( int i = 0; i < anz; i++ )
        rend |= eintr�ge->z( i )->tick( zeit );
    cs.unlock();
    bool ret = rend;
    rend = 0;
    return ret;
}

void KartenKaufenListe::render( Bild &zRObj )
{
    int br = ram->getBreite();
    int h� = ram->getHeight();
    if( !zRObj.setDrawOptions( pos.x, pos.y, br, h� ) )
        return;
    ram->render( zRObj );
    cs.lock();
    int anz = eintr�ge->getEintragAnzahl();
    for( int i = 0; i < anz; i++ )
        eintr�ge->z( i )->render( i * 100 - vScroll->getScroll(), zRObj );
    cs.unlock();
    vScroll->render( 200, 0, 15, 380, zRObj );
    zRObj.releaseDrawOptions();
}

// constant
int KartenKaufenListe::getEintragAnzahl()
{
    return eintr�ge->getEintragAnzahl();
}

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

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


// Inhalt der KartenKaufen Klasse aus KartenKaufen.h
// Konstruktor
KartenKaufen::KartenKaufen( Schrift *zSchrift )
    : Thread()
{
    Bild *shopZur�ck = bilder->get( "shop.ltdb/zur�ck.png" );
    if( !shopZur�ck )
    {
        LTDBDatei *datei = new LTDBDatei();
        datei->setDatei( new Text( "data/client/bilder/shop.ltdb" ) );
        datei->leseDaten( 0 );
        shopZur�ck = datei->laden( 0, new Text( "zur�ck.png" ) );
        datei->release();
        bilder->add( "shop.ltdb/zur�ck.png", shopZur�ck->getThis() );
    }
    Bild *shopWeiter = bilder->get( "shop.ltdb/weiter.png" );
    if( !shopWeiter )
    {
        LTDBDatei *datei = new LTDBDatei();
        datei->setDatei( new Text( "data/client/bilder/shop.ltdb" ) );
        datei->leseDaten( 0 );
        shopWeiter = datei->laden( 0, new Text( "weiter.png" ) );
        datei->release();
        bilder->add( "shop.ltdb/weiter.png", shopWeiter->getThis() );
    }
    alpha = 255;
    sichtbar = 0;
    suchText = new Text( "" );
    ram = new LRahmen();
    ram->setSize( 780, 440 );
    ram->setFarbe( 0xFFFFFFFF );
    pos = Punkt( 10, 50 );
    spielArt = new AuswahlBox();
    spielArt->setStyle( AuswahlBox::Style::AuswahlBuffer | AuswahlBox::Style::MausBuffer | AuswahlBox::Style::Erlaubt | AuswahlBox::Style::Hintergrund |
                        AuswahlBox::Style::Rahmen | AuswahlBox::Style::Sichtbar | AuswahlBox::Style::VScroll | AuswahlBox::Style::MaxHeight );
    spielArt->setSize( 200, 20 );
    spielArt->setPosition( 5, 5 );
    spielArt->setRahmenFarbe( 0xFFFFFFFF );
    spielArt->setRahmenBreite( 1 );
    spielArt->setMaxAuskappHeight( 100 );
    spielArt->setSchriftZ( zSchrift->getThis() );
    spielArt->setHintergrundFarbe( 0xFF000000 );
    spielArt->setMausEreignis( _ret1ME );
    spielArt->setAuswAlphaFeldFarbe( 0x5000FF00 );
    spielArt->setAuswAlphaFeldStrength( -10 );
    spielArt->setMausAlphaFeldFarbe( 0x1000FF00 );
    spielArt->setMausAlphaFeldStrength( -10 );
    spielArt->setEintragHeight( 20 );
    spielArt->addEintrag( "Spiel Art w�hlen" );
    suchFilterT = initTextFeld( 210, 5, 70, 20, zSchrift, TextFeld::Style::Text, "Suchfilter:" );
    suchFilter = initTextFeld( 285, 5, 225, 20, zSchrift, TextFeld::Style::TextFeld, "" );
    initToolTip( suchFilter, "Gebe etwas vom Namen der Karte ein, nach der du suchst.", zSchrift->getThis(), hauptScreen );
    suchen = initKnopf( 515, 5, 100, 20, zSchrift, Knopf::Style::Sichtbar, "suchen" );
    seiten = initTextFeld( 55, 30, 250, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, "Seite 0 von 0, 0 Funde." );
    zur�ck = initKnopf( 5, 30, 20, 20, 0, 0, "" );
    zur�ck->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
    zur�ck->setHintergrundBildZ( shopZur�ck );
    initToolTip( zur�ck, "Seite zur�ck bl�ttern.", zSchrift->getThis(), hauptScreen );
    weiter = initKnopf( 30, 30, 20, 20, 0, 0, "" );
    weiter->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
    weiter->setHintergrundBildZ( shopWeiter );
    initToolTip( weiter, "Seite weiter bl�ttern.", zSchrift->getThis(), hauptScreen );
    liste = new KartenKaufenListe( zSchrift->getThis() );
    auswahl = new KartenKaufenAuswahl( zSchrift );
    laden = ( Framework::Animation2D* )ladeAnimation->dublizieren();
    laden->setPosition( 365, 195 );
    laden->setSichtbar( 0 );
    tickVal = 0;
    seite = 0;
    maxSeite = 0;
    rend = 0;
    aktion = 0;
    ref = 1;
    start();
}

// Destruktor
KartenKaufen::~KartenKaufen()
{
    if( run )
        warteAufThread( 1000 );
    if( run )
        ende();
    spielArt->release();
    suchText->release();
    ram->release();
    suchFilterT->release();
    suchFilter->release();
    suchen->release();
    seiten->release();
    weiter->release();
    zur�ck->release();
    liste->release();
    auswahl->release();
    laden->release();
}

// nicht constant
void KartenKaufen::setSichtbar( bool sicht )
{
    sichtbar = sicht;
    if( !run && sichtbar )
    {
        aktion = 0;
        start();
    }
}

void KartenKaufen::thread()
{
    laden->setSichtbar( 1 );
    if( !aktion )
    {
        Array< int > *saList = infoClient->getAccountSpielArtListe();
        if( saList )
        {
            RCArray< Text > *saNamen = new RCArray< Text >();
            int anz = saList->getEintragAnzahl();
            for( int i = 0; i < anz; i++ )
            {
                if( !saList->hat( i ) )
                    continue;
                Text *name = infoClient->getSpielName( saList->hat( i ) ? saList->get( i ) : 0 );
                if( name )
                    saNamen->add( name );
            }
            spielArt->lockZeichnung();
            spielArt->setAuswahl( 0 );
            anz = spielArt->getEintragAnzahl();
            for( int i = 1; i < anz; i++ )
                spielArt->removeEintrag( 1 );
            anz = saNamen->getEintragAnzahl();
            for( int i = 0; i < anz; i++ )
            {
                if( saNamen->z( i ) )
                    spielArt->addEintrag( saNamen->z( i )->getText() );
            }
            spielArt->unlockZeichnung();
            saNamen->release();
            saList->release();
        }
        if( !liste->getEintragAnzahl() )
        {
            hauptScreen->lock();
            suchText->setText( suchFilter->zText()->getText() );
            seite = 1;
            maxSeite = 1;
            aktion = 1;
            hauptScreen->unlock();
        }
        if( !aktion )
        {
            laden->setSichtbar( 0 );
            return;
        }
    }
    int spielArtId = 0;
    if( spielArt->getAuswahl() > 0 )
        spielArtId = infoClient->getSpielId( spielArt->zEintrag( spielArt->getAuswahl() )->zText()->getText() );
    Array< int > *list = 0;
    if( !shopClient )
        shopClient = mainClient->createShopServerClient();
    if( shopClient && shopClient->verbinde() )
    {
        list = shopClient->suchKarten( suchText->getText(), spielArtId );
        shopClient->trenne( 0 );
    }
    if( !list )
    {
        laden->setSichtbar( 0 );
        run = 0;
        return;
    }
    Array< int > *slist = new Array< int >();
    int anz = list->getEintragAnzahl();
    maxSeite = anz / 10 + 1;
    if( !( anz % 10 ) )
        maxSeite--;
    while( anz <= seite * 10 && seite > 0 )
        seite--;
    for( int i = seite * 10; i < anz && i < seite * 10 + 10; i++ )
        slist->add( list->hat( i ) ? list->get( i ) : 0 );
    list->release();
    auswahl->reset();
    liste->ladeKarten( slist );
    slist->release();
    Text *t = new Text( "Seite " );
    t->append( maxSeite ? seite + 1 : 0 );
    t->append( " von " );
    t->append( maxSeite );
    t->append( ", " );
    t->append( anz );
    if( anz == 1 )
        t->append( " Fund." );
    else
        t->append( " Funde." );
    seiten->setText( t );
    zur�ck->setStyle( TextFeld::Style::Erlaubt, seite > 0 );
    weiter->setStyle( TextFeld::Style::Erlaubt, seite + 1 < maxSeite );
    laden->setSichtbar( 0 );
}

void KartenKaufen::doMausEreignis( MausEreignis &me )
{
    if( !sichtbar || run )
        return;
    int mx = me.mx;
    int my = me.my;
    me.mx -= pos.x;
    me.my -= pos.y;
    spielArt->doMausEreignis( me );
    suchFilter->doMausEreignis( me );
    int auswId = liste->doMausEreignis( me );
    if( auswId )
        auswahl->ladeKarteSeite( auswId );
    auswahl->doMausEreignis( me );
    int ak = 0;
    bool tmp = me.verarbeitet;
    suchen->doMausEreignis( me );
    ak = me.verarbeitet ? 1 : 0;
    zur�ck->doMausEreignis( me );
    ak = me.verarbeitet && !ak ? 2 : ak;
    weiter->doMausEreignis( me );
    ak = me.verarbeitet && !ak ? 3 : ak;
    if( tmp )
        ak = 0;
    if( me.id == ME_RLinks )
    {
        switch( ak )
        {
        case 1: // Suchen
            suchText->setText( suchFilter->zText()->getText() );
            seite = 1;
            maxSeite = 1;
            aktion = 1;
            start();
            break;
        case 2: // Seite zur�ck bl�ttern
            seite--;
            if( seite < 1 )
                seite = 1;
            aktion = 1;
            start();
            break;
        case 3: // Seite vorw�rts bl�ttern
            seite++;
            if( seite > maxSeite )
                seite = maxSeite;
            aktion = 1;
            start();
            break;
        }
    }
    me.mx = mx;
    me.my = my;
}

void KartenKaufen::doTastaturEreignis( TastaturEreignis &te )
{
    if( !sichtbar || run )
        return;
    bool vera = te.verarbeitet;
    suchFilter->doTastaturEreignis( te );
    if( !vera && te.verarbeitet && te.taste == T_Enter && te.id == TE_Release )
    {
        MausEreignis me;
        me.id = ME_RLinks;
        me.verarbeitet = 0;
        me.mx = suchen->getX() + 1 + pos.x;
        me.my = suchen->getY() + 1 + pos.y;
        doMausEreignis( me );
    }
    auswahl->doTastaturEreignis( te );
}

bool KartenKaufen::tick( double zeit )
{
    rend |= spielArt->tick( zeit );
    rend |= suchFilter->tick( zeit );
    rend |= suchen->tick( zeit );
    rend |= weiter->tick( zeit );
    rend |= zur�ck->tick( zeit );
    rend |= liste->tick( zeit );
    rend |= auswahl->tick( zeit );
    rend |= laden->tick( zeit );
    tickVal += zeit * 250;
    int val = (int)tickVal;
    if( val < 1 )
    {
        bool ret = rend;
        rend = 0;
        return ret;
    }
    if( val > 10 )
        val = 10;
    tickVal -= val;
    if( sichtbar && alpha != 255 && !run )
    {
        if( alpha + val > 255 )
            alpha = 255;
        else
            alpha += val;
        rend = 1;
    }
    if( sichtbar && alpha != 125 && run )
    {
        if( alpha > 125 )
        {
            if( alpha - val < 125 )
                alpha = 125;
            else
                alpha -= val;
            rend = 1;
        }
        else
        {
            if( alpha + val > 125 )
                alpha = 125;
            else
                alpha += 125;
            rend = 1;
        }
    }
    if( !sichtbar && alpha != 0 )
    {
        if( alpha - val < 0 )
            alpha = 0;
        else
            alpha -= val;
        rend = 1;
    }
    bool ret = rend;
    rend = 0;
    return ret;
}

void KartenKaufen::render( Bild &zRObj )
{
    if( !alpha )
        return;
    int br = ram->getBreite();
    int h� = ram->getHeight();
    if( !zRObj.setDrawOptions( pos.x, pos.y, br, h� ) )
        return;
    zRObj.setAlpha( alpha );
    ram->render( zRObj );
    suchFilterT->render( zRObj );
    suchFilter->render( zRObj );
    suchen->render( zRObj );
    seiten->render( zRObj );
    weiter->render( zRObj );
    zur�ck->render( zRObj );
    liste->render( zRObj );
    auswahl->render( zRObj );
    spielArt->render( zRObj );
    zRObj.releaseAlpha();
    laden->render( zRObj );
    zRObj.releaseDrawOptions();
}

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

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

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