#include "Men�.h"
#include "Initialisierung.h"
#include <MausEreignis.h>
#include <Textfeld.h>
#include <InitDatei.h>
#include <Text.h>
#include <Datei.h>
#include <TastaturEreignis.h>
#include <KSGTDatei.h>
#include <Schrift.h>
#include <DateiSystem.h>
#include <Rahmen.h>
#include <Bildschirm.h>
#include <AsynchronCall.h>

// Inhalt der Men�Verloren Klasse aus Men�.h
// Kontruktor
Men�Verloren::Men�Verloren( Schrift *zSchrift )
{
	ram = new LRahmen();
	ram->setSize( 160, 100 );
	ram->setPosition( 320, 200 );
	ram->setFarbe( 0xFFFFFFFF );
	verloren = initTextFeld( 325, 210, 150, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Du hast verloren." );
	neu = initKnopf( 350, 240, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Neues Spiel" );
	beenden = initKnopf( 350, 270, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Zur�ck" );
	ref = 1;
}

// Destruktor
Men�Verloren::~Men�Verloren()
{
	verloren->release();
	neu->release();
	beenden->release();
	ram->release();
}

// nicht constant
int Men�Verloren::doMausEreignis( MausEreignis &me )
{
	bool vera = me.verarbeitet;
	int ret = 0;
	neu->doMausEreignis( me );
	if( !vera && me.verarbeitet && me.id == ME_RLinks )
		ret = 1;
	beenden->doMausEreignis( me );
	if( !vera && me.verarbeitet && !ret && me.id == ME_RLinks )
		ret = 2;
	return ret;
}

bool Men�Verloren::tick( double tickVal )
{
	bool ret = verloren->tick( tickVal );
	ret |= neu->tick( tickVal );
	ret |= beenden->tick( tickVal );
	return ret;
}

void Men�Verloren::render( Bild &zRObj )
{
	zRObj.alphaRegion( ram->getX(), ram->getY(), ram->getBreite(), ram->getHeight(), 0xD0000000 );
	verloren->render( zRObj );
	neu->render( zRObj );
	beenden->render( zRObj );
	ram->render( zRObj );
}

// Reference Counting
Men�Verloren *Men�Verloren::getThis()
{
	ref++;
	return this;
}

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


// Inhalt der Men�Spiel Klasse aus Men�.h
// Konstruktor
Men�Spiel::Men�Spiel( Schrift *zSchrift, Bildschirm *zScreen, MinigameKlientV *klient )
{
	scoreT = initTextFeld( 690, 10, 100, 20, zSchrift, TextFeld::Style::Text, "Score: 0" );
	beenden = initKnopf( 690, 40, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Beenden" );
	map = new Map( klient );
	verloren = new Men�Verloren( zSchrift );
    timePuffer = 0;
	beendet = 0;
	ref = 1;
}

// Destruktor
Men�Spiel::~Men�Spiel()
{
	scoreT->release();
	beenden->release();
	map->release();
	verloren->release();
}

// nicht constant
void Men�Spiel::reset()
{
    timePuffer = 0;
    Text optionen = "Width=";
    InitDatei *opd = new InitDatei( "data/Minigames/Bl�cke/data/optionen.ini" );
    if( !opd->laden() )
        DateiPfadErstellen( "data/Minigames/Bl�cke/data/optionen.ini" );
    if( opd->wertExistiert( "Breite" ) )
        optionen += (int)*opd->zWert( "Breite" );
    else
    {
        opd->addWert( "Breite", "20" );
        optionen += 20;
    }
    optionen += ",Height=";
    if( opd->wertExistiert( "Height" ) )
        optionen += (int)*opd->zWert( "Height" );
    else
    {
        opd->addWert( "Height", "12" );
        optionen += 12;
    }
    optionen += ",Farben=";
    if( opd->wertExistiert( "Farben" ) )
        optionen += (int)*opd->zWert( "Farben" );
    else
    {
        opd->addWert( "Farben", "5" );
        optionen += 5;
    }
    optionen += ",Speed=";
    if( opd->wertExistiert( "Geschwindigkeit" ) )
        optionen += (int)*opd->zWert( "Geschwindigkeit" );
    else
    {
        opd->addWert( "Geschwindigkeit", "4000" );
        optionen += 4000;

    }
    optionen += ",Fortsetzen=";
    if( opd->wertExistiert( "Fortsetzen" ) )
        optionen += (int)*opd->zWert( "Fortsetzen" ) != 0;
    else
    {
        opd->addWert( "Fortsetzen", "0" );
        optionen += 0;

    }
    optionen += ",Seed=0";
    opd->speichern();
    opd->release();
	map->reset( &optionen );
	beendet = 0;
	scoreT->setText( "Score: " );
	scoreT->zText()->append( map->getScore() );
}

void Men�Spiel::doMausEreignis( MausEreignis &me )
{
	bool vera = me.verarbeitet;
	beenden->doMausEreignis( me );
	if( !vera && me.verarbeitet && me.id == ME_RLinks )
	{
		map->speichern();
		beendet = 1;
	}
	map->doMausEreignis( me );
	scoreT->setText( "Score: " );
	scoreT->zText()->append( map->getScore() );
	if( map->istBeendet() )
	{
		int ak = verloren->doMausEreignis( me );
		if( ak == 1 )
			reset();
		if( ak == 2 )
			beendet = 1;
	}
}

void Men�Spiel::doTastaturEreignis( TastaturEreignis &te )
{
	if( map->istBeendet() )
	{
		if( te.id == TE_Release && te.taste == T_Enter )
			reset();
		if( te.id == TE_Release && te.taste == T_BackSpace )
			beendet = 1;
		return;
	}
	map->doTastaturEreignis( te );
}

bool Men�Spiel::tick( double tickVal )
{
	bool ret = beenden->tick( tickVal );
    timePuffer += tickVal;
    while( timePuffer >= 0.01 )
    {
        ret |= map->tick( 0.01 );
        timePuffer -= 0.01;
    }
	ret |= map->tick( tickVal );
	if( map->istBeendet() )
		ret |= verloren->tick( tickVal );
	return ret;
}

void Men�Spiel::render( Bild &zRObj )
{
	map->render( zRObj );
	scoreT->render( zRObj );
	beenden->render( zRObj );
	if( map->istBeendet() )
		verloren->render( zRObj );
}

// constant
bool Men�Spiel::istBeendet() const
{
	return beendet;
}

// Reference Counting
Men�Spiel *Men�Spiel::getThis()
{
	ref++;
	return this;
}

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


// Inhalt der Men�Wiederhohlung Klasse
// Konstruktor
Men�Wiederhohlung::Men�Wiederhohlung( Schrift *zSchrift, Bildschirm *zScreen, Datei *datei, Text *zOptionen )
{
    scoreT = initTextFeld( 690, 10, 100, 20, zSchrift, TextFeld::Style::Text, "Score: 0" );
    beenden = initKnopf( 690, 40, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Beenden" );
    this->datei = datei;
    if( !datei->istOffen() )
        datei->open( Datei::Style::lesen );
    __int64 seed;
    datei->lese( (char*)&seed, 8 );
    zOptionen->append( ",Fortsetzen=0,Seed=" );
    zOptionen->append( seed );
    map = new Map( 0 );
    map->reset( zOptionen );
    beendet = 0;
    nowTime = 0;
    nextTime = 0;
    datei->lese( (char*)&nextTime, 8 );
    timePuffer = 0;
    ref = 1;
}

// Destruktor
Men�Wiederhohlung::~Men�Wiederhohlung()
{
    scoreT->release();
    beenden->release();
    map->release();
    datei->close();
    datei->release();
}

// nicht constant
void Men�Wiederhohlung::doMausEreignis( MausEreignis &me )
{
    bool vera = me.verarbeitet;
    beenden->doMausEreignis( me );
    if( !vera && me.verarbeitet && me.id == ME_RLinks )
        beendet = 1;
    if( map->istBeendet() )
        beendet = 1;
}

void Men�Wiederhohlung::doTastaturEreignis( TastaturEreignis &te )
{}

bool Men�Wiederhohlung::tick( double tickVal )
{
    bool ret = beenden->tick( tickVal );
    // TODO Replay Activity
    while( nextTime >= 0 && nowTime + tickVal >= nextTime )
    {
        while( nowTime < nextTime )
        {
            ret |= map->tick( 0.01 );
            tickVal -= 0.01;
            nowTime += 0.01;
        }
        char ak;
        MausEreignis me;
        datei->lese( &ak, 1 );
        me.id = ME_RRechts;
        if( ak == 0 )
        {
            datei->lese( (char*)&me.mx, 4 );
            datei->lese( (char*)&me.my, 4 );
            me.id = ME_RLinks;
        }
        if( datei->istEnde() )
            nextTime = -1;
        else
            datei->lese( (char*)&nextTime, 8 );
        me.verarbeitet = 0;
        map->doMausEreignis( me );
    }
    timePuffer += tickVal;
    while( timePuffer > 0 )
    {
        ret |= map->tick( 0.01 );
        nowTime += 0.01;
        timePuffer -= 0.01;
    }
    scoreT->setText( "Score: " );
    scoreT->zText()->append( map->getScore() );
    return ret;
}

void Men�Wiederhohlung::render( Bild &zRObj )
{
    map->render( zRObj );
    scoreT->render( zRObj );
    beenden->render( zRObj );
}

// constant
bool Men�Wiederhohlung::istBeendet() const
{
    return beendet;
}

// Reference Counting
Men�Wiederhohlung *Men�Wiederhohlung::getThis()
{
    ref++;
    return this;
}

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

// Inhalt der Men�Statistik Klasse aus Men�.h
// Konstruktor
Men�Statistik::Men�Statistik( Schrift *zSchrift, Bildschirm *zScreen, MinigameKlientV *klient )
{
    this->klient = klient;
    wiederH = 0;
	ansichtT = initTextFeld( 245, 10, 50, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, "Ansicht:" );
	ansicht = initAuswahlBox( 295, 10, 120, 20, zSchrift, AuswahlBox::Style::Normal | AuswahlBox::Style::Hintergrund, { "Tabelle", "Diagramm" } );
	optionen = initKontrollKnopf( 425, 10, 130, 20, zSchrift, KontrollKnopf::Style::Normal, "Optionen beachten" );
    worldBestT = initObjTabelle( 150, 40, 500, 120, zSchrift, ObjTabelle::Style::normal | ObjTabelle::Style::VScroll, { { "Score", 60, 0, 0 }, { "Spieler", 100, 0, 0 }, { "Ansehen", 55, 0, 0 }, { "Breite", 70, 0, 0 },{ "Height", 70, 0, 0 },{ "Farben", 65, 0, 0 },{ "Tempo", 60, 0, 0 } }, 20 );
	gesammtT = initObjTabelle( 150, 170, 500, 290, zSchrift, ObjTabelle::Style::normal | ObjTabelle::Style::VScroll, { { "Score", 70, 0, 0 }, { "Datum", 145, 0, 0 }, { "Breite", 70, 0, 0 }, { "Height", 70, 0, 0 }, { "Farben", 65, 0, 0 }, { "Tempo", 60, 0, 0 } }, 20 );
	optionenT = initObjTabelle( 150, 170, 500, 290, zSchrift, ObjTabelle::Style::normal | ObjTabelle::Style::VScroll, { { "Score", 70, 0, 0 }, { "Datum", 145, 0, 0 }, { "Breite", 70, 0, 0 }, { "Height", 70, 0, 0 }, { "Farben", 65, 0, 0 }, { "Tempo", 60, 0, 0 } }, 20 );
	gesammtD = initLinienDiagramm( 100, 170, 600, 290, zSchrift, LDiag::Style::DatenRahmen, 0 );
	optionenD = initLinienDiagramm( 100, 170, 600, 290, zSchrift, LDiag::Style::DatenRahmen, 0 );
	removen = initKnopf( 10, 470, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Zur�cksetzen" );
	zur�ck = initKnopf( 350, 470, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Zur�ck" );
	schrift = zSchrift->getThis();
    screen = zScreen->getThis();
    asyncFinished = 1;
}

// Destruktor
Men�Statistik::~Men�Statistik()
{
	int anz = gesammtT->getZeilenAnzahl();
	for( int i = 0; i < anz; i++ )
	{
		for( int j = 0; j < 6; j++ )
			( (TextFeld*)gesammtT->zZeichnung( j, 0 ) )->release();
		gesammtT->removeZeile( 0 );
	}
	for( int j = 0; j < 6; j++ )
		( (TextFeld*)optionenT->zZeichnung( j, 0 ) )->release();
    while( !asyncFinished )
    {
        Sleep( 100 );
    }
    anz = worldBestT->getZeilenAnzahl();
    for( int i = 0; i < anz; i++ )
    {
        for( int j = 0; j < 7; j++ )
        {
            if( j == 2 )
                ( (Knopf*)worldBestT->zZeichnung( j, 0 ) )->release();
            else
                ( (TextFeld*)worldBestT->zZeichnung( j, 0 ) )->release();
        }
        worldBestT->removeZeile( 0 );
    }
    worldBestT->release();
	ansichtT->release();
	ansicht->release();
	optionen->release();
	gesammtT->release();
	optionenT->release();
	gesammtD->release();
	optionenD->release();
	removen->release();
	zur�ck->release();
	schrift->release();
    klient->release();
    if( wiederH )
        wiederH->release();
    screen->release();
}

// nicht constant
void Men�Statistik::reset()
{
	int anz = gesammtT->getZeilenAnzahl();
	for( int i = 1; i < anz; i++ )
	{
		for( int j = 0; j < 6; j++ )
			( (TextFeld*)gesammtT->zZeichnung( j, 1 ) )->release();
		gesammtT->removeZeile( 1 );
	}
	anz = optionenT->getZeilenAnzahl();
	for( int i = 1; i < anz; i++ )
		optionenT->removeZeile( 1 );
    anz = worldBestT->getZeilenAnzahl();
    for( int i = 1; i < anz; i++ )
    {
        for( int j = 0; j < 7; j++ )
        {
            if( j == 2 )
                ( (Knopf*)worldBestT->zZeichnung( j, 1 ) )->release();
            else
                ( (TextFeld*)worldBestT->zZeichnung( j, 1 ) )->release();
        }
        worldBestT->removeZeile( 1 );
    }
    ObjTabelle *tmpWBT = worldBestT->getThis();
    MinigameKlientV *tmpKlient = klient->getThis();
    Schrift *tmpSchrift = schrift->getThis();
    new AsynchronCall( [ this, tmpWBT, tmpKlient, tmpSchrift ]()
    {
        Array< int > score;
        RCArray< Text > player;
        RCArray< Text > option;
        int anz = tmpKlient->getMinigameBestscoreList( "Bloecke", &score, &player, &option );
        for( int i = 0; i < anz; i++ )
        {
            TextFeld *scoreT = initTextFeld( 0, 0, 0, 0, tmpSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, Text( score.get( i ) ) );
            TextFeld *spielerT = initTextFeld( 0, 0, 0, 0, tmpSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, player.z( i )->getText() );
            Text optionen = option.z( i )->getText();
            Text *breite = optionen.getTeilText( optionen.positionVon( '=' ) + 1, optionen.positionVon( ',' ) );
            Text *h�he = optionen.getTeilText( optionen.positionVon( '=', 1 ) + 1, optionen.positionVon( ',', 1 ) );
            Text *farben = optionen.getTeilText( optionen.positionVon( '=', 2 ) + 1, optionen.positionVon( ',', 2 ) );
            Text *geschwindigkeit = optionen.getTeilText( optionen.positionVon( '=', 3 ) + 1 );
            TextFeld *breiteT = initTextFeld( 0, 0, 0, 0, tmpSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, breite->getText() );
            breite->release();
            TextFeld *h�heT = initTextFeld( 0, 0, 0, 0, tmpSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, h�he->getText() );
            h�he->release();
            TextFeld *farbenT = initTextFeld( 0, 0, 0, 0, tmpSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, farben->getText() );
            farben->release();
            TextFeld *geschwindigkeitT = initTextFeld( 0, 0, 0, 0, tmpSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, geschwindigkeit->getText() );
            geschwindigkeit->release();
            Knopf *ansehenK = initKnopf( 0, 0, 0, 0, tmpSchrift, Knopf::Style::Normal, "Ansehen" );
            ansehenK->setMausEreignis( [ this, optionen ]( void *p, void *obj, MausEreignis me ) -> bool
            {
                if( me.id == ME_RLinks && !me.verarbeitet )
                {
                    ( (Knopf*)obj )->removeStyle( Knopf::Style::Erlaubt );
                    getThis();
                    new AsynchronCall( [ this, optionen, obj ]()
                    {
                        Datei *d = klient->downloadGameCapture( "Bloecke", optionen );
                        ( (Knopf*)obj )->addStyle( Knopf::Style::Erlaubt );
                        if( wiederH )
                            wiederH = wiederH->release();
                        Text options = optionen.getText();
                        wiederH = new Men�Wiederhohlung( schrift, screen, d, &options );
                        release();
                    } );
                }
                return 1;
            } );
            tmpWBT->addZeile( optionen.getText() );
            tmpWBT->setZeichnungZ( 0, i + 1, scoreT );
            tmpWBT->setZeichnungZ( 1, i + 1, spielerT );
            tmpWBT->setZeichnungZ( 2, i + 1, ansehenK );
            tmpWBT->setZeichnungZ( 3, i + 1, breiteT );
            tmpWBT->setZeichnungZ( 4, i + 1, h�heT );
            tmpWBT->setZeichnungZ( 5, i + 1, farbenT );
            tmpWBT->setZeichnungZ( 6, i + 1, geschwindigkeitT );
        }
        tmpKlient->release();
        tmpWBT->release();
        tmpSchrift->release();
    }, &asyncFinished );
	InitDatei *opd = new InitDatei( "data/Minigames/Bl�cke/data/optionen.ini" );
	opd->laden();
	if( !opd->wertExistiert( "Breite" ) )
		opd->addWert( "Breite", "20" );
	if( !opd->wertExistiert( "Height" ) )
		opd->addWert( "Height", "12" );
	if( !opd->wertExistiert( "Farben" ) )
		opd->addWert( "Farben", "5" );
	if( !opd->wertExistiert( "Geschwindigkeit" ) )
		opd->addWert( "Geschwindigkeit", "4000" );
	if( !opd->wertExistiert( "Fortsetzen" ) )
		opd->addWert( "Fortsetzen", "0" );
	opd->speichern();
	KSGTDatei *stb = new KSGTDatei( "data/Minigames/Bl�cke/data/score.ksgt" );
	stb->laden();
	anz = stb->getZeilenAnzahl();
	bool *fertig = new bool[ anz ];
	ZeroMemory( fertig, anz );
	int mS = 0;
	int omS = 0;
	int oAnz = 0;
	for( int i = 0; i < anz; i++ )
	{
		int maxScore = -1;
		int p = -1;
		for( int j = 0; j < anz; j++ )
		{
			if( !fertig[ j ] && maxScore < (int)*stb->zFeld( j, 1 ) )
			{
				p = j;
				maxScore = (int)*stb->zFeld( j, 1 );
			}
		}
		if( p >= 0 )
		{
			fertig[ p ] = 1;
			TextFeld *scoreT = initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, stb->zFeld( p, 1 )->getText() );
			TextFeld *datumT = initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, stb->zFeld( p, 0 )->getText() );
			TextFeld *breiteT = initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, stb->zFeld( p, 2 )->getText() );
			TextFeld *h�heT = initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, stb->zFeld( p, 3 )->getText() );
			TextFeld *farbenT = initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, stb->zFeld( p, 5 )->getText() );
			TextFeld *tempoT = initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, stb->zFeld( p, 4 )->getText() );
			gesammtT->addZeile( Text() += p );
			gesammtT->setZeichnungZ( 0, i + 1, scoreT );
			gesammtT->setZeichnungZ( 1, i + 1, datumT );
			gesammtT->setZeichnungZ( 2, i + 1, breiteT );
			gesammtT->setZeichnungZ( 3, i + 1, h�heT );
			gesammtT->setZeichnungZ( 4, i + 1, farbenT );
			gesammtT->setZeichnungZ( 5, i + 1, tempoT );
			if( breiteT->zText()->istGleich( opd->zWert( "Breite" )->getText() ) &&
				h�heT->zText()->istGleich( opd->zWert( "Height" )->getText() ) &&
				farbenT->zText()->istGleich( opd->zWert( "Farben" )->getText() ) &&
				tempoT->zText()->istGleich( opd->zWert( "Geschwindigkeit" )->getText() ) )
			{
				optionenT->addZeile( Text() += p );
				int n = optionenT->getZeilenNummer( Text() += p );
				optionenT->setZeichnungZ( 0, n, scoreT );
				optionenT->setZeichnungZ( 1, n, datumT );
				optionenT->setZeichnungZ( 2, n, breiteT );
				optionenT->setZeichnungZ( 3, n, h�heT );
				optionenT->setZeichnungZ( 4, n, farbenT );
				optionenT->setZeichnungZ( 5, n, tempoT );
				if( !omS )
					omS = maxScore;
				oAnz++;
			}
		}
		if( !mS )
			mS = maxScore;
	}
	delete[] fertig;
	DiagDaten *gd = new DiagDaten();
	gd->style = DiagDaten::Style::autoIntervall | DiagDaten::Style::autoRaster | DiagDaten::Style::intervalle | DiagDaten::Style::intervallTexte | DiagDaten::Style::Sichtbar;
	gd->hIntervallFarbe = 0xFFFFFFFF;
	gd->hIntervallName->setText( "Spiel" );
	gd->rasterDicke = 1;
	gd->rasterFarbe = 0xFF505050;
	gd->vIntervallFarbe = 0xFFFFFFFF;
	gd->vIntervallName->setText( "Score" );
	gesammtD->setDiagDatenZ( gd );
	gesammtD->addVIntervallText( mS + 1, Text() += ( mS + 1 ) );
	gesammtD->addVIntervallText( 0, "0" );
	gesammtD->addHIntervallText( 0, "1" );
	if( anz > 1 )
		gesammtD->addHIntervallText( anz - 1, Text() += anz );
	gesammtD->addWert( "Score" );
	gesammtD->setWertStyle( 0, DiagWert::Style::Sichtbar | DiagWert::Style::Hintergrund );
	gesammtD->setWertFarbe( 0, 0xFF00FF00 );
	gesammtD->zDiagWert( 0 )->hintergrund = 0xFF205050;
	DiagDaten *od = new DiagDaten();
	od->style = DiagDaten::Style::autoIntervall | DiagDaten::Style::autoRaster | DiagDaten::Style::intervalle | DiagDaten::Style::intervallTexte | DiagDaten::Style::Sichtbar;
	od->hIntervallFarbe = 0xFFFFFFFF;
	od->hIntervallName->setText( "Spiel" );
	od->rasterDicke = 1;
	od->rasterFarbe = 0xFF505050;
	od->vIntervallFarbe = 0xFFFFFFFF;
	od->vIntervallName->setText( "Score" );
	optionenD->setDiagDatenZ( od );
	optionenD->addVIntervallText( omS + 1, Text() += ( omS + 1 ) );
	optionenD->addVIntervallText( 0, "0" );
	optionenD->addHIntervallText( 0, "1" );
	if( oAnz > 1 )
		optionenD->addHIntervallText( oAnz - 1, Text() += oAnz );
	optionenD->addWert( "Score" );
	optionenD->setWertStyle( 0, DiagWert::Style::Sichtbar | DiagWert::Style::Hintergrund );
	optionenD->setWertFarbe( 0, 0xFF00FF00 );
	optionenD->zDiagWert( 0 )->hintergrund = 0xFF205050;
	int j = 0;
	for( int i = 0; i < anz; i++ )
	{
		gesammtD->addPunkt( 0, i, (int)*stb->zFeld( i, 1 ) );
		if( (int)*stb->zFeld( i, 2 ) == (int)*opd->zWert( "Breite" ) &&
			(int)*stb->zFeld( i, 3 ) == (int)*opd->zWert( "Height" ) &&
			(int)*stb->zFeld( i, 5 ) == (int)*opd->zWert( "Farben" ) &&
			(int)*stb->zFeld( i, 4 ) == (int)*opd->zWert( "Geschwindigkeit" ) )
		{
			optionenD->addPunkt( 0, j, (int)*stb->zFeld( i, 1 ) );
			j++;
		}
	}
	stb->release();
	opd->release();
	beendet = 0;
}

void Men�Statistik::doMausEreignis( MausEreignis &me )
{
    if( wiederH )
    {
        wiederH->doMausEreignis( me );
        return;
    }
	ansicht->doMausEreignis( me );
	optionen->doMausEreignis( me );
    gesammtT->doMausEreignis( me );
    optionenT->doMausEreignis( me );
    worldBestT->doMausEreignis( me );
	bool vera = me.verarbeitet;
	removen->doMausEreignis( me );
	if( !vera && me.verarbeitet && me.id == ME_RLinks )
	{ // Statistik removen
		if( optionen->hatStyle( KontrollKnopf::Style::Selected ) )
		{ // nur bestimmte Statistik removen
			InitDatei *opd = new InitDatei( "data/Minigames/Bl�cke/data/optionen.ini" );
			opd->laden();
			KSGTDatei *score = new KSGTDatei( "data/Minigames/Bl�cke/data/score.ksgt" );
			score->laden();
			int zeilen = score->getZeilenAnzahl();
			for( int i = 0; i < zeilen; i++ )
			{
				if( (int)*score->zFeld( i, 2 ) == (int)*opd->zWert( "Breite" ) &&
					(int)*score->zFeld( i, 3 ) == (int)*opd->zWert( "Height" ) &&
					(int)*score->zFeld( i, 5 ) == (int)*opd->zWert( "Farben" ) &&
					(int)*score->zFeld( i, 4 ) == (int)*opd->zWert( "Geschwindigkeit" ) )
				{
					score->removeZeile( i );
					i--;
					zeilen--;
				}
			}
			score->speichern();
			score->release();
			opd->release();
		}
		else // alles removen
			DateiRemove( "data/Minigames/Bl�cke/data/score.ksgt" );
		reset();
	}
	vera = me.verarbeitet;
	zur�ck->doMausEreignis( me );
	if( !vera && me.verarbeitet && me.id == ME_RLinks )
		beendet = 1;
}

bool Men�Statistik::tick( double tickVal )
{
    if( wiederH )
    {
        bool ret = wiederH->tick( tickVal );
        if( wiederH->istBeendet() )
            wiederH = wiederH->release();
        return ret;
    }
	bool ret = ansicht->tick( tickVal );
	ret |= optionen->tick( tickVal );
	ret |= removen->tick( tickVal );
	ret |= zur�ck->tick( tickVal );
	ret |= gesammtT->tick( tickVal );
	ret |= optionenT->tick( tickVal );
	ret |= gesammtD->tick( tickVal );
	ret |= optionenD->tick( tickVal );
    ret |= worldBestT->tick( tickVal );
	return ret;
}

void Men�Statistik::render( Bild &zRObj )
{
    if( wiederH )
    {
        wiederH->render( zRObj );
        return;
    }
    schrift->setSchriftSize( 12 );
    Text weltScore = "Welt Score:";
    schrift->setDrawPosition( 10, 40 );
    schrift->renderText( &weltScore, zRObj, 0xFFFFFFFF );
    Text localScore = "Dein Score:";
    schrift->setDrawPosition( 10, 170 );
    schrift->renderText( &localScore, zRObj, 0xFFFFFFFF );
    worldBestT->render( zRObj );
	if( !ansicht->getAuswahl() )
	{
		if( optionen->hatStyle( KontrollKnopf::Style::Selected ) )
			optionenT->render( zRObj );
		else
			gesammtT->render( zRObj );
	}
	else
	{
		if( optionen->hatStyle( KontrollKnopf::Style::Selected ) )
			optionenD->render( zRObj );
		else
			gesammtD->render( zRObj );
	}
	ansichtT->render( zRObj );
	ansicht->render( zRObj );
	optionen->render( zRObj );
	removen->render( zRObj );
	zur�ck->render( zRObj );
}

// constant
bool Men�Statistik::istBeendet() const
{
	return beendet;
}

bool Men�Statistik::istWiederhohlung() const
{
    return wiederH != 0;
}

// Reference Counting
Men�Statistik *Men�Statistik::getThis()
{
	ref++;
	return this;
}

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


// Inhalt der Men�Optionen aus Men�.h
// Konstruktor
Men�Optionen::Men�Optionen( Schrift *zSchrift, Bildschirm *zScreen )
{
	breiteT = initTextFeld( 310, 140, 130, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, "Spielfeld Breite:" );
	breite = initTextFeld( 440, 140, 50, 20, zSchrift, TextFeld::Style::TextFeld, "" );
	breite->setTastaturEreignis( _nurNummernTE );
	h�heT = initTextFeld( 310, 180, 130, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, "Spielfeld Height:" );
	h�he = initTextFeld( 440, 180, 50, 20, zSchrift, TextFeld::Style::TextFeld, "" );
	h�he->setTastaturEreignis( _nurNummernTE );
	bAnzahlT = initTextFeld( 310, 220, 130, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, "Verschiedene Farben:" );
	bAnzahl = initTextFeld( 440, 220, 50, 20, zSchrift, TextFeld::Style::TextFeld, "" );
	bAnzahl->setTastaturEreignis( _nurNummernTE );
	tempoT = initTextFeld( 310, 260, 130, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, "Zeit Abst�nde:" );
	tempo = initTextFeld( 440, 260, 50, 20, zSchrift, TextFeld::Style::TextFeld, "" );
	tempo->setTastaturEreignis( _nurNummernTE );
	fortsetzen = initKontrollKnopf( 310, 300, 180, 20, zSchrift, KontrollKnopf::Style::Normal, "Letztes Spiel fortsetzen" );
	fortsetzen->setMausEreignis( _ret1ME );
	abbrechen = initKnopf( 310, 340, 85, 20, zSchrift, Knopf::Style::Sichtbar, "Abbrechen" );
	ok = initKnopf( 405, 340, 85, 20, zSchrift, Knopf::Style::Sichtbar, "Ok" );
	beendet = 0;
	ref = 1;
}

// Destruktor
Men�Optionen::~Men�Optionen()
{
	breiteT->release();
	breite->release();
	h�heT->release();
	h�he->release();
	bAnzahlT->release();
	bAnzahl->release();
	tempoT->release();
	tempo->release();
	fortsetzen->release();
	abbrechen->release();
	ok->release();
}

// nicht constant
void Men�Optionen::reset()
{
	InitDatei *opd = new InitDatei( "data/Minigames/Bl�cke/data/optionen.ini" );
	if( !opd->laden() )
		DateiPfadErstellen( "data/Minigames/Bl�cke/data/optionen.ini" );
	breite->setText( "20" );
	if( opd->wertExistiert( "Breite" ) )
		breite->setText( Text() += (int)*opd->zWert( "Breite" ) );
	else
		opd->addWert( "Breite", "20" );
	h�he->setText( "12" );
	if( opd->wertExistiert( "Height" ) )
		h�he->setText( Text() += (int)*opd->zWert( "Height" ) );
	else
		opd->addWert( "Height", "12" );
	bAnzahl->setText( "5" );
	if( opd->wertExistiert( "Farben" ) )
		bAnzahl->setText( Text() += (int)*opd->zWert( "Farben" ) );
	else
		opd->addWert( "Farben", "5" );
	tempo->setText( "4000" );
	if( opd->wertExistiert( "Geschwindigkeit" ) )
		tempo->setText( Text() += (int)*opd->zWert( "Geschwindigkeit" ) );
	else
		opd->addWert( "Geschwindigkeit", "4000" );
	fortsetzen->removeStyle( KontrollKnopf::Style::Selected );
	if( opd->wertExistiert( "Fortsetzen" ) )
		fortsetzen->setStyle( KontrollKnopf::Style::Selected, (int)*opd->zWert( "Fortsetzen" ) != 0 );
	else
		opd->addWert( "Fortsetzen", "0" );
	beendet = 0;
	opd->speichern();
	opd->release();
}

void Men�Optionen::doMausEreignis( MausEreignis &me )
{
	breite->doMausEreignis( me );
	h�he->doMausEreignis( me );
	bAnzahl->doMausEreignis( me );
	tempo->doMausEreignis( me );
	fortsetzen->doMausEreignis( me );
	bool vera = me.verarbeitet;
	abbrechen->doMausEreignis( me );
	if( !vera && me.verarbeitet && me.id == ME_RLinks )
		beendet = 1;
	vera = me.verarbeitet;
	ok->doMausEreignis( me );
	if( !vera && me.verarbeitet && me.id == ME_RLinks )
	{
		InitDatei *opd = new InitDatei( "data/Minigames/Bl�cke/data/optionen.ini" );
		if( !opd->laden() )
			DateiPfadErstellen( "data/Minigames/Bl�cke/data/optionen.ini" );
		if( (int)*breite->zText() > 100 )
			breite->setText( "100" );
		if( (int)*breite->zText() < 10 )
			breite->setText( "10" );
		if( opd->wertExistiert( "Breite" ) )
			opd->setWert( "Breite", Text() += (int)*breite->zText() );
		else
			opd->addWert( "Breite", Text() += (int)*breite->zText() );
		if( (int)*h�he->zText() > 100 )
			h�he->setText( "100" );
		if( (int)*h�he->zText() < 10 )
			h�he->setText( "10" );
		if( opd->wertExistiert( "Height" ) )
			opd->setWert( "Height", Text() += (int)*h�he->zText() );
		else
			opd->addWert( "Height", Text() += (int)*h�he->zText() );
		if( (int)*bAnzahl->zText() > 10 )
			bAnzahl->setText( "10" );
		if( (int)*bAnzahl->zText() < 3 )
			bAnzahl->setText( "3" );
		if( opd->wertExistiert( "Farben" ) )
			opd->setWert( "Farben", Text() += (int)*bAnzahl->zText() );
		else
			opd->addWert( "Farben", Text() += (int)*bAnzahl->zText() );
		if( (int)*tempo->zText() < 100 )
			tempo->setText( "100" );
		if( opd->wertExistiert( "Geschwindigkeit" ) )
			opd->setWert( "Geschwindigkeit", Text() += (int)*tempo->zText() );
		else
			opd->addWert( "Geschwindigkeit", Text() += (int)*tempo->zText() );
		if( opd->wertExistiert( "Fortsetzen" ) )
			opd->setWert( "Fortsetzen", Text() += (int)fortsetzen->hatStyle( KontrollKnopf::Style::Selected ) );
		else
			opd->addWert( "Fortsetzen", Text() += (int)fortsetzen->hatStyle( KontrollKnopf::Style::Selected ) );
		opd->speichern();
		opd->release();
		beendet = 1;
	}
}

void Men�Optionen::doTastaturEreignis( TastaturEreignis &te )
{
	breite->doTastaturEreignis( te );
	h�he->doTastaturEreignis( te );
	bAnzahl->doTastaturEreignis( te );
	tempo->doTastaturEreignis( te );
}

bool Men�Optionen::tick( double tickVal )
{
	bool ret = breite->tick( tickVal );
	ret |= h�he->tick( tickVal );
	ret |= bAnzahl->tick( tickVal );
	ret |= tempo->tick( tickVal );
	ret |= fortsetzen->tick( tickVal );
	ret |= abbrechen->tick( tickVal );
	ret |= ok->tick( tickVal );
	return ret;
}

void Men�Optionen::render( Bild &zRObj )
{
	breiteT->render( zRObj );
	breite->render( zRObj );
	h�heT->render( zRObj );
	h�he->render( zRObj );
	bAnzahlT->render( zRObj );
	bAnzahl->render( zRObj );
	tempoT->render( zRObj );
	tempo->render( zRObj );
	fortsetzen->render( zRObj );
	abbrechen->render( zRObj );
	ok->render( zRObj );
}

// constant
bool Men�Optionen::istBeendet() const
{
	return beendet;
}

// Reference Counting
Men�Optionen *Men�Optionen::getThis()
{
	ref++;
	return this;
}

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


// Inhalt der Men� Klasse aus Men�.h
// Konstruktor
Men�::Men�( Schrift *zSchrift, Bildschirm *zScreen, MinigameKlientV *klient )
{
	spielen = initKnopf( 350, 180, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Spielen" );
	spielenF = new Men�Spiel( zSchrift, zScreen, klient->getThis() );
	optionen = initKnopf( 350, 220, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Optionen" );
	optionenF = new Men�Optionen( zSchrift, zScreen );
	statistik = initKnopf( 350, 260, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Statistik" );
	statistikF = new Men�Statistik( zSchrift, zScreen, klient );
	beenden = initKnopf( 350, 300, 100, 20, zSchrift, Knopf::Style::Sichtbar, "Beenden" );
	ram = new LRahmen();
	ram->setFarbe( 0xFFFFFFFF );
	beendet = 0;
	status = 0;
	LTDBDatei *bgd = new LTDBDatei();
	bgd->setDatei( new Text( "data/Minigames/Bl�cke/bilder/hintergrund.ltdb" ) );
	bgd->leseDaten( 0 );
	hintergrund = bgd->laden( 0, new Text( "bg.jpg" ) );
	bgd->release();
	ref = 1;
}

// Destruktor
Men�::~Men�()
{
	spielen->release();
	spielenF->release();
	optionen->release();
	optionenF->release();
	statistik->release();
	statistikF->release();
	beenden->release();
	if( hintergrund )
		hintergrund->release();
	ram->release();
}

// nicht constant
void Men�::reset()
{
	status = 0;
	beendet = 0;
}

void Men�::doMausEreignis( MausEreignis &me )
{
	switch( status )
	{
	case 0:
		if( 1 )
		{
			bool vera = me.verarbeitet;
			spielen->doMausEreignis( me );
			if( !vera && me.verarbeitet && me.id == ME_RLinks )
			{
				spielenF->reset();
				status = 3;
			}
			vera = me.verarbeitet;
			optionen->doMausEreignis( me );
			if( !vera && me.verarbeitet && me.id == ME_RLinks )
			{
				optionenF->reset();
				status = 1;
			}
			vera = me.verarbeitet;
			statistik->doMausEreignis( me );
			if( !vera && me.verarbeitet && me.id == ME_RLinks )
			{
				statistikF->reset();
				status = 2;
			}
			vera = me.verarbeitet;
			beenden->doMausEreignis( me );
			if( !vera && me.verarbeitet && me.id == ME_RLinks )
				beendet = 1;
		}
		break;
	case 1:
		optionenF->doMausEreignis( me );
		break;
	case 2:
		statistikF->doMausEreignis( me );
		break;
	case 3:
		spielenF->doMausEreignis( me );
	}
}

void Men�::doTastaturEreignis( TastaturEreignis &te )
{
	if( status == 1 )
		optionenF->doTastaturEreignis( te );
	if( status == 3 )
		spielenF->doTastaturEreignis( te );
}

bool Men�::tick( double z )
{
	switch( status )
	{
	case 0:
		if( 1 )
		{
			bool ret = spielen->tick( z );
			ret |= statistik->tick( z );
			ret |= optionen->tick( z );
			ret |= beenden->tick( z );
			return ret;
		}
	case 1:
		if( optionenF->istBeendet() )
		{
			status = 0;
			return 1;
		}
		return optionenF->tick( z );
	case 2:
		if( statistikF->istBeendet() )
		{
			status = 0;
			return 1;
		}
		return statistikF->tick( z );
	case 3:
		if( spielenF->istBeendet() )
		{
			status = 0;
			return 1;
		}
		return spielenF->tick( z );
	}
	return 0;
}

void Men�::render( Bild &zRObj )
{
	if( status != 3 && ( status != 2 || !statistikF->istWiederhohlung() ) )
		zRObj.drawBild( 0, 0, hintergrund->getBreite(), hintergrund->getHeight(), *hintergrund );
	switch( status )
	{
	case 0:
		ram->setPosition( 300, 170 );
		ram->setSize( 200, 160 );
		zRObj.alphaRegion( ram->getX(), ram->getY(), ram->getBreite(), ram->getHeight(), 0xD0000000 );
		ram->render( zRObj );
		spielen->render( zRObj );
		statistik->render( zRObj );
		optionen->render( zRObj );
		beenden->render( zRObj );
		break;
	case 1:
		ram->setPosition( 300, 130 );
		ram->setSize( 200, 240 );
		zRObj.alphaRegion( ram->getX(), ram->getY(), ram->getBreite(), ram->getHeight(), 0xD0000000 );
		ram->render( zRObj );
		optionenF->render( zRObj );
		break;
	case 2:
        if( !statistikF->istWiederhohlung() )
            zRObj.alphaRegion( 0, 0, hintergrund->getBreite(), hintergrund->getHeight(), 0xD0000000 );
		statistikF->render( zRObj );
		break;
	case 3:
		spielenF->render( zRObj );
	}
}

// constant
bool Men�::istBeendet() const
{
	return beendet;
}

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

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