#include "PatchServer.h"
#include <TextFeld.h>
#include <MausEreignis.h>
#include "..\..\Login\Login.h"
#include <Datei.h>
#include <iostream>

// Inhalt der PSUpdate Klasse aus PatchServer.h
// Kontruktor
PSUpdate::PSUpdate( PatchServer *zPSA, AdminAccount *account )
{
    this->account = account;
    this->zPSA = zPSA;
    gruppeAnzahl = 0;
    gruppeId = 0;
    this->psc = 0;
    id = 0;
    ref = 1;
}

// Destruktor
PSUpdate::~PSUpdate()
{
    ende();
    if( psc )
    {
        psc->abbruch();
        psc->release();
    }
    account->release();
    delete[] gruppeId;
}

// nicht constant
void PSUpdate::setServer( const char *ip, unsigned short port )
{
    if( psc )
    {
        psc->abbruch();
        psc->release();
    }
    psc = new PSKlient( ip, port );
}

void PSUpdate::setUpdateListe( int gAnzahl, Array< int > *gId )
{
    gruppeAnzahl = gAnzahl;
    delete[] gruppeId;
    gruppeId = 0;
    if( gAnzahl )
    {
        gruppeId = new int[ gAnzahl ];
        for( int i = 0; i < gAnzahl; i++ )
            gruppeId[ i ] = gId->get( i );
    }
}

void PSUpdate::thread()
{
    if( !psc )
    {
        for( int g = 0; g < gruppeAnzahl; g++ )
            zPSA->setUpdateFertig( 1, gruppeId[ g ] );
        return;
    }
    if( !psc->login( account->zName()->getText(), account->zPasswort()->getText() ) )
    {
        for( int g = 0; g < gruppeAnzahl; g++ )
            zPSA->setUpdateFertig( 1, gruppeId[ g ] );
        return;
    }
    Array< FileGroupInfo* > fileGroupList;
    psc->getFileGroupInfoList( &fileGroupList );
    RCArray< ReferenceCounting< std::pair< int, Text > > > systemT;
    psc->getSystemInfoList( &systemT );
    int gAnz = fileGroupList.getEintragAnzahl();
    for( int g = 0; g < gruppeAnzahl; g++ )
    {
        Text *initPfad = new Text( "data/" );
        for( int i = 0; i < gAnz; i++ )
        {
            if( gruppeId[ g ] == fileGroupList.get( i )->id )
            {
                initPfad->append( (char*)fileGroupList.get( i )->name );
                break;
            }
        }
        initPfad->append( ".ini" );
        InitDatei *systemInit = new InitDatei( initPfad );
        systemInit->laden();
        bool cont = 0;
        int sAnz = systemT.getEintragAnzahl();
        for( int i = 0; i < sAnz; i++ ) // Prüfen, ob Lokale Version aktuell ist
        {
            if( !systemInit->wertExistiert( systemT.z( i )->second ) )
            {
                systemInit->release();
                zPSA->setUpdateFertig( 1, gruppeId[ g ] );
                cont = 1;
                break;
            }
            Text *pfad = new Text( systemInit->zWert( (char*)systemT.z( i )->second )->getText() );
            pfad->append( "/" );
            RCArray< ReferenceCounting< FileInfo > > dateiT;
            psc->getFileInfoList( systemT.z( i )->first, gruppeId[ g ], &dateiT );
            int dAnz = dateiT.getEintragAnzahl();
            bool br = 0;
            for( int j = 0; j < dAnz; j++ )
            {
                Text *pf = new Text( pfad->getText() );
                pf->append( dateiT.z( j )->path.getText() );
                if( !DateiExistiert( pf->getThis() ) )
                {
                    pfad->release();
                    pf->release();
                    systemInit->release();
                    zPSA->setUpdateFertig( 1, gruppeId[ g ] );
                    cont = 1;
                    br = 1;
                    break;
                }
                if( !DateiIstVerzeichnis( pf->getThis() ) )
                {
                    Datei *d = new Datei();
                    d->setDatei( pf->getText() );
                    Zeit *zeit = d->getLastChange();
                    d->release();
                    if( !zeit->istGleich( "y-m-d h:i:s", dateiT.z( j )->time.getText() ) )
                    {
                        zeit->release();
                        pfad->release();
                        pf->release();
                        systemInit->release();
                        zPSA->setUpdateFertig( 1, gruppeId[ g ] );
                        cont = 1;
                        br = 1;
                        break;
                    }
                    zeit->release();
                }
                pf->release();
            }
            if( br )
                break;
            pfad->release();
        }
        if( cont )
            continue;
        if( psc->updateStarten( gruppeId[ g ] ) )
        {
            RCArray< Text > *systemA = new RCArray< Text >();
            RCArray< RCArray< Text > > *dateiA = new RCArray< RCArray< Text > >();
            Array< int > *dateiAnzahlA = new Array< int >();
            int systemAnzahl = 0;
            bool ok = psc->getDateiListe( &systemAnzahl, dateiAnzahlA, systemA, dateiA );
            if( !ok )
            {
                systemA->release();
                dateiA->release();
                dateiAnzahlA->release();
                systemInit->release();
                zPSA->setUpdateFertig( 1, gruppeId[ g ] );
                continue;
            }
            __int64 maxAktionen = 0;
            for( int i = 0; i < systemAnzahl; i++ )
            {
                for( int j = 0; j < dateiAnzahlA->get( i ); j++ )
                {
                    Text *pfad = new Text( systemInit->zWert( systemA->z( i )->getText() )->getText() );
                    pfad->append( "/" );
                    pfad->append( dateiA->z( i )->z( j )->getText() );
                    Datei *d = new Datei();
                    d->setDatei( pfad );
                    if( !d->istOrdner() )
                        maxAktionen += d->getSize();
                    d->release();
                }
            }
            __int64 aktionen = 0;
            int prozent = 0;
            bool br = 0;
            for( int i = 0; i < systemAnzahl; i++ )
            {
                for( int j = 0; j < dateiAnzahlA->get( i ); j++ )
                {
                    Text *pfad = new Text( systemInit->zWert( systemA->z( i )->getText() )->getText() );
                    pfad->append( "/" );
                    pfad->append( dateiA->z( i )->z( j )->getText() );
                    Datei *d = new Datei();
                    d->setDatei( pfad );
                    if( d->istOrdner() )
                    {
                        d->release();
                        continue;
                    }
                    __int64 gr = d->getSize();
                    d->open( Datei::Style::lesen );
                    int version;
                    int system = 0;
                    for( int s = 0; s < sAnz; s++ )
                    {
                        if( systemT.z( s )->second.istGleich( systemA->z( i )->getText() ) )
                            system = systemT.z( s )->first;
                    }
                    psc->getFileVersion( dateiA->z( i )->z( j )->getText(), system, gruppeId[ g ], &version );
                    psc->lock();
                    psc->zKlient()->sende( "\xE", 1 );
                    char ret = 0;
                    psc->zKlient()->getNachricht( &ret, 1 );
                    if( ret == 1 )
                    {
                        psc->zKlient()->sende( (char*)&system, 4 );
                        psc->zKlient()->sende( (char*)&version, 4 );
                        short län = dateiA->z( i )->z( j )->getLength();
                        psc->zKlient()->sende( (char*)&län, 2 );
                        psc->zKlient()->sende( dateiA->z( i )->z( j )->getText(), län );
                        psc->zKlient()->getNachricht( &ret, 1 );
                        if( ret == 1 )
                        {
                            while( gr )
                            {
                                if( gr >= 2048 )
                                {
                                    gr -= 2048;
                                    län = 2048;
                                }
                                else
                                {
                                    län = (int)gr;
                                    gr = 0;
                                }
                                if( län < 0 )
                                    break;
                                psc->zKlient()->sende( (char*)&län, 2 );
                                char *buff = new char[ län ];
                                d->lese( buff, län );
                                psc->zKlient()->sende( buff, län );
                                delete[] buff;
                                aktionen += län;
                                if( prozent != 100 / ( maxAktionen / (long double)aktionen ) )
                                {
                                    prozent = (int)( 100 / ( maxAktionen / (long double)aktionen ) );
                                    zPSA->setUpdateProzent( prozent, gruppeId[ g ] );
                                }
                            }
                            psc->zKlient()->sende( "\0\0", 2 );
                            psc->zKlient()->getNachricht( &ret, 1 );
                        }
                    }
                    if( prozent != 100 / ( maxAktionen / (long double)aktionen ) )
                    {
                        prozent = (int)( 100 / ( maxAktionen / (long double)aktionen ) );
                        zPSA->setUpdateProzent( prozent, gruppeId[ g ] );
                    }
                    if( ret == 3 )
                    {
                        d->close();
                        d->release();
                        systemA->release();
                        dateiA->release();
                        dateiAnzahlA->release();
                        char l = 0;
                        psc->zKlient()->getNachricht( &l, 1 );
                        char *txt = new char[ l + 1 ];
                        txt[ l ] = 0;
                        if( l )
                            psc->zKlient()->getNachricht( txt, l );
                        std::cout << "Error: " << txt << "\n";
                        delete[] txt;
                        psc->unlock();
                        zPSA->setUpdateProzent( 0, gruppeId[ g ] );
                        zPSA->setUpdateFertig( 1, gruppeId[ g ] );
                        br = 1;
                        break;
                    }
                    psc->unlock();
                    d->close();
                    d->release();
                }
                if( br )
                    break;
            }
            if( br )
                continue;
            psc->updateFertig();
            systemA->release();
            dateiA->release();
            dateiAnzahlA->release();
        }
        else
        {
            systemInit->release();
            zPSA->setUpdateProzent( 0, gruppeId[ g ] );
            zPSA->setUpdateFertig( 1, gruppeId[ g ] );
            continue;
        }
        zPSA->setUpdateProzent( 0, gruppeId[ g ] );
        zPSA->setUpdateFertig( 0, gruppeId[ g ] );
        systemInit->release();
    }
    for( int i = 0; i < gAnz; i++ )
        delete fileGroupList.get( i );
    zPSA->setUpdateFertig( 0, 0 );
    run = 0;
}

// constant

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

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


// Inhalt der PSDetails Klasse aus PatchServer.h
// Konstruktor
PSDetails::PSDetails( PatchServer *zPSA, MSKlient *mk )
{
    this->zPSA = zPSA;
    this->mk = mk;
    id = 0;
    ref = 1;
}

// Destruktor
PSDetails::~PSDetails()
{
    ende();
    mk->release();
}

// nicht constant
void PSDetails::setServerId( int id )
{
    this->id = id;
}

void PSDetails::thread()
{
    ServerDetails detail;
    mk->getPatchServerDetails( id, &detail );
    if( !mk->getPatchServerDetails( id, &detail ) )
    {
        Text *err = new Text( "Fehler: Server Rückgabe: " );
        err->append( mk->getLetzterFehler() );
        zPSA->setServerDetails( id, "", "", 0, 0, 0, 0, -2, err );
    }
    else
    {
        PSKlient *psc = new PSKlient( detail.ip, detail.adminPort );
        int st = psc->getStatus();
        if( st >= 0 )
            psc->trenne();
        psc->release();
        zPSA->setServerDetails( id,
                                detail.name,
                                detail.ip,
                                detail.port,
                                detail.adminPort,
                                detail.tasks,
                                detail.maxTasks,
                                st,
                                0 );
    }
    run = 0;
}

// constant

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

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


// Inhalt der PSSuche Klasse aus PatchServer.h
// Konstruktor
PSSuche::PSSuche( PatchServer *zPSA, MSKlient *mk )
{
    this->zPSA = zPSA;
    this->mk = mk;
    ref = 1;
}

// Destruktor
PSSuche::~PSSuche()
{
    ende();
    mk->release();
}

// nicht constant
void PSSuche::thread()
{
    Array< ServerData* > list;
    if( mk->getPatchServerListe( &list ) )
    {
        int anz = list.getEintragAnzahl();
        for( int i = 0; i < anz; i++ )
        {
            int st = -1;
            ServerData *s = list.get( i );
            if( !s->status.istGleich( "Unerreichbar" ) )
            {
                PSKlient *psc = new PSKlient( s->ip.getText(), s->adminPort );
                st = psc->getStatus();
                switch( st )
                {
                case -2:
                    s->status = "Unbekannt";
                    break;
                case -1:
                    s->status = "Unerreichbar";
                    break;
                case 0:
                    s->status = "Offline";
                    break;
                case 1:
                    s->status = "Pausiert";
                    break;
                case 2:
                    s->status = "Online";
                    break;
                case 3:
                    s->status = "Veraltet";
                    break;
                }
                if( st >= 0 )
                    psc->trenne();
                psc->release();
            }
            zPSA->addServer( s->id,
                             s->name,
                             s->ip,
                             s->port,
                             s->adminPort,
                             s->status );
            delete s;
        }
    }
    zPSA->sucheAbgeschlossen();
    run = 0;
}

// constant

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

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


TextFeld *getTabellenEintrag( const char *txt, Schrift *s, int farbe )
{
    TextFeld *tmp = new TextFeld();
    tmp->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Center );
    tmp->setSchriftZ( s );
    tmp->setText( txt );
    tmp->setSchriftFarbe( farbe );
    return tmp;
}


// Inhalt der PatchServer Klasse aus PatchServer.h
// Konstruktor
PatchServer::PatchServer( Schrift *s, InitDatei *d, MSKlient *msk, RessourceBild *rb, AdminAccount *acc, Bildschirm *b )
    : Abschnitt( b )
{
    fenster = 0;
    this->msk = msk;
    iD = d;
    account = acc;
    schrift = s;
    psc = 0;

    f = new Fenster();
    f->setStyle( Fenster::Style::Sichtbar | Fenster::Style::Erlaubt | Fenster::Style::Rahmen | Fenster::Style::Titel | Fenster::Style::TitelBuffered );
    f->setRFarbe( 0xFFFFFFFF );
    f->setRBreite( 1 );
    f->setTitel( "Patch Server" );
    f->setTSchriftZ( s->getThis() );
    f->setTSFarbe( 0xFFFFFFFF );
    f->setTSSize( 12 );
    f->setTAfFarbe( 0x1000FF00 );
    f->setTAfStrength( -15 );
    f->setTRFarbe( 0xFFFFFFFF );
    f->setTRBreite( 1 );
    f->zTTextFeld()->addStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Center | TextFeld::Style::Rahmen );
    f->zTTextFeld()->setSize( 0, 20 );
    f->setSize( 492, 277 );

    liste = new Fenster();
    liste->setStyle( Fenster::Style::Sichtbar | Fenster::Style::Erlaubt );
    liste->setSize( 490, 255 );
    f->addMember( liste );

    details = new Fenster();
    details->setStyle( Fenster::Style::Erlaubt );
    details->setSize( 490, 255 );
    f->addMember( details );

    updateF = new Fenster();
    updateF->setStyle( Fenster::Style::Erlaubt );
    updateF->setSize( 490, 255 );
    f->addMember( updateF );

    tabelle = new ObjTabelle();
    tabelle->setStyle( ObjTabelle::Style::Sichtbar | ObjTabelle::Style::VScroll | ObjTabelle::Style::Rahmen | ObjTabelle::Style::Raster | ObjTabelle::Style::Erlaubt );
    tabelle->setMausEreignis( _ret1ME );
    tabelle->setLinienRahmenFarbe( 0xFFFFFFFF );
    tabelle->setRasterFarbe( 0xFFA0A0A0 );
    tabelle->setRasterBreite( 1 );
    tabelle->setPosition( 5, 5 );
    tabelle->setSize( 480, 220 );
    tabelle->setVertikalKlickScroll( 5 );
    tabelle->addSpalte( "id" );
    tabelle->setSpaltenBreite( 0, 40 );
    tabelle->addSpalte( "name" );
    tabelle->setSpaltenBreite( 1, 105 );
    tabelle->addSpalte( "ip" );
    tabelle->setSpaltenBreite( 2, 90 );
    tabelle->addSpalte( "port" );
    tabelle->setSpaltenBreite( 3, 50 );
    tabelle->addSpalte( "aport" );
    tabelle->setSpaltenBreite( 4, 50 );
    tabelle->addSpalte( "status" );
    tabelle->setSpaltenBreite( 5, 100 );
    tabelle->addSpalte( "auswahl" );
    tabelle->setSpaltenBreite( 6, 20 );
    tabelle->addZeile( "Überschrifft" );
    tabelle->setZeilenHeight( 0, 20 );
    tabelle->setZeichnungZ( 0, 0, getTabellenEintrag( "Id", s->getThis(), 0xFFFFFFFF ) );
    tabelle->setZeichnungZ( 1, 0, getTabellenEintrag( "Name", s->getThis(), 0xFFFFFFFF ) );
    tabelle->setZeichnungZ( 2, 0, getTabellenEintrag( "Ip", s->getThis(), 0xFFFFFFFF ) );
    tabelle->setZeichnungZ( 3, 0, getTabellenEintrag( "Port", s->getThis(), 0xFFFFFFFF ) );
    tabelle->setZeichnungZ( 4, 0, getTabellenEintrag( "APort", s->getThis(), 0xFFFFFFFF ) );
    tabelle->setZeichnungZ( 5, 0, getTabellenEintrag( "Status", s->getThis(), 0xFFFFFFFF ) );
    tabelle->setZeichnungZ( 6, 0, 0 );
    liste->addMember( tabelle );

    aktualisieren = new Knopf();
    aktualisieren->setText( "" );
    aktualisieren->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::HAlpha | Knopf::Style::KlickBuffer );
    aktualisieren->setHintergrundBildZ( rb->get( "neuladen.png" ) );
    aktualisieren->setPosition( 236, 230 );
    aktualisieren->setSize( 20, 20 );
    aktualisieren->setMausEreignisParameter( this );
    aktualisieren->setMausEreignis( patchServerAktualisierenMausEreignis );
    f->addMember( aktualisieren );

    weiter = new Knopf();
    weiter->setText( "" );
    weiter->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::HAlpha | Knopf::Style::KlickBuffer );
    weiter->setHintergrundBildZ( rb->get( "weiter.png" ) );
    weiter->setPosition( 261, 230 );
    weiter->setSize( 20, 20 );
    weiter->setMausEreignisParameter( this );
    weiter->setMausEreignis( patchServerWeiterMausEreignis );
    f->addMember( weiter );

    zurück = new Knopf();
    zurück->setText( "" );
    zurück->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::HAlpha | Knopf::Style::KlickBuffer );
    zurück->setHintergrundBildZ( rb->get( "zurück.png" ) );
    zurück->setPosition( 211, 230 );
    zurück->setSize( 20, 20 );
    zurück->setMausEreignisParameter( this );
    zurück->setMausEreignis( patchServerZurückMausEreignis );
    f->addMember( zurück );

    serverId = new TextFeld();
    serverId->setStyle( TextFeld::Style::Sichtbar );
    serverId->setSchriftZ( s->getThis() );
    serverId->setSchriftFarbe( 0xFFFFFFFF );
    serverId->setSchriftSize( 12 );
    serverId->setText( "ID: " );
    serverId->setSize( 100, 20 );
    serverId->setPosition( 10, 10 );
    details->addMember( serverId );

    serverName = new TextFeld();
    serverName->setStyle( TextFeld::Style::Sichtbar );
    serverName->setSchriftZ( s->getThis() );
    serverName->setSchriftFarbe( 0xFFFFFFFF );
    serverName->setSchriftSize( 12 );
    serverName->setText( "Name: " );
    serverName->setSize( 150, 20 );
    serverName->setPosition( 120, 10 );
    details->addMember( serverName );

    serverIp = new TextFeld();
    serverIp->setStyle( TextFeld::Style::Sichtbar );
    serverIp->setSchriftZ( s->getThis() );
    serverIp->setSchriftFarbe( 0xFFFFFFFF );
    serverIp->setSchriftSize( 12 );
    serverIp->setText( "IP: " );
    serverIp->setSize( 120, 20 );
    serverIp->setPosition( 280, 10 );
    details->addMember( serverIp );

    serverPort = new TextFeld();
    serverPort->setStyle( TextFeld::Style::Sichtbar );
    serverPort->setSchriftZ( s->getThis() );
    serverPort->setSchriftFarbe( 0xFFFFFFFF );
    serverPort->setSchriftSize( 12 );
    serverPort->setText( "Port: " );
    serverPort->setSize( 100, 20 );
    serverPort->setPosition( 10, 40 );
    details->addMember( serverPort );

    serverAPort = new TextFeld();
    serverAPort->setStyle( TextFeld::Style::Sichtbar );
    serverAPort->setSchriftZ( s->getThis() );
    serverAPort->setSchriftFarbe( 0xFFFFFFFF );
    serverAPort->setSchriftSize( 12 );
    serverAPort->setText( "Admin Port: " );
    serverAPort->setSize( 200, 20 );
    serverAPort->setPosition( 120, 40 );
    details->addMember( serverAPort );

    serverClients = new TextFeld();
    serverClients->setStyle( TextFeld::Style::Sichtbar );
    serverClients->setSchriftZ( s->getThis() );
    serverClients->setSchriftFarbe( 0xFFFFFFFF );
    serverClients->setSchriftSize( 12 );
    serverClients->setText( "Clients: " );
    serverClients->setSize( 100, 20 );
    serverClients->setPosition( 10, 70 );
    details->addMember( serverClients );

    serverMaxClients = new TextFeld();
    serverMaxClients->setStyle( TextFeld::Style::Sichtbar );
    serverMaxClients->setSchriftZ( s->getThis() );
    serverMaxClients->setSchriftFarbe( 0xFFFFFFFF );
    serverMaxClients->setSchriftSize( 12 );
    serverMaxClients->setText( "Max Clients: " );
    serverMaxClients->setSize( 80, 20 );
    serverMaxClients->setPosition( 120, 70 );
    details->addMember( serverMaxClients );

    maxClients = new TextFeld();
    maxClients->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Erlaubt | TextFeld::Style::Rahmen | TextFeld::Style::Buffered | TextFeld::Style::VCenter );
    maxClients->setSchriftZ( s->getThis() );
    maxClients->setSchriftFarbe( 0xFFFFFFFF );
    maxClients->setSchriftSize( 12 );
    maxClients->setLinienRahmenBreite( 1 );
    maxClients->setLinienRahmenFarbe( 0xFFFFFFFF );
    maxClients->setAlphaFeldFarbe( 0x1000FF00 );
    maxClients->setAlphaFeldStrength( -5 );
    maxClients->setText( "" );
    maxClients->setSize( 100, 20 );
    maxClients->setPosition( 200, 68 );
    maxClients->setMausEreignis( _ret1ME );
    maxClients->setTastaturEreignisParameter( this );
    maxClients->setTastaturEreignis( patchServerMaxClientsTastaturEreignis );
    details->addMember( maxClients );

    serverStatus = new TextFeld();
    serverStatus->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Mehrfarbig );
    serverStatus->setSchriftZ( s->getThis() );
    serverStatus->setSchriftFarbe( 0xFFFFFFFF );
    serverStatus->setSchriftSize( 12 );
    serverStatus->setText( "Status: " );
    serverStatus->setSize( 150, 20 );
    serverStatus->setPosition( 10, 100 );
    details->addMember( serverStatus );

    serverFehler = new TextFeld();
    serverFehler->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Mehrzeilig );
    serverFehler->setSchriftZ( s->getThis() );
    serverFehler->setSchriftFarbe( 0xFFFFFFFF );
    serverFehler->setSchriftSize( 12 );
    serverFehler->setText( "" );
    serverFehler->setSize( 470, 60 );
    serverFehler->setPosition( 10, 130 );
    details->addMember( serverFehler );

    update = new Knopf();
    update->setStyle( Knopf::Style::Normal & ~Knopf::Style::Erlaubt );
    update->setText( "Update" );
    update->setSchriftZ( s->getThis() );
    update->setMausEreignisParameter( this );
    update->setMausEreignis( patchServerUpdateMausEreignis );
    update->setSize( 80, 20 );
    update->setPosition( 400, 100 );
    details->addMember( update );

    pausieren = new Knopf();
    pausieren->setStyle( Knopf::Style::Normal & ~Knopf::Style::Erlaubt );
    pausieren->setText( "Pausieren" );
    pausieren->setSchriftZ( s->getThis() );
    pausieren->setMausEreignisParameter( this );
    pausieren->setMausEreignis( patchServerPausierenMausEreignis );
    pausieren->setSize( 80, 20 );
    pausieren->setPosition( 10, 200 );
    details->addMember( pausieren );

    stoppen = new Knopf();
    stoppen->setStyle( Knopf::Style::Normal & ~Knopf::Style::Erlaubt );
    stoppen->setText( "Stoppen" );
    stoppen->setSchriftZ( s->getThis() );
    stoppen->setMausEreignisParameter( this );
    stoppen->setMausEreignis( patchServerStoppenMausEreignis );
    stoppen->setSize( 80, 20 );
    stoppen->setPosition( 100, 200 );
    details->addMember( stoppen );

    beenden = new Knopf();
    beenden->setStyle( Knopf::Style::Normal & ~Knopf::Style::Erlaubt );
    beenden->setText( "Beenden" );
    beenden->setSchriftZ( s->getThis() );
    beenden->setMausEreignisParameter( this );
    beenden->setMausEreignis( patchServerBeendenMausEreignis );
    beenden->setSize( 80, 20 );
    beenden->setPosition( 190, 200 );
    details->addMember( beenden );

    terminieren = new Knopf();
    terminieren->setStyle( Knopf::Style::Normal & ~Knopf::Style::Erlaubt );
    terminieren->setText( "Terminieren" );
    terminieren->setSchriftZ( s->getThis() );
    terminieren->setMausEreignisParameter( this );
    terminieren->setMausEreignis( patchServerTerminierenMausEreignis );
    terminieren->setSize( 80, 20 );
    terminieren->setPosition( 280, 200 );
    details->addMember( terminieren );

    setMaxClients = new Knopf();
    setMaxClients->setStyle( Knopf::Style::Normal & ~Knopf::Style::Erlaubt );
    setMaxClients->setText( "set Max Clients" );
    setMaxClients->setSchriftZ( s->getThis() );
    setMaxClients->setMausEreignisParameter( this );
    setMaxClients->setMausEreignis( patchServerSetMaxClientsMausEreignis );
    setMaxClients->setSize( 110, 20 );
    setMaxClients->setPosition( 370, 200 );
    details->addMember( setMaxClients );

    updateT = new ObjTabelle();
    updateT->setStyle( ObjTabelle::Style::Sichtbar | ObjTabelle::Style::Erlaubt | ObjTabelle::Style::Rahmen | ObjTabelle::Style::VScroll );
    updateT->setVertikalKlickScroll( 10 );
    updateT->setMausEreignis( _ret1ME );
    updateT->setLinienRahmenFarbe( 0xFFFFFFFF );
    updateT->setPosition( 5, 5 );
    updateT->setSize( 480, 190 );
    updateT->addSpalte( "Name" );
    updateT->addSpalte( "Status" );
    updateT->addSpalte( "Auswahl" );
    updateT->addSpalte( "Update" );
    updateT->setSpaltenBreite( 0, 340 );
    updateT->setSpaltenBreite( 1, 100 );
    updateT->setSpaltenBreite( 2, 22 );
    updateT->setSpaltenBreite( 3, 0 );
    updateT->addZeile( "Titel" );
    updateT->setZeilenHeight( 0, 20 );
    TextFeld *uTN = new TextFeld();
    uTN->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Rahmen | TextFeld::Style::Center );
    uTN->setSchriftZ( s->getThis() );
    uTN->setSchriftFarbe( 0xFFFFFFFF );
    uTN->setSchriftSize( 12 );
    uTN->setLinienRahmenFarbe( 0xFFFFFFFF );
    uTN->setText( "Name" );
    updateT->setZeichnungZ( 0, 0, uTN );
    TextFeld *uTS = new TextFeld();
    uTS->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Rahmen | TextFeld::Style::Center );
    uTS->setSchriftZ( s->getThis() );
    uTS->setSchriftFarbe( 0xFFFFFFFF );
    uTS->setSchriftSize( 12 );
    uTS->setLinienRahmenFarbe( 0xFFFFFFFF );
    uTS->setText( "Status" );
    updateT->setZeichnungZ( 1, 0, uTS );
    updateT->setMausEreignis( _ret1ME );
    updateT->setTastaturEreignis( _ret1TE );
    updateF->addMember( updateT );

    updateStarten = new Knopf();
    updateStarten->setStyle( Knopf::Style::Normal );
    updateStarten->setText( "Start" );
    updateStarten->setSchriftZ( s->getThis() );
    updateStarten->setMausEreignisParameter( this );
    updateStarten->setMausEreignis( patchServerUpdateStartenMausEreignis );
    updateStarten->setSize( 80, 20 );
    updateStarten->setPosition( 205, 200 );
    updateF->addMember( updateStarten );

    obj = new Zeichnung();

    suchen = new PSSuche( this, msk->getThis() );
    getDetails = new PSDetails( this, msk->getThis() );
    updateTh = new PSUpdate( this, account->getThis() );
    rb->release();
    ref = 1;
}

// Destruktor
PatchServer::~PatchServer()
{
    for( int i = 0; i < updateT->getZeilenAnzahl(); i++ )
    {
        ( (TextFeld*)updateT->zZeichnung( 0, i ) )->release();
        if( updateT->zZeichnung( 3, i ) == obj )
            ( (FBalken*)updateT->zZeichnung( 1, i ) )->release();
        else
            ( (TextFeld*)updateT->zZeichnung( 1, i ) )->release();
        if( updateT->zZeichnung( 2, i ) )
            ( (KontrollKnopf*)updateT->zZeichnung( 2, i ) )->release();
    }
    delete obj;
    if( psc )
    {
        psc->trenne();
        psc->release();
    }
    if( fenster )
    {
        fenster->removeMember( f );
        fenster->release();
    }
    account->release();
    msk->release();
    iD->release();
    f->release();
    liste->release();
    details->release();
    updateF->release();
    updateStarten->release();
    updateT->release();
    aktualisieren->release();
    weiter->release();
    zurück->release();
    update->release();
    pausieren->release();
    stoppen->release();
    beenden->release();
    terminieren->release();
    setMaxClients->release();
    serverId->release();
    serverName->release();
    serverIp->release();
    serverPort->release();
    serverAPort->release();
    serverClients->release();
    serverMaxClients->release();
    serverStatus->release();
    serverFehler->release();
    maxClients->release();
    suchen->release();
    getDetails->release();
    updateTh->release();
    for( int x = 0; x < tabelle->getSpaltenAnzahl(); x++ )
    {
        for( int y = 0; y < tabelle->getZeilenAnzahl(); y++ )
        {
            Zeichnung *obj = tabelle->zZeichnung( x, y );
            if( obj )
            {
                if( x == tabelle->getSpaltenNummer( "auswahl" ) )
                    ( (KontrollKnopf*)obj )->release();
                else
                    ( (TextFeld*)obj )->release();
            }
            tabelle->setZeichnungZ( x, y, 0 );
        }
    }
    tabelle->release();
    schrift->release();
}

// nicht constant
void PatchServer::setFenster( Fenster *f )
{
    if( fenster )
        fenster->release();
    this->f->setPosition( f->getBreite() / 2 - this->f->getBreite() / 2, f->getHeight() / 2 - this->f->getHeight() / 2 );
    fenster = f;
}

void PatchServer::setSichtbar( bool s )
{
    sichtbar = s;
    if( s )
    {
        if( !suchen->isRunning() && liste->hatStyle( Fenster::Style::Sichtbar ) )
        {
            for( int x = 0; x < tabelle->getSpaltenAnzahl(); x++ )
            {
                for( int y = 1; y < tabelle->getZeilenAnzahl(); y++ )
                {
                    Zeichnung *obj = tabelle->zZeichnung( x, y );
                    if( obj )
                    {
                        if( x == tabelle->getSpaltenNummer( "auswahl" ) )
                            ( (KontrollKnopf*)obj )->release();
                        else
                            ( (TextFeld*)obj )->release();
                    }
                    tabelle->setZeichnungZ( x, y, 0 );
                }
            }
            for( int y = 1; y < tabelle->getZeilenAnzahl(); y++ )
                tabelle->removeZeile( 1 );
            weiter->removeStyle( Knopf::Style::Erlaubt );
            aktualisieren->removeStyle( Knopf::Style::Erlaubt );
            tabelle->removeStyle( ObjTabelle::Style::Erlaubt );
            suchen->start();
        }
        fenster->addMember( f );
    }
    else
        fenster->removeMember( f );
}

void PatchServer::addServer( int id, char *name, char *ip, int port, int adminPort, char *status )
{
    Text *txt = new Text();
    txt->append( id );
    tabelle->addZeile( txt->getText() );
    int y = tabelle->getZeilenNummer( txt->getText() );
    tabelle->setZeilenHeight( y, 20 );
    tabelle->setZeichnungZ( 0, y, getTabellenEintrag( txt->getText(), schrift->getThis(), 0xFFFFFFFF ) );
    tabelle->setZeichnungZ( 1, y, getTabellenEintrag( name, schrift->getThis(), 0xFFFFFFFF ) );
    tabelle->setZeichnungZ( 2, y, getTabellenEintrag( ip, schrift->getThis(), 0xFFFFFFFF ) );
    txt->setText( "" );
    txt->append( port );
    tabelle->setZeichnungZ( 3, y, getTabellenEintrag( txt->getText(), schrift->getThis(), 0xFFFFFFFF ) );
    txt->setText( "" );
    txt->append( adminPort );
    tabelle->setZeichnungZ( 4, y, getTabellenEintrag( txt->getText(), schrift->getThis(), 0xFFFFFFFF ) );
    txt->release();
    tabelle->setZeichnungZ( 5, y, getTabellenEintrag( status, schrift->getThis(), getColorFromStatus( status ) ) );
    KontrollKnopf *knopf = new KontrollKnopf();
    knopf->setStyle( KontrollKnopf::Style::Sichtbar | KontrollKnopf::Style::Erlaubt | KontrollKnopf::Style::KlickBuffer );
    knopf->loadData( "data/bilder/icons.ltdb" );
    knopf->setMausEreignisParameter( this );
    knopf->setMausEreignis( patchServerAuswahlKnopfMausEreignis );
    tabelle->setZeichnungZ( 6, y, knopf );
}

void PatchServer::setServerDetails( int id, char *name, char *ip, int port, int adminPort, int clients, int maxClients, int status, Text *error )
{
    if( !psc )
    {
        psc = new PSKlient( ip, adminPort );
        psc->verbinden();
        psc->login( account->zName()->getText(), account->zPasswort()->getText() );
        updateTh->setServer( ip, adminPort );
    }
    if( !error )
    {
        serverId->setText( "ID: " );
        serverId->zText()->append( id );
        serverName->setText( "Name: " );
        serverName->zText()->append( name );
        serverIp->setText( "IP: " );
        serverIp->zText()->append( ip );
        serverPort->setText( "Port: " );
        serverPort->zText()->append( port );
        serverAPort->setText( "Admin Port: " );
        serverAPort->zText()->append( adminPort );
        serverClients->setText( "Clients: " );
        serverClients->zText()->append( clients );
        this->maxClients->setText( "" );
        this->maxClients->zText()->append( maxClients );
        serverFehler->setText( "" );
        switch( status )
        {
        case -2: // Unbekannt
            serverStatus->setText( "\r0xFFFFFFFFStatus: \r0xFFFF8800Unbekannt" );
            break;
        case -1: // Unerreichbar
            serverStatus->setText( "\r0xFFFFFFFFStatus: \r0xFFFF0000Unerreichbar" );
            break;
        case 0: // Offline
            serverStatus->setText( "\r0xFFFFFFFFStatus: \r0xFFFFFF00Offline" );
            stoppen->setText( "Starten" );
            stoppen->addStyle( Knopf::Style::Erlaubt );
            beenden->addStyle( Knopf::Style::Erlaubt );
            terminieren->addStyle( Knopf::Style::Erlaubt );
            this->maxClients->addStyle( TextFeld::Style::Erlaubt );
            break;
        case 1: // Pausiert
            serverStatus->setText( "\r0xFFFFFFFFStatus: \r0xFF88FF00Pausiert" );
            pausieren->setText( "Fortsetzen" );
            pausieren->addStyle( Knopf::Style::Erlaubt );
            stoppen->setText( "Stoppen" );
            stoppen->addStyle( Knopf::Style::Erlaubt );
            beenden->addStyle( Knopf::Style::Erlaubt );
            terminieren->addStyle( Knopf::Style::Erlaubt );
            this->maxClients->addStyle( TextFeld::Style::Erlaubt );
            break;
        case 2: // Online
            serverStatus->setText( "\r0xFFFFFFFFStatus: \r0xFF00FF00Online" );
            pausieren->setText( "Pausieren" );
            pausieren->addStyle( Knopf::Style::Erlaubt );
            terminieren->addStyle( Knopf::Style::Erlaubt );
            this->maxClients->addStyle( TextFeld::Style::Erlaubt );
            break;
        case 3: // Veraltet
            serverStatus->setText( "\r0xFFFFFFFFStatus: \r0xFFB0FF00Veraltet" );
            pausieren->setText( "Pausieren" );
            pausieren->addStyle( Knopf::Style::Erlaubt );
            update->addStyle( Knopf::Style::Erlaubt );
            beenden->addStyle( Knopf::Style::Erlaubt );
            terminieren->addStyle( Knopf::Style::Erlaubt );
            this->maxClients->addStyle( TextFeld::Style::Erlaubt );
            break;
        }
        aktualisieren->addStyle( Knopf::Style::Erlaubt );
        zurück->addStyle( Knopf::Style::Erlaubt );
        update->addStyle( Knopf::Style::Erlaubt );
    }
    else
    {
        serverId->setText( "ID: " );
        serverName->setText( "Name: " );
        serverIp->setText( "IP: " );
        serverPort->setText( "Port: " );
        serverAPort->setText( "APort: " );
        serverClients->setText( "Clients: " );
        this->maxClients->setText( "" );
        this->serverStatus->setText( "Status: " );
        aktualisieren->addStyle( Knopf::Style::Erlaubt );
        zurück->addStyle( Knopf::Style::Erlaubt );
        serverFehler->setText( error );
    }
}

void PatchServer::sucheAbgeschlossen()
{
    aktualisieren->addStyle( Knopf::Style::Erlaubt );
    tabelle->addStyle( ObjTabelle::Style::Erlaubt );
}

void PatchServer::setUpdateProzent( int prozent, int gruppe )
{
    for( int i = 0; i < updateT->getZeilenAnzahl(); i++ )
    {
        if( gruppe == TextZuInt( updateT->zZeilenName( i )->getText(), 10 ) )
        {
            if( updateT->zZeichnung( 3, i ) != obj )
            {
                updateT->lockZeichnung();
                ( (TextFeld*)updateT->zZeichnung( 1, i ) )->release();
                FBalken *fb = new FBalken();
                fb->setStyle( FBalken::Style::Sichtbar | FBalken::Style::L_R | FBalken::Style::FFarbe | FBalken::Style::Hintergrund | FBalken::Style::Prozent | FBalken::Style::Rahmen | FBalken::Style::FRahmen );
                fb->setFBgFarbe( 0xFF00FF00 );
                fb->setHintergrundFarbe( 0xFFFFFFFF );
                fb->setSFarbe( 0xFF000000 );
                fb->setSchriftZ( schrift->getThis() );
                fb->setSSize( 12 );
                fb->setLinienRahmenBreite( 1 );
                fb->setLinienRahmenFarbe( 0xFF55FF55 );
                fb->setFRFarbe( 0xFF55FF55 );
                fb->reset();
                fb->setAktionAnzahl( 100 );
                updateT->setZeichnungZ( 1, i, fb );
                updateT->setZeichnungZ( 3, i, obj );
                updateT->unlockZeichnung();
            }
            ( (FBalken*)updateT->zZeichnung( 1, i ) )->reset();
            ( (FBalken*)updateT->zZeichnung( 1, i ) )->aktionPlus( prozent );
            return;
        }
    }
}

void PatchServer::setUpdateFertig( bool error, int gruppe )
{
    if( !gruppe )
    { // gesamter Vorgang abgeschlossen
        aktualisieren->addStyle( Knopf::Style::Erlaubt );
        zurück->addStyle( Knopf::Style::Erlaubt );
        updateStarten->addStyle( Knopf::Style::Erlaubt );
        updateT->addStyle( ObjTabelle::Style::Erlaubt );
        MausEreignis me;
        me.id = ME_RLinks;
        b->lock();
        aktualisierenMausEreignis( 0, me );
        b->unlock();
    }
    else
    { // einzelner Schritt abgeschlossen
        for( int i = 0; i < updateT->getZeilenAnzahl(); i++ )
        {
            if( gruppe == TextZuInt( updateT->zZeilenName( i )->getText(), 10 ) )
            {
                updateT->lockZeichnung();
                ( (FBalken*)updateT->zZeichnung( 1, i ) )->release();
                TextFeld *uTS = new TextFeld();
                uTS->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Rahmen | TextFeld::Style::Center );
                uTS->setSchriftZ( schrift->getThis() );
                uTS->setSchriftSize( 12 );
                uTS->setLinienRahmenFarbe( 0xFFFFFFFF );
                if( error )
                {
                    uTS->setText( "Fehler" );
                    uTS->setSchriftFarbe( 0xFFFF0000 );
                }
                else
                {
                    uTS->setText( "Aktuell" );
                    uTS->setSchriftFarbe( 0xFF00FF00 );
                }
                updateT->setZeichnungZ( 1, i, uTS );
                updateT->setZeichnungZ( 3, i, 0 );
                updateT->unlockZeichnung();
                return;
            }
        }
    }
}

bool PatchServer::aktualisierenMausEreignis( void *o, MausEreignis me )
{
    if( me.id == ME_RLinks )
    {
        if( liste->hatStyle( Fenster::Style::Sichtbar ) )
        {
            if( !suchen->isRunning() )
            {
                for( int x = 0; x < tabelle->getSpaltenAnzahl(); x++ )
                {
                    for( int y = 1; y < tabelle->getZeilenAnzahl(); y++ )
                    {
                        Zeichnung *obj = tabelle->zZeichnung( x, y );
                        if( obj )
                        {
                            if( x == tabelle->getSpaltenNummer( "auswahl" ) )
                                ( (KontrollKnopf*)obj )->release();
                            else
                                ( (TextFeld*)obj )->release();
                        }
                        tabelle->setZeichnungZ( x, y, 0 );
                    }
                }
                for( int y = 1; y < tabelle->getZeilenAnzahl(); y++ )
                    tabelle->removeZeile( 1 );
                weiter->removeStyle( Knopf::Style::Erlaubt );
                aktualisieren->removeStyle( Knopf::Style::Erlaubt );
                tabelle->removeStyle( ObjTabelle::Style::Erlaubt );
                suchen->start();
            }
        }
        else if( details->hatStyle( Fenster::Style::Sichtbar ) )
        {
            aktualisieren->removeStyle( Knopf::Style::Erlaubt );
            zurück->removeStyle( Knopf::Style::Erlaubt );
            update->removeStyle( Knopf::Style::Erlaubt );
            pausieren->removeStyle( Knopf::Style::Erlaubt );
            stoppen->removeStyle( Knopf::Style::Erlaubt );
            beenden->removeStyle( Knopf::Style::Erlaubt );
            terminieren->removeStyle( Knopf::Style::Erlaubt );
            setMaxClients->removeStyle( Knopf::Style::Erlaubt );
            maxClients->removeStyle( TextFeld::Style::Erlaubt );
            getDetails->start();
        }
        else if( updateF->hatStyle( Fenster::Style::Sichtbar ) )
        {
            int id = -1;
            for( int i = 1; i < tabelle->getZeilenAnzahl(); i++ )
            {
                if( ( (KontrollKnopf*)tabelle->zZeichnung( 6, i ) )->hatStyle( KontrollKnopf::Style::Selected ) )
                {
                    id = TextZuInt( tabelle->zZeilenName( i )->getText(), 10 );
                    break;
                }
            }
            Array< FileGroupInfo* > list;
            if( psc->getFileGroupInfoList( &list ) )
            {
                for( int i = 1; i < updateT->getZeilenAnzahl(); )
                {
                    ( (TextFeld*)updateT->zZeichnung( 0, i ) )->release();
                    if( updateT->zZeichnung( 3, i ) == obj )
                        ( (FBalken*)updateT->zZeichnung( 1, i ) )->release();
                    else
                        ( (TextFeld*)updateT->zZeichnung( 1, i ) )->release();
                    if( updateT->zZeichnung( 2, i ) )
                        ( (KontrollKnopf*)updateT->zZeichnung( 2, i ) )->release();
                    updateT->removeZeile( i );
                }
                int anz = list.getEintragAnzahl();
                for( int i = 0; i < anz; i++ )
                {
                    FileGroupInfo *info = list.get( i );
                    updateT->addZeile( new Text( info->id ) );
                    TextFeld *uTN = new TextFeld();
                    uTN->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Rahmen | TextFeld::Style::VCenter );
                    uTN->setSchriftZ( schrift->getThis() );
                    uTN->setSchriftFarbe( 0xFFFFFFFF );
                    uTN->setSchriftSize( 12 );
                    uTN->setLinienRahmenFarbe( 0xFFFFFFFF );
                    uTN->setText( info->name );
                    updateT->setZeichnungZ( 0, i + 1, uTN );
                    TextFeld *uTS = new TextFeld();
                    uTS->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Rahmen | TextFeld::Style::Center );
                    uTS->setLinienRahmenFarbe( 0xFFFFFFFF );
                    uTS->setSchriftZ( schrift->getThis() );
                    uTS->setSchriftSize( 12 );
                    if( info->status.istGleich( "Fehlt" ) )
                        uTS->setSchriftFarbe( 0xFFFF0000 );
                    if( info->status.istGleich( "Aktuell" ) )
                        uTS->setSchriftFarbe( 0xFF00FF00 );
                    if( info->status.istGleich( "Veraltet" ) )
                        uTS->setSchriftFarbe( 0xFFFFFF00 );
                    if( info->status.istGleich( "Update" ) )
                        uTS->setSchriftFarbe( 0xFFFFFFFF );
                    uTS->setText( info->status.getText() );
                    updateT->setZeichnungZ( 1, i + 1, uTS );
                    if( info->status.istGleich( "Veraltet" ) || info->status.istGleich( "Fehlt" ) )
                    {
                        KontrollKnopf *auswahl = new KontrollKnopf();
                        auswahl->setStyle( KontrollKnopf::Style::Sichtbar | KontrollKnopf::Style::Erlaubt | KontrollKnopf::Style::KlickBuffer | KontrollKnopf::Style::Rahmen );
                        auswahl->loadData( "data/bilder/icons.ltdb" );
                        auswahl->setMausEreignisParameter( this );
                        auswahl->setMausEreignis( patchServerAuswahlKnopfMausEreignis );
                        auswahl->setLinienRahmenFarbe( 0xFFFFFFFF );
                        updateT->setZeichnungZ( 2, i + 1, auswahl );
                    }
                    delete info;
                }
            }
            else
                WMessageBox( 0, new Text( "Fehler" ), new Text( psc->getLetzterFehler() ), MB_ICONERROR );
        }
    }
    return 1;
}

bool PatchServer::auswahlKnopfMausEreignis( void *o, MausEreignis me )
{
    if( !o )
        return 0;
    if( me.id == ME_RLinks )
    {
        if( liste->hatStyle( Fenster::Style::Sichtbar ) )
        {
            for( int i = 1; i < tabelle->getZeilenAnzahl(); i++ )
                ( (KontrollKnopf*)tabelle->zZeichnung( 6, i ) )->removeStyle( KontrollKnopf::Style::Selected );
            weiter->addStyle( Knopf::Style::Erlaubt );
        }
    }
    return 1;
}

bool PatchServer::weiterMausEreignis( void *o, MausEreignis me )
{
    if( me.id == ME_RLinks )
    {
        liste->removeStyle( Fenster::Style::Sichtbar );
        details->addStyle( Fenster::Style::Sichtbar );
        aktualisieren->removeStyle( Knopf::Style::Erlaubt );
        zurück->removeStyle( Knopf::Style::Erlaubt );
        update->removeStyle( Knopf::Style::Erlaubt );
        pausieren->removeStyle( Knopf::Style::Erlaubt );
        stoppen->removeStyle( Knopf::Style::Erlaubt );
        beenden->removeStyle( Knopf::Style::Erlaubt );
        terminieren->removeStyle( Knopf::Style::Erlaubt );
        setMaxClients->removeStyle( Knopf::Style::Erlaubt );
        maxClients->removeStyle( TextFeld::Style::Erlaubt );
        int id = -1;
        for( int i = 1; i < tabelle->getZeilenAnzahl(); i++ )
        {
            if( ( (KontrollKnopf*)tabelle->zZeichnung( 6, i ) )->hatStyle( KontrollKnopf::Style::Selected ) )
            {
                id = TextZuInt( tabelle->zZeilenName( i )->getText(), 10 );
                break;
            }
        }
        getDetails->setServerId( id );
        getDetails->start();
    }
    return 1;
}

bool PatchServer::zurückMausEreignis( void *o, MausEreignis me )
{
    if( me.id == ME_RLinks )
    {
        if( details->hatStyle( Fenster::Style::Sichtbar ) )
        {
            details->removeStyle( Fenster::Style::Sichtbar );
            liste->addStyle( Fenster::Style::Sichtbar );
            if( !suchen->isRunning() )
            {
                for( int x = 0; x < tabelle->getSpaltenAnzahl(); x++ )
                {
                    for( int y = 1; y < tabelle->getZeilenAnzahl(); y++ )
                    {
                        Zeichnung *obj = tabelle->zZeichnung( x, y );
                        if( obj )
                        {
                            if( x == tabelle->getSpaltenNummer( "auswahl" ) )
                                ( (KontrollKnopf*)obj )->release();
                            else
                                ( (TextFeld*)obj )->release();
                        }
                        tabelle->setZeichnungZ( x, y, 0 );
                    }
                }
                for( int y = 1; y < tabelle->getZeilenAnzahl(); y++ )
                    tabelle->removeZeile( 1 );
                weiter->removeStyle( Knopf::Style::Erlaubt );
                zurück->removeStyle( Knopf::Style::Erlaubt );
                aktualisieren->removeStyle( Knopf::Style::Erlaubt );
                suchen->start();
            }
            if( psc )
            {
                psc->trenne();
                psc = (PSKlient*)psc->release();
            }
        }
        else if( updateF->hatStyle( Fenster::Style::Sichtbar ) )
        {
            updateF->removeStyle( Fenster::Style::Sichtbar );
            details->addStyle( Fenster::Style::Sichtbar );
            aktualisierenMausEreignis( 0, me );
        }
    }
    return 1;
}

bool PatchServer::updateMausEreignis( void *o, MausEreignis me )
{
    if( me.id == ME_RLinks )
    {
        zurück->addStyle( Knopf::Style::Erlaubt );
        weiter->removeStyle( Knopf::Style::Erlaubt );
        details->removeStyle( Fenster::Style::Sichtbar );
        updateF->addStyle( Fenster::Style::Sichtbar );
        aktualisieren->addStyle( Knopf::Style::Erlaubt );
        aktualisierenMausEreignis( 0, me );
    }
    return 1;
}

bool PatchServer::pausierenMausEreignis( void *o, MausEreignis me )
{
    if( me.id == ME_RLinks )
    {
        if( pausieren->zText()->istGleich( "Pausieren" ) )
        {
            if( psc->pause() )
            {
                aktualisieren->removeStyle( Knopf::Style::Erlaubt );
                zurück->removeStyle( Knopf::Style::Erlaubt );
                update->removeStyle( Knopf::Style::Erlaubt );
                pausieren->removeStyle( Knopf::Style::Erlaubt );
                stoppen->removeStyle( Knopf::Style::Erlaubt );
                beenden->removeStyle( Knopf::Style::Erlaubt );
                terminieren->removeStyle( Knopf::Style::Erlaubt );
                setMaxClients->removeStyle( Knopf::Style::Erlaubt );
                maxClients->removeStyle( TextFeld::Style::Erlaubt );
                getDetails->start();
            }
            else
                serverFehler->setText( psc->getLetzterFehler() );
        }
        else
        {
            if( psc->fortsetzen() )
            {
                aktualisieren->removeStyle( Knopf::Style::Erlaubt );
                zurück->removeStyle( Knopf::Style::Erlaubt );
                update->removeStyle( Knopf::Style::Erlaubt );
                pausieren->removeStyle( Knopf::Style::Erlaubt );
                stoppen->removeStyle( Knopf::Style::Erlaubt );
                beenden->removeStyle( Knopf::Style::Erlaubt );
                terminieren->removeStyle( Knopf::Style::Erlaubt );
                setMaxClients->removeStyle( Knopf::Style::Erlaubt );
                maxClients->removeStyle( TextFeld::Style::Erlaubt );
                getDetails->start();
            }
            else
                serverFehler->setText( psc->getLetzterFehler() );
        }
    }
    return 1;
}

bool PatchServer::stoppenMausEreignis( void *o, MausEreignis me )
{
    if( me.id == ME_RLinks )
    {
        if( stoppen->zText()->istGleich( "Stoppen" ) )
        {
            if( psc->stop() )
            {
                aktualisieren->removeStyle( Knopf::Style::Erlaubt );
                zurück->removeStyle( Knopf::Style::Erlaubt );
                update->removeStyle( Knopf::Style::Erlaubt );
                pausieren->removeStyle( Knopf::Style::Erlaubt );
                stoppen->removeStyle( Knopf::Style::Erlaubt );
                beenden->removeStyle( Knopf::Style::Erlaubt );
                terminieren->removeStyle( Knopf::Style::Erlaubt );
                setMaxClients->removeStyle( Knopf::Style::Erlaubt );
                maxClients->removeStyle( TextFeld::Style::Erlaubt );
                getDetails->start();
            }
            else
                serverFehler->setText( psc->getLetzterFehler() );
        }
        else
        {
            if( psc->start() )
            {
                aktualisieren->removeStyle( Knopf::Style::Erlaubt );
                zurück->removeStyle( Knopf::Style::Erlaubt );
                update->removeStyle( Knopf::Style::Erlaubt );
                pausieren->removeStyle( Knopf::Style::Erlaubt );
                stoppen->removeStyle( Knopf::Style::Erlaubt );
                beenden->removeStyle( Knopf::Style::Erlaubt );
                terminieren->removeStyle( Knopf::Style::Erlaubt );
                setMaxClients->removeStyle( Knopf::Style::Erlaubt );
                maxClients->removeStyle( TextFeld::Style::Erlaubt );
                getDetails->start();
            }
            else
                serverFehler->setText( psc->getLetzterFehler() );
        }
    }
    return 1;
}

bool PatchServer::beendenMausEreignis( void *o, MausEreignis me )
{
    if( me.id == ME_RLinks )
    {
        if( psc->beenden() )
        {
            aktualisieren->removeStyle( Knopf::Style::Erlaubt );
            zurück->removeStyle( Knopf::Style::Erlaubt );
            update->removeStyle( Knopf::Style::Erlaubt );
            pausieren->removeStyle( Knopf::Style::Erlaubt );
            stoppen->removeStyle( Knopf::Style::Erlaubt );
            beenden->removeStyle( Knopf::Style::Erlaubt );
            terminieren->removeStyle( Knopf::Style::Erlaubt );
            setMaxClients->removeStyle( Knopf::Style::Erlaubt );
            maxClients->removeStyle( TextFeld::Style::Erlaubt );
            zurückMausEreignis( 0, me );
        }
        else
            serverFehler->setText( psc->getLetzterFehler() );
    }
    return 1;
}

bool PatchServer::terminierenMausEreignis( void *o, MausEreignis me )
{
    if( me.id == ME_RLinks )
    {
        if( psc->terminieren() )
        {
            aktualisieren->removeStyle( Knopf::Style::Erlaubt );
            zurück->removeStyle( Knopf::Style::Erlaubt );
            update->removeStyle( Knopf::Style::Erlaubt );
            pausieren->removeStyle( Knopf::Style::Erlaubt );
            stoppen->removeStyle( Knopf::Style::Erlaubt );
            beenden->removeStyle( Knopf::Style::Erlaubt );
            terminieren->removeStyle( Knopf::Style::Erlaubt );
            setMaxClients->removeStyle( Knopf::Style::Erlaubt );
            maxClients->removeStyle( TextFeld::Style::Erlaubt );
            zurückMausEreignis( 0, me );
        }
        else
            serverFehler->setText( psc->getLetzterFehler() );
    }
    return 1;
}

bool PatchServer::setMaxClientsMausEreignis( void *o, MausEreignis me )
{
    if( me.id == ME_RLinks )
    {
        if( psc->setMaxTasks( TextZuInt( maxClients->zText()->getText(), 10 ) ) )
        {
            aktualisieren->removeStyle( Knopf::Style::Erlaubt );
            zurück->removeStyle( Knopf::Style::Erlaubt );
            update->removeStyle( Knopf::Style::Erlaubt );
            pausieren->removeStyle( Knopf::Style::Erlaubt );
            stoppen->removeStyle( Knopf::Style::Erlaubt );
            beenden->removeStyle( Knopf::Style::Erlaubt );
            terminieren->removeStyle( Knopf::Style::Erlaubt );
            setMaxClients->removeStyle( Knopf::Style::Erlaubt );
            maxClients->removeStyle( TextFeld::Style::Erlaubt );
            getDetails->start();
        }
        else
            serverFehler->setText( psc->getLetzterFehler() );
    }
    return 1;
}

bool PatchServer::updateStartenMausEreignis( void *o, MausEreignis me )
{
    if( me.id == ME_RLinks )
    {
        int id = -1;
        for( int i = 1; i < tabelle->getZeilenAnzahl(); i++ )
        {
            if( ( (KontrollKnopf*)tabelle->zZeichnung( 6, i ) )->hatStyle( KontrollKnopf::Style::Selected ) )
            {
                id = TextZuInt( tabelle->zZeilenName( i )->getText(), 10 );
                break;
            }
        }
        if( id > 0 )
        {
            int anzahl = 0;
            Array< int > *gruppen = new Array< int >();
            for( int i = 1; i < updateT->getZeilenAnzahl(); i++ )
            {
                if( updateT->zZeichnung( 2, i ) && ( (KontrollKnopf*)updateT->zZeichnung( 2, i ) )->hatStyle( KontrollKnopf::Style::Selected ) )
                {
                    int gId = TextZuInt( updateT->zZeilenName( i )->getText(), 10 );
                    gruppen->set( gId, anzahl );
                    anzahl++;
                }
            }
            if( anzahl )
            {
                updateStarten->removeStyle( Knopf::Style::Erlaubt );
                zurück->removeStyle( Knopf::Style::Erlaubt );
                aktualisieren->removeStyle( Knopf::Style::Erlaubt );
                updateT->removeStyle( ObjTabelle::Style::Erlaubt );
                updateTh->setUpdateListe( anzahl, gruppen );
                updateTh->start();
            }
            gruppen->release();
        }
    }
    return 1;
}

bool PatchServer::maxClientsTastaturEreignis( void *o, TastaturEreignis te )
{
    bool ret = 0;
    if( te.taste >= '0' && te.taste <= '9' )
        ret = 1;
    if( te.taste == T_Entf || te.taste == T_BackSpace )
        ret = 1;
    if( te.taste == T_Links || te.taste == T_Rechts )
        ret = 1;
    if( ret )
        setMaxClients->addStyle( Knopf::Style::Erlaubt );
    return ret;
}

// constant

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

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


// Ereignisse
bool patchServerAktualisierenMausEreignis( void *p, void *o, MausEreignis me )
{
    if( !p )
        return 0;
    return ( (PatchServer*)p )->aktualisierenMausEreignis( o, me );
}

bool patchServerAuswahlKnopfMausEreignis( void *p, void *o, MausEreignis me )
{
    if( !p )
        return 0;
    return ( (PatchServer*)p )->auswahlKnopfMausEreignis( o, me );
}

bool patchServerWeiterMausEreignis( void *p, void *o, MausEreignis me )
{
    if( !p )
        return 0;
    return ( (PatchServer*)p )->weiterMausEreignis( o, me );
}

bool patchServerZurückMausEreignis( void *p, void *o, MausEreignis me )
{
    if( !p )
        return 0;
    return ( (PatchServer*)p )->zurückMausEreignis( o, me );
}

bool patchServerUpdateMausEreignis( void *p, void *o, MausEreignis me )
{
    if( !p )
        return 0;
    return ( (PatchServer*)p )->updateMausEreignis( o, me );
}

bool patchServerPausierenMausEreignis( void *p, void *o, MausEreignis me )
{
    if( !p )
        return 0;
    return ( (PatchServer*)p )->pausierenMausEreignis( o, me );
}

bool patchServerStoppenMausEreignis( void *p, void *o, MausEreignis me )
{
    if( !p )
        return 0;
    return ( (PatchServer*)p )->stoppenMausEreignis( o, me );
}

bool patchServerBeendenMausEreignis( void *p, void *o, MausEreignis me )
{
    if( !p )
        return 0;
    return ( (PatchServer*)p )->beendenMausEreignis( o, me );
}

bool patchServerTerminierenMausEreignis( void *p, void *o, MausEreignis me )
{
    if( !p )
        return 0;
    return ( (PatchServer*)p )->terminierenMausEreignis( o, me );
}

bool patchServerSetMaxClientsMausEreignis( void *p, void *o, MausEreignis me )
{
    if( !p )
        return 0;
    return ( (PatchServer*)p )->setMaxClientsMausEreignis( o, me );
}

bool patchServerUpdateStartenMausEreignis( void *p, void *o, MausEreignis me )
{
    if( !p )
        return 0;
    return ( (PatchServer*)p )->updateStartenMausEreignis( o, me );
}

bool patchServerMaxClientsTastaturEreignis( void *p, void *o, TastaturEreignis te )
{
    if( !p )
        return 0;
    return ( (PatchServer*)p )->maxClientsTastaturEreignis( o, te );
}