#include "SpielStatistik.h"

SpielStatistik::SpielStatistik()
{
    InitializeCriticalSection( &cs );
    addNachrichtF = 0;
    addChatF = 0;
    addFreundF = 0;
    accountAnsehenF = 0;
    istFreundF = 0;
    nachrichtParam = 0;
    bilder = 0;
    schrift = 0;
    screen = 0;
    infoc = 0;
    spielc = 0;
    status = 0;
    gss = new Array< SSDSpieler * >();
    gts = new Array< SSDTeam * >();
    chat = 0;
    tabelle = 0;
    accountId = 0;
    rend = 0;
    ref = 1;
}

SpielStatistik::~SpielStatistik()
{
    if( chat )
        chat->release();
    if( tabelle )
        tabelle->release();
    if( schrift )
        schrift->release();
    if( infoc )
        infoc->release();
    if( spielc )
        spielc->release();
    int anz = gss->getEintragAnzahl();
    for( int i = 0; i < anz; i++ )
    {
        if( gss->hat( i ) )
            delete gss->get( i );
    }
    gss->release();
    anz = gts->getEintragAnzahl();
    for( int i = 0; i < anz; i++ )
    {
        if( gts->hat( i ) )
            delete gts->get( i );
    }
    gts->release();
    DeleteCriticalSection( &cs );
}

void SpielStatistik::lock()
{
    EnterCriticalSection( &cs );
}

void SpielStatistik::unlock()
{
    LeaveCriticalSection( &cs );
}

void SpielStatistik::bereit()
{
    char byte = 0;
    spielc->statistikNachricht( 1, &byte );
}

void SpielStatistik::setBilder( BilderV *b )
{
    bilder = b;
}

void SpielStatistik::setAccountId( int id )
{
    accountId = id;
}

void SpielStatistik::setR�ckrufFunktionen( void( *addNachrichtF )( void *, Text *, Text *, Text *, Text * ),
                                           void( *addChatF )( void *, int ), void( *addFreundF )( void *, int ),
                                           void( *accountAnsehenF )( void *, int ), bool( *istFreundF )( void *, int ), void *nachrichtParam )
{
    this->addNachrichtF = addNachrichtF;
    this->addChatF = addChatF;
    this->addFreundF = addFreundF;
    this->accountAnsehenF = accountAnsehenF;
    this->istFreundF = istFreundF;
    this->nachrichtParam = nachrichtParam;
}

void SpielStatistik::setSchrift( Schrift *schrift )
{
    if( this->schrift )
        this->schrift->release();
    this->schrift = schrift;
}

void SpielStatistik::setBildschirm( Bildschirm *zScreen )
{
    screen = zScreen;
}

void SpielStatistik::setKlients( KSGClient::InformationServerClient *infoc, KSGClient::SpielServerClient *spielc )
{
    if( this->infoc )
        this->infoc->release();
    if( this->spielc )
        this->spielc->release();
    this->infoc = infoc;
    this->spielc = spielc;
}

void SpielStatistik::nachricht( int l�n, char *bytes )
{
    lock();
    char num = *bytes;
    bytes++;
    l�n--;
    switch( num )
    {
    case 0: // Spieler Statistik
        if( 1 )
        {
            SSDSpieler *ssdgs = new SSDSpieler();
            ssdgs->spielerNummer = *(int *)bytes;
            bytes += 4;
            l�n -= 4;
            char snl�n = *bytes;
            l�n--;
            bytes++;
            char *txt = new char[ snl�n + 1 ];
            txt[ snl�n ] = 0;
            for( int i = 0; i < snl�n; i++ )
                txt[ i ] = bytes[ i ];
            bytes += snl�n;
            l�n -= snl�n;
            ssdgs->spielerName = txt;
            delete[] txt;
            char tnl�n = *bytes;
            l�n--;
            bytes++;
            txt = new char[ tnl�n + 1 ];
            txt[ tnl�n ] = 0;
            for( int i = 0; i < tnl�n; i++ )
                txt[ i ] = bytes[ i ];
            bytes += tnl�n;
            l�n -= tnl�n;
            ssdgs->teamName = txt;
            delete[] txt;
            ssdgs->spielerFarbe = *(int *)bytes;
            bytes += 4;
            l�n -= 4;
            ssdgs->teamFarbe = *(int *)bytes;
            bytes += 4;
            l�n -= 4;
            ssdgs->schadenBekommen = *(int *)bytes;
            bytes += 4;
            l�n -= 4;
            ssdgs->schadenGemacht = *(int *)bytes;
            bytes += 4;
            l�n -= 4;
            ssdgs->lebenGeheilt = *(int *)bytes;
            bytes += 4;
            l�n -= 4;
            ssdgs->sch�sse = *(int *)bytes;
            bytes += 4;
            l�n -= 4;
            ssdgs->treffer = *(int *)bytes;
            bytes += 4;
            l�n -= 4;
            ssdgs->punkte = *(int *)bytes;
            bytes += 4;
            l�n -= 4;
            ssdgs->kills = *(int *)bytes;
            bytes += 4;
            l�n -= 4;
            ssdgs->tode = *(int *)bytes;
            bytes += 4;
            l�n -= 4;
            ssdgs->itemsAufgehoben = *(int *)bytes;
            bytes += 4;
            l�n -= 4;
            ssdgs->itemsVerwendet = *(int *)bytes;
            bytes += 4;
            l�n -= 4;
            gss->add( ssdgs );
        }
        break;
    case 1: // Team Statistik
        if( 1 )
        {
            SSDTeam *ssdgt = new SSDTeam();
            ssdgt->teamNummer = *(int *)bytes;
            bytes += 4;
            l�n -= 4;
            char tnl�n = *bytes;
            l�n--;
            bytes++;
            char *txt = new char[ tnl�n + 1 ];
            txt[ tnl�n ] = 0;
            for( int i = 0; i < tnl�n; i++ )
                txt[ i ] = bytes[ i ];
            bytes += tnl�n;
            l�n -= tnl�n;
            ssdgt->teamName = txt;
            delete[] txt;
            ssdgt->teamFarbe = *(int *)bytes;
            bytes += 4;
            l�n -= 4;
            ssdgt->punkte = *(int *)bytes;
            bytes += 4;
            l�n -= 4;
            ssdgt->kills = *(int *)bytes;
            bytes += 4;
            l�n -= 4;
            ssdgt->tode = *(int *)bytes;
            bytes += 4;
            l�n -= 4;
            gts->add( ssdgt );
        }
        break;
    case 2: // Ladevorgang abgeschlossen
        if( 1 )
        {
            chat = new StatistikChat( accountId, spielc->getThis(), infoc->getThis(), schrift->getThis(), bilder, addNachrichtF, addChatF, addFreundF, accountAnsehenF, nachrichtParam );
            int anz = gss->getEintragAnzahl();
            for( int i = 0; i < anz; i++ )
            {
                if( gss->hat( i ) )
                {
                    int acc = infoc->getAccountId( gss->get( i )->spielerName );
                    if( acc )
                        chat->addSpieler( acc, istFreundF( nachrichtParam, acc ) || acc == accountId );
                }
            }
            tabelle = new StatistikTabelle( gss->getThis(), gts->getThis(), schrift, screen );
            status = 1;
        }
        break;
    case 3: // Chat Nachricht
        if( 1 )
        {
            int vonAccount = *(int *)bytes;
            bytes += 4;
            l�n -= 4;
            char *txt = new char[ (__int64)l�n + 1 ];
            txt[ l�n ] = 0;
            for( int i = 0; i < l�n; i++ )
                txt[ i ] = bytes[ i ];
            if( status == 1 )
                chat->addChatNachricht( vonAccount, txt );
            delete[] txt;
        }
        break;
    case 4: // Spieler hat verlassen
        if( 1 )
        {
            int acc = *(int *)bytes;
            bytes += 4;
            l�n -= 4;
            if( status == 1 )
                chat->spielerOffline( acc );
        }
        break;
    default:
        // Fehler
        break;
    }
    if( l�n != 0 )
    {
        // Fehler
    }
    unlock();
}

void SpielStatistik::doPublicMausEreignis( MausEreignis &me )
{
    if( !status )
        return;
    lock();
    if( status == 1 )
    {
        tabelle->doPublicMausEreignis( me );
        chat->doPublicMausEreignis( me );
    }
    unlock();
}

void SpielStatistik::doTastaturEreignis( TastaturEreignis &te )
{
    if( !status )
        return;
    lock();
    if( status == 1 )
        chat->doTastaturEreignis( te );
    unlock();
}

bool SpielStatistik::tick( double zeit )
{
    if( !status )
        return 0;
    lock();
    if( status == 1 )
    {
        rend |= chat->tick( zeit );
        rend |= tabelle->tick( zeit );
        if( chat->hatVerlassen() && status == 1 )
        {
            spielc->trenne();
            status = 2;
        }
    }
    bool ret = rend;
    rend = 0;
    unlock();
    return ret;
}

void SpielStatistik::render( Bild &zRObj )
{
    if( !status )
        return;
    lock();
    chat->render( zRObj );
    tabelle->render( zRObj );
    unlock();
}

void SpielStatistik::verlassen()
{
    if( spielc )
        spielc->trenne();
    status = 2;
}

// constant
int SpielStatistik::getStatus() const // 0 = laden, 1 = l�uft, 2 = fortsetzen
{
    return status;
}

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

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