#include "SpielAuswahl.h"
#include <Datei.h>
#include <Text.h>
#include <Schrift.h>
#include <Rahmen.h>
#include <Punkt.h>
#include <DateiSystem.h>
#include "..\..\..\Global\Initialisierung.h"
#include <AlphaFeld.h>
#include <MausEreignis.h>
#include <KSGTDatei.h>
#include "..\..\..\Global\Variablen.h"

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

SpielDaten::Loader::Loader( SpielDaten *sd, int aktion )
{
    this->sd = sd;
    this->aktion = aktion;
    beenden = 0;
    ref = 2;
    start();
}

void SpielDaten::Loader::setBeenden()
{
    beenden = 1;
}

void SpielDaten::Loader::thread()
{
    Text *pfad = new Text( "data/spiele/" );
    pfad->append( sd->name->getText() );
    pfad->append( "/data/game.ini" );
    if( !DateiExistiert( pfad->getThis() ) )
    {
        if( !aktion )
        {
            if( sd->aAnimation )
                sd->aAnimation->setSichtbar( 0 );
            sd->geladen = 0;
            sd->ausgew�hlt = 0;
            hauptScreen->lock();
            if( sd->aAnimation )
                sd->aAnimation = sd->aAnimation->release();
            hauptScreen->unlock();
            if( sd->hintergrund )
                sd->hintergrund = sd->hintergrund->release();
            if( sd->beschreibung )
            {
                sd->beschreibung->zur�cksetzen();
                sd->beschreibung = sd->beschreibung->release();
            }
            if( sd->ksgs )
            {
                dllDateien->releaseDLL( "KSGScript.dll" );
                sd->ksgs = 0;
            }
        }
        else
        {
            if( !sd->hintergrund )
                sd->hintergrund = new Bild();
            sd->hintergrund->neuBild( 200, 100, 0xFF000000 );
            sd->schrift->lock();
            sd->schrift->setSchriftSize( 12 );
            sd->schrift->setDrawPosition( 10, 10 );
            sd->schrift->renderText( sd->name, *sd->hintergrund, 0xFFFFFFFF );
            sd->schrift->unlock();
            if( !sd->geladen )
                sd->geladen = 1;
            sd->rend = 1;
            int dgId = infoClient->getDateiGruppeIdVonSpiel( sd->spielId );
            if( dgId )
            {
                KSGTDatei *dg = new KSGTDatei( "data/dg.ksgt" );
                dg->laden();
                bool gefunden = 0;
                for( int i = 0; i < dg->getZeilenAnzahl(); i++ )
                {
                    if( dg->zFeld( i, 0 ) && TextZuInt( dg->zFeld( i, 0 )->getText(), 10 ) == dgId )
                    {
                        gefunden = 1;
                        break;
                    }
                }
                if( !gefunden )
                {
                    for( int i = 0; i < dg->getZeilenAnzahl(); i++ )
                    {
                        if( dg->zFeld( i, 3 ) && !dg->zFeld( i, 3 )->istGleich( "SOFORT" ) && !dg->zFeld( i, 3 )->istGleich( "NICHT" ) )
                        {
                            int platz = TextZuInt( dg->zFeld( i, 3 )->getText(), 10 ) + 1;
                            Text *plT = new Text();
                            plT->append( platz );
                            dg->zFeld( i, 3 )->setText( plT );
                        }
                    }
                    Text *idT = new Text();
                    idT->append( dgId );
                    Text *pfad = infoClient->getDateiGruppePfad( dgId );
                    if( pfad )
                    {
                        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();
                    }
                    else
                        idT->release();
                }
                dg->speichern();
                dg->release();
            }
            if( aktion == 2 && !beenden )
            {
                if( sd->beschreibung )
                {
                    sd->beschreibung->zur�cksetzen();
                    sd->beschreibung = sd->beschreibung->release();
                }
                if( !sd->ksgs )
                    sd->ksgs = dllDateien->ladeDLL( "KSGScript.dll", "data/bin/KSGScript.dll" );
                if( sd->ksgs )
                {
                    KSGSGetZeichnung getKSGScript = (KSGSGetZeichnung)GetProcAddress( sd->ksgs, KSGS_START_FUNKTION );
                    if( getKSGScript )
                    {
                        sd->beschreibung = getKSGScript();
                        sd->beschreibung->setBildschirmZ( hauptScreen->getThis() );
                        sd->beschreibung->setSchriftZ( sd->schrift->getThis() );
                        sd->beschreibung->setSize( 578, 428 );
                        sd->beschreibung->setR�ckrufParam( sd );
                        sd->beschreibung->setR�ckrufFunktion( SpielAuswahlKSGSAktion );
                        sd->beschreibung->setScriptDatei( "data/script/SpielNichtAktuell.ksgs" );
                    }
                    else
                    {
                        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
                {
                    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 );
                }
                if( sd->beschreibung )
                    sd->geladen = 2;
                if( sd->beschreibung && sd->ksgs && sd->ausgew�hlt )
                    sd->beschreibung->neuLaden();
            }
        }
        pfad->release();
        sd->rend = 1;
        return;
    }
    Datei *ini = new Datei();
    ini->setDatei( pfad->getText() );
    ini->open( Datei::Style::lesen );
    if( !aktion )
    {
        if( sd->aAnimation )
            sd->aAnimation->setSichtbar( 0 );
        sd->geladen = 0;
        sd->ausgew�hlt = 0;
        hauptScreen->lock();
        if( sd->aAnimation )
            sd->aAnimation = sd->aAnimation->release();
        hauptScreen->unlock();
        if( sd->hintergrund )
            sd->hintergrund = sd->hintergrund->release();
        if( sd->beschreibung )
        {
            sd->beschreibung->zur�cksetzen();
            sd->beschreibung = sd->beschreibung->release();
        }
        if( sd->ksgs )
        {
            dllDateien->releaseDLL( "KSGScript.dll" );
            sd->ksgs = 0;
        }
        sd->rend = 1;
    }
    else
    {
        Text *pf = ini->leseZeile();
        pf->remove( pf->getLength() - 1 );
        pf->insert( 0, "/bilder/" );
        pf->insert( 0, sd->name->getText() );
        pf->insert( 0, "data/spiele/" );
        if( pf->hat( ".ltdb/" ) )
        {
            if( !sd->hintergrund )
            {
                LTDBDatei *bildDatei = new LTDBDatei();
                bildDatei->setDatei( pf->getTeilText( 0, pf->positionVon( ".ltdb" ) + 5 ) );
                bildDatei->leseDaten( 0 );
                sd->hintergrund = bildDatei->laden( 0, pf->getTeilText( pf->positionVon( ".ltdb" ) + 6 ) );
                bildDatei->release();
            }
        }
        else
        {
            if( !sd->hintergrund )
            {
                LTDBDatei *bildDatei = new LTDBDatei();
                bildDatei->setDatei( pf->getThis() );
                bildDatei->leseDaten( 0 );
                sd->hintergrund = bildDatei->laden( 0, bildDatei->zBildListe()->get( 0 ) );
                bildDatei->release();
            }
        }
        pf->release();
        pf = ini->leseZeile();
        pf->release();
        pf = ini->leseZeile();
        pf->remove( pf->getLength() - 1 );
        pf->insert( 0, "/data/" );
        pf->insert( 0, sd->name->getText() );
        pf->insert( 0, "data/spiele/" );
        Datei *idDatei = new Datei();
        idDatei->setDatei( pf->getText() );
        idDatei->open( Datei::Style::lesen );
        idDatei->lese( (char*)&sd->spielId, 4 );
        idDatei->close();
        idDatei->release();
        pf->release();
        if( !sd->geladen )
            sd->geladen = 1;
        sd->rend = 1;
        ini->setLPosition( 0, 0 );
        if( aktion == 2 && !beenden )
        {
            pf = ini->leseZeile();
            pf->remove( pf->getLength() - 1 );
            pf->insert( 0, "/bilder/" );
            pf->insert( 0, sd->name->getText() );
            pf->insert( 0, "data/spiele/" );
            if( !pf->hat( ".ltdb/" ) )
            {
                LTDBDatei *add = new LTDBDatei();
                add->setDatei( pf->getThis() );
                add->leseDaten( 0 );
                Animation2DData *ad = new Animation2DData();
                ad->ladeAnimation( add );
                ad->setWiederhohlend( 1 );
                ad->setFPS( 30 );
                hauptScreen->lock();
                if( sd->aAnimation )
                    sd->aAnimation = sd->aAnimation->release();
                sd->aAnimation = new Animation2D();
                hauptScreen->unlock();
                sd->aAnimation->setSize( 200, 100 );
                sd->aAnimation->setPosition( 0, 0 );
                sd->aAnimation->setAnimationDataZ( ad );
            }
            pf->release();
            pf = ini->leseZeile();
            pf->remove( pf->getLength() - 1 );
            pf->insert( 0, "/data/" );
            pf->insert( 0, sd->name->getText() );
            pf->insert( 0, "data/spiele/" );
            if( sd->beschreibung )
            {
                sd->beschreibung->zur�cksetzen();
                sd->beschreibung = sd->beschreibung->release();
            }
            if( !sd->ksgs )
                sd->ksgs = dllDateien->ladeDLL( "KSGScript.dll", "data/bin/KSGScript.dll" );
            if( sd->ksgs )
            {
                KSGSGetZeichnung getKSGScript = (KSGSGetZeichnung)GetProcAddress( sd->ksgs, KSGS_START_FUNKTION );
                if( getKSGScript )
                {
                    sd->beschreibung = getKSGScript();
                    sd->beschreibung->setBildschirmZ( hauptScreen->getThis() );
                    sd->beschreibung->setSchriftZ( sd->schrift->getThis() );
                    sd->beschreibung->setSize( 578, 428 );
                    sd->beschreibung->setR�ckrufParam( sd );
                    sd->beschreibung->setR�ckrufFunktion( SpielAuswahlKSGSAktion );
                    sd->beschreibung->setScriptDatei( pf->getText() );
                }
                else
                {
                    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
            {
                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 );
            }
            pf->release();
            if( sd->beschreibung )
                sd->geladen = 2;
            if( sd->beschreibung && sd->ksgs && sd->ausgew�hlt )
                sd->beschreibung->neuLaden();
            sd->rend = 1;
        }
    }
    pfad->release();
    ini->close();
    ini->release();
    if( !sd->erlaubt )
        sd->updateErlaubt();
    sd->rend = 1;
    release();
}

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

int SpielDaten::Loader::getAktion() const
{
    return aktion;
}

// Inhalt der SpielDaten Klasse aus SpielAuswahl.h
// Konstruktor
SpielDaten::SpielDaten( Schrift *zSchrift, const char *name, int id )
{
    this->name = new Text( name );
    hintergrund = 0;
    aAnimation = 0;
    beschreibung = 0;
    ksgs = 0;
    rahmen = new LRahmen();
    rahmen->setFarbe( 0xFFFFFFFF );
    rahmen->setRamenBreite( 1 );
    tickVal = 0;
    animation = 0;
    ausgew�hlt = 0;
    pos = Punkt( 0, 500 );
    gr = Punkt( 200, 100 );
    schrift = zSchrift->getThis();
    spielId = id;
    geladen = 0;
    erlaubt = 0;
    auswahl = new AlphaFeld();
    auswahl->setFarbe( 0x0000FF00 );
    auswahl->setStrength( 8 );
    auswahl->setSize( 200, 100 );
    ladenBild = 0;
    rend = 0;
    ref = 1;
    alpha = 0;
    tAlpha = 0;
    loader = new Loader( this, 1 );
}

// Destruktor
SpielDaten::~SpielDaten()
{
    if( loader && loader->isRunning() )
        loader->warteAufThread( INT_MAX );
    loader->release();
    if( schrift )
        schrift->release();
    name->release();
    if( hintergrund )
        hintergrund->release();
    if( aAnimation )
        aAnimation->release();
    if( beschreibung )
    {
        beschreibung->zur�cksetzen();
        beschreibung->release();
    }
    if( ksgs )
    {
        dllDateien->releaseDLL( "KSGScript.dll" );
        ksgs = 0;
    }
    rahmen->release();
    auswahl->release();
}

// nicht constant
void SpielDaten::ksgsAktion( RCArray< KSGSVariable > *parameter, KSGSVariable **retVal )
{}

void SpielDaten::setSichtbar( bool sichtbar )
{
    if( sichtbar )
        animation |= 0x1;
    else
    {
        animation &= ~0x1;
        setAuswahl( 0 );
        auswahl->setFarbe( auswahl->getFarbe() & 0xFFFFFF );
    }
    if( !erlaubt && sichtbar && ausgew�hlt )
        updateH->setSichtbar( spielId, 1 );
    hauptScreen->lock();
    if( loader->getAktion() == (sichtbar ? 2 : 0) )
    {
        hauptScreen->unlock();
        rend = 1;
        return;
    }
    loader->setBeenden();
    Loader *altLoader = loader;
    loader = new Loader( this, sichtbar ? 2 : 0 );
    altLoader->release();
    hauptScreen->unlock();
    rend = 1;
}

void SpielDaten::setSichtbar()
{
    animation |= 1;
    if( ausgew�hlt && geladen == 2 )
    {
        animation |= 0x4;
        beschreibung->setPosition( beschreibung->getX(), 0 );
    }
    if( !erlaubt && ausgew�hlt )
        updateH->setSichtbar( spielId, 1 );
    hauptScreen->lock();
    if( geladen != 2 && loader->getAktion() != 2 )
    {
        Loader *altLoader = loader;
        loader = new Loader( this, 2 );
        altLoader->release();
    }
    hauptScreen->unlock();
    rend = 1;
}

void SpielDaten::setAuswahl( bool auswahl )
{
    if( ausgew�hlt == auswahl )
        return;
    ausgew�hlt = auswahl;
    if( auswahl )
    {
        if( aAnimation )
            aAnimation->setSichtbar( 1 );
        if( beschreibung && ksgs )
            beschreibung->neuLaden();
        animation |= 0x4;
    }
    else
        animation &= ~0x4;
    if( !erlaubt && ausgew�hlt )
        updateH->setSichtbar( spielId, 1 );
    if( !erlaubt && !ausgew�hlt )
        updateH->setSichtbar( spielId, 0 );
    rend = 1;
}

void SpielDaten::updateErlaubt()
{
    bool update = erlaubt;
    erlaubt = 0;
    KSGTDatei *dgt = new KSGTDatei( "data/dg.ksgt" );
    dgt->laden();
    bool ak = 0;
    int dgId = infoClient->getDateiGruppeIdVonSpiel( spielId );
    for( int i = 0; i < dgt->getZeilenAnzahl(); i++ )
    {
        if( dgt->zFeld( i, 0 ) && TextZuInt( dgt->zFeld( i, 0 )->getText(), 10 ) == dgId )
        {
            int lv = dgt->zFeld( i, 2 ) ? TextZuInt( dgt->zFeld( i, 2 )->getText(), 10 ) : 0;
            int ov = infoClient->getSpielVersion( spielId );
            if( lv == ov )
                ak = 1;
            break;
        }
    }
    dgt->release();
    erlaubt = ak && infoClient->istSpielErlaubt( spielId );
    if( !erlaubt && !updateH->hat( spielId ) )
    {
        updateH->erstellen( schrift, spielId );
        if( ausgew�hlt )
            updateH->setSichtbar( spielId, 1 );
    }
    if( erlaubt && updateH->hat( spielId ) )
        updateH->remove( spielId, 0 );
}

void SpielDaten::setPosition( int lPos )
{
    pos.y = lPos * 100;
    rend = 1;
}

bool SpielDaten::tick( double tickVal )
{
    if( beschreibung )
        rend |= beschreibung->tick( tickVal );
    if( !erlaubt )
        rend |= updateH->tick( spielId, tickVal );
    this->tickVal += tickVal * 500;
    int val = ( int ) this->tickVal;
    if( val < 1 )
    {
        bool ret = rend;
        rend = 0;
        return ret;
    }
    if( val > 17 )
        val = 17;
    this->tickVal -= val;
    if( aAnimation && geladen == 2 && aAnimation->istSichtbar() )
    {
        if( aAnimation->getJetzt() + 1 >= aAnimation->zAnimationData()->getBildAnzahl() )
        {
            rend |= aAnimation->tick( tickVal );
            if( aAnimation->getJetzt() + 1 < aAnimation->zAnimationData()->getBildAnzahl() )
                aAnimation->setSichtbar( 0 );
        }
        else
            rend |= aAnimation->tick( tickVal );
    }
    if( ausgew�hlt )
    {
        int a = ( auswahl->getFarbe() >> 24 ) & 0xFF;
        if( a != 150 )
        {
            if( a + val > 150 )
                a = 150;
            else
                a += val;
            auswahl->setFarbe( ( ( a << 24 ) & 0xFF000000 ) | ( auswahl->getFarbe() & 0xFFFFFF ) );
            rend = 1;
        }
    }
    else
    {
        int a = ( auswahl->getFarbe() >> 24 ) & 0xFF;
        if( a != 0 )
        {
            if( a - val < 0 )
                a = 0;
            else
                a -= val;
            auswahl->setFarbe( ( ( a << 24 ) & 0xFF000000 ) | ( auswahl->getFarbe() & 0xFFFFFF ) );
            rend = 1;
        }
    }
    if( ( animation | 0x1 ) == animation ) // sichtbar
    {
        if( tAlpha != 255 )
        {
            if( tAlpha + val > 255 )
                tAlpha = 255;
            else
                tAlpha += val;
            rend = 1;
        }
    }
    else // unsichtbar
    {
        if( tAlpha != 0 )
        {
            if( tAlpha - val < 0 )
                tAlpha = 0;
            else
                tAlpha -= val;
            rend = 1;
        }
    }
    if( geladen == 2 )
    {
        if( ( animation | 0x4 ) == animation ) // ausw�hlen
        {
            if( beschreibung )
            {
                if( alpha != 255 )
                {
                    if( alpha + val < 255 )
                        alpha += val;
                    else
                        alpha = 255;
                    rend = 1;
                }
            }
        }
        else // abw�hlen
        {
            int a = ( auswahl->getFarbe() >> 24 ) & 0xFF;
            if( a != 0 )
            {
                a -= val;
                if( a < 0 )
                    a = 0;
                auswahl->setFarbe( ( ( a << 24 ) & 0xFF000000 ) | ( auswahl->getFarbe() & 0xFFFFFF ) );
                rend = 1;
            }
            if( beschreibung )
            {
                if( alpha != 0 )
                {
                    if( alpha - val > 0 )
                        alpha -= val;
                    else
                        alpha = 0;
                    rend = 1;
                }
            }
        }
    }
    bool ret = rend;
    rend = 0;
    return ret;
}

void SpielDaten::doMausEreignis( MausEreignis &me )
{
    if( !erlaubt && ausgew�hlt )
    {
        me.mx -= gr.x + 90;
        me.my -= 350;
        updateH->doMausEreignis( spielId, me );
        me.my += 350;
        me.mx += 90;
        if( beschreibung )
            beschreibung->doMausEreignis( me );
        me.mx += gr.x;
    }
}

void SpielDaten::render( Bild &zRObj )
{
    int x = pos.x;
    int y = pos.y;
    int br = gr.x;
    int h� = gr.y;
    if( !zRObj.setDrawOptions( x, y, br, h� ) )
        return;
    zRObj.setAlpha( tAlpha );
    rahmen->setSize( br, h� );
    int rbr = rahmen->getRBreite();
    if( geladen && hintergrund && ( !( ausgew�hlt && geladen == 2 && aAnimation ) || !aAnimation->istSichtbar() ) )
        zRObj.drawBild( rbr, rbr, br - rbr * 2, h� - rbr * 2, *hintergrund );
    if( aAnimation )
        aAnimation->render( zRObj );
    rahmen->render( zRObj );
    if( auswahl && ( ( auswahl->getFarbe() >> 24 ) & 0xFF ) && ( !( ausgew�hlt && geladen == 2 && aAnimation ) || !aAnimation->istSichtbar() ) )
    {
        auswahl->setPosition( rbr, rbr );
        auswahl->setSize( br - rbr * 2, h� - rbr * 2 );
        auswahl->render( zRObj );
    }
    zRObj.releaseDrawOptions();
    x = br;
    y = 0;
    br = 580;
    h� = 480;
    if( !zRObj.setDrawOptions( x, y, br, h� ) )
    {
        zRObj.releaseAlpha();
        return;
    }
    if( geladen == 2 && beschreibung )
    {
        zRObj.setAlpha( alpha );
        beschreibung->render( zRObj );
        zRObj.releaseAlpha();
    }
    if( !erlaubt )
        updateH->render( spielId, 90, 350, zRObj );
    if( ausgew�hlt && geladen != 2 && ladeAnimation->zAnimationData() )
    {
        ladenBild++;
        if( ladenBild >= ladeAnimation->zAnimationData()->getBildAnzahl() )
            ladenBild = 0;
        zRObj.drawBild( 275, 195, 50, 50, *ladeAnimation->zAnimationData()->zBild( ladenBild ) );
        rend = 1;
    }
    zRObj.releaseDrawOptions();
    zRObj.releaseAlpha();
}

// constant
int SpielDaten::getSpielId() const
{
    return spielId;
}

bool SpielDaten::istausgew�hlt() const
{
    return ausgew�hlt;
}

Text *SpielDaten::zName() const
{
    return name;
}

bool SpielDaten::istErlaubt() const
{
    return erlaubt;
}

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

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

// Inhalt der SpielAuswahl Klasse aus SpielAuswahl.h
// Konstruktor
SpielAuswahlFenster::SpielAuswahlFenster( Schrift *zSchrift )
    : Thread()
{
    schrift = zSchrift->getThis();
    rahmen = new LRahmen();
    rahmen->setFarbe( 0xFFFFFFFF );
    rahmen->setRamenBreite( 1 );
    rahmen->setSize( 760, 500 );
    members = new RCArray< SpielDaten >();
    anzahl = 0;
    animation = 0;
    auswahl = -1;
    tickVal = 0;
    seite = 0;
    pos = Punkt( 10, 10 );
    gr = Punkt( 780, 430 );
    rend = 0;
    ref = 1;
    alpha = 0;
    start();
}

// Destruktor
SpielAuswahlFenster::~SpielAuswahlFenster()
{
    if( run )
    {
        warteAufThread( 5000 );
        ende();
    }
    if( schrift )
        schrift->release();
    if( rahmen )
        rahmen->release();
    if( members )
        members->release();
}

// nicht constant
void SpielAuswahlFenster::setSichtbar( bool sichtbar )
{
    if( sichtbar )
    {
        animation |= 0x1;
        start();
    }
    else
    {
        auswahl = -1;
        for( int i = seite * 4; i >= 0 && i < anzahl && i < seite * 4 + 4; i++ )
            members->z( i )->setSichtbar( 0 );
        animation &= ~0x1;
    }
    rend = 1;
}

void SpielAuswahlFenster::bl�ttern( bool oben )
{
    for( int i = seite * 4; i >= 0 && i < anzahl && i < seite * 4 + 4; i++ )
        members->z( i )->setSichtbar( 0 );
    seite += oben ? 1 : -1;
    for( int i = seite * 4; i >= 0 && i < anzahl && i < seite * 4 + 4; i++ )
    {
        members->z( i )->setPosition( i % 4 );
        members->z( i )->setSichtbar( 1 );
    }
    auswahl = -1;
    rend = 1;
}

void SpielAuswahlFenster::updateListe()
{
    if( run )
        return;
    start();
}

void SpielAuswahlFenster::thread()
{
    Array< int > *liste = infoClient->getAccountSpielArtListe();
    if( !liste )
    {
        nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( infoClient->getLetzterFehler() ),
                                                      new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
        run = 0;
        return;
    }
    int anz = liste->getEintragAnzahl();
    for( int i = 0; i < anz; i++ )
    {
        Text *name = infoClient->getSpielName( liste->hat( i ) ? liste->get( i ) : 0 );
        if( name )
        {
            bool gefunden = 0;
            for( int j = 0; j < anzahl; j++ )
            {
                SpielDaten *tmp = members->z( j );
                if( liste->hat( i ) && tmp->getSpielId() == liste->get( i ) )
                {
                    gefunden = 1;
                    break;
                }
            }
            if( !gefunden )
            {
                SpielDaten *tmp = new SpielDaten( schrift, name->getText(), liste->hat( i ) ? liste->get( i ) : 0 );
                members->add( tmp, anzahl );
                anzahl++;
            }
            name->release();
        }
    }
    if( liste )
        liste->release();
    for( int i = 0; i < anzahl; i++ )
        members->z( i )->updateErlaubt();
    for( int i = seite * 4; i < anzahl && i >= 0 && i < seite * 4 + 4; i++ )
    {
        members->z( i )->setPosition( i % 4 );
        members->z( i )->setSichtbar();
    }
    rend = 1;
    run = 0;
}

bool SpielAuswahlFenster::tick( double tickVal )
{
    for( int i = 0; i < anzahl; i++ )
        rend |= members->z( i )->tick( tickVal );
    this->tickVal += tickVal * 750;
    int val = ( int )this->tickVal;
    if( val < 1 )
    {
        bool ret = rend;
        rend = 0;
        return ret;
    }
    if( val > 25 )
        val = 25;
    this->tickVal -= val;
    if( ( animation | 0x1 ) == animation ) // sichtbar
    {
        if( alpha < 255 )
        {
            if( alpha + val >= 255 )
            {
                alpha = 255;
                for( int i = seite * 4; i < anzahl && i >= 0 && i < seite * 4 + 4; i++ )
                {
                    members->z( i )->setPosition( i % 4 );
                    members->z( i )->setSichtbar( 1 );
                }
            }
            else
                alpha += val;
            rend = 1;
        }
    }
    else // unsichtbar
    {
        if( alpha > 0 )
        {
            if( alpha - val < 0 )
                alpha = 0;
            else
                alpha -= val;
            rend = 1;
        }
    }
    bool ret = rend;
    rend = 0;
    return ret;
}

void SpielAuswahlFenster::doMausEreignis( MausEreignis &me )
{
    if( pos.x != 10 )
        return;
    me.mx -= pos.x;
    me.my -= pos.y;
    for( int i = 0; i < anzahl; i++ )
        members->z( i )->doMausEreignis( me );
    if( me.mx < 0 || me.my < 0 )
    {
        me.mx += pos.x;
        me.my += pos.y;
        return;
    }
    if( me.mx > 200 || me.my > getAnzahlAufSeite() * 100 )
    {
        me.mx += pos.x;
        me.my += pos.y;
        return;
    }
    if( me.id == ME_RLinks )
    {
        int treffer = me.my / 100 + seite * 4;
        if( treffer >= anzahl )
        {
            me.mx += pos.x;
            me.my += pos.y;
            return;
        }
        if( treffer == auswahl )
        {
            me.mx += pos.x;
            me.my += pos.y;
            return;
        }
        if( auswahl >= 0 )
            members->z( auswahl )->setAuswahl( 0 );
        members->z( treffer )->setAuswahl( 1 );
        auswahl = treffer;
        rend = 1;
    }
    me.mx += pos.x;
    me.my += pos.y;
}

void SpielAuswahlFenster::render( Bild &zrObj )
{
    int x = pos.x;
    int y = pos.y;
    int br = gr.x;
    int h� = gr.y;
    if( !zrObj.setDrawOptions( x, y, br, h� ) )
        return;
    zrObj.setAlpha( alpha );
    rahmen->setSize( br, h� );
    rahmen->render( zrObj );
    int rbr = rahmen->getRBreite();
    if( !zrObj.setDrawOptions( rbr, rbr, br - rbr * 2, h� - rbr * 2 ) )
    {
        zrObj.releaseDrawOptions();
        zrObj.releaseAlpha();
        return;
    }
    for( int i = seite * 4; i >= 0 && i < anzahl && i < seite * 4 + 4; i++ )
        members->z( i )->render( zrObj );
    zrObj.releaseDrawOptions();
    if( !anzahl )
    {
        Text t = "Dieser Account besitzt momentan noch keine Spiele.\nBesuche den Shop um neue Spiele zu erwerben!";
        schrift->lock();
        schrift->setDrawPosition( 10, 10 );
        schrift->setSchriftSize( 12 );
        schrift->renderText( &t, zrObj, 0xFFFFFFFF );
        schrift->unlock();
    }
    zrObj.releaseDrawOptions();
    zrObj.releaseAlpha();
}

// constant
int SpielAuswahlFenster::getAnzahl() const
{
    return anzahl;
}

int SpielAuswahlFenster::getSeiteAnzahl() const
{
    return ( anzahl / 4.0 == anzahl / 4 ) ? ( anzahl / 4 ) : ( anzahl / 4 + 1 );
}

int SpielAuswahlFenster::getSeite() const
{
    return seite;
}

int SpielAuswahlFenster::getAnzahlAufSeite() const
{
    return ( anzahl < seite * 4 + 4 ) ? ( anzahl - seite * 4 ) : 4;
}

bool SpielAuswahlFenster::hatAuswahl() const
{
    return auswahl != -1;
}

SpielDaten *SpielAuswahlFenster::getAuswahl() const
{
    return members->get( auswahl );
}

SpielDaten *SpielAuswahlFenster::zAuswahl() const
{
    return members->z( auswahl );
}

bool SpielAuswahlFenster::istAuswahlErlubt() const
{
    return auswahl != -1 && members->z( auswahl )->istErlaubt();
}

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

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