#include "SpielStatistik.h"
#include <Punkt.h>
#include "../../../Global/Variablen.h"

typedef SpielStatistikV* ( *GetStatistikKlasse )( void );

// Inhalt der SpielStatistik Klasse aus SpielStatistik.h
// Konstruktor
SpielStatistik::SpielStatistik( Schrift *zSchrift )
	: pos( 10, 10 ),
	  gr( 780, 480 )
{
	stat = 0;
	spielDll = 0;
	la = (Animation2D*)ladeAnimation->dublizieren();
	la->setPosition( 365, 215 );
	la->setSichtbar( 0 );
	schrift = zSchrift->getThis();
	tickVal = 0;
	sichtbar = 0;
	alpha = 0;
	spielArt = 0;
	rend = 0;
	ref = 1;
}

// Destruktor
SpielStatistik::~SpielStatistik()
{
	if( stat )
		stat->release();
	if( spielDll )
		FreeLibrary( spielDll );
	la->release();
	schrift->release();
}

// nicht constant
void SpielStatistik::setSpielArt( int spielArt )
{
	if( this->spielArt )
		return;
	this->spielArt = spielArt;
	la->setSichtbar( 1 );
	Text *name = infoKlient->getSpielName( spielArt );
	if( !name )
	{
		this->spielArt = 0;
		la->setSichtbar( 0 );
		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Die Spiel Statistik konnte nicht geladen werden." ), new Text( "Ok" ) );
		return;
	}
	Text *pfad = new Text( "data/spiele/" );
	pfad->anhängen( name->getText() );
	pfad->anhängen( "/bin/" );
	pfad->anhängen( name );
	pfad->anhängen( ".dll" );
	spielDll = LoadLibrary( pfad->getText() );
	pfad->release();
	if( !spielDll )
	{
		this->spielArt = 0;
		la->setSichtbar( 0 );
		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Die Spiel Statistik konnte nicht geladen werden." ), new Text( "Ok" ) );
		return;
	}
	GetStatistikKlasse gsk = (GetStatistikKlasse)GetProcAddress( spielDll, "GetStatistikKlasse" );
	if( !gsk )
	{
		FreeLibrary( spielDll );
		this->spielArt = 0;
		la->setSichtbar( 0 );
		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Die Spiel Statistik konnte nicht geladen werden." ), new Text( "Ok" ) );
		return;
	}
	stat = gsk();
	if( !stat )
	{
		FreeLibrary( spielDll );
		this->spielArt = 0;
		la->setSichtbar( 0 );
		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Die Spiel Statistik konnte nicht geladen werden." ), new Text( "Ok" ) );
		return;
	}
	stat->setAccountId( loginKlient->getAccountId() );
	stat->setBilder( bilder );
	stat->setRückrufFunktionen( spielStatistikAddNachrichtF, spielStatistikAddChatF, spielStatistikAddFreundF, spielStatistikAccountAnsehenF, spielStatistikIstFreundF, this );
	stat->setSchrift( schrift->getThis() );
	stat->setBildschirm( hauptScreen->getThis() );
	stat->setKlients( infoKlient->getThis(), spielKlient->getThis() );
	stat->bereit();
}

void SpielStatistik::nachricht( int län, char *bytes )
{
	if( stat )
		stat->nachricht( län, bytes );
}

void SpielStatistik::reset()
{
	spielArt = 0;
	la->setSichtbar( 0 );
	sichtbar = 0;
	alpha = 0;
	stat = stat->release();
	FreeLibrary( spielDll );
	spielDll = 0;
}

void SpielStatistik::doMausEreignis( MausEreignis &me )
{
	me.mx -= pos.x;
	me.my -= pos.y;
	if( stat )
		stat->doMausEreignis( me );
	me.mx += pos.x;
	me.my += pos.y;
}

void SpielStatistik::doTastaturEreignis( TastaturEreignis &te )
{
	if( stat )
		stat->doTastaturEreignis( te );
}

bool SpielStatistik::tick( double zeit )
{
	if( stat && stat->getStatus() == 1 )
	{
		sichtbar = 1;
		la->setSichtbar( 0 );
	}
	else
		sichtbar = 0;
	tickVal += zeit * 250;
	int val = (int)tickVal;
	if( val > 10 )
		val = 10;
	tickVal -= val;
	if( val )
	{
		if( sichtbar && alpha != 255 )
		{
			if( alpha + val > 255 )
				alpha = 255;
			else
				alpha += val;
			rend = 1;
		}
		if( !sichtbar && alpha != 0 )
		{
			if( alpha - val < 0 )
				alpha = 0;
			else
				alpha -= val;
			rend = 1;
		}
	}
	if( stat && sichtbar )
		rend |= stat->tick( zeit );
	rend |= la->tick( zeit );
	bool ret = rend;
	rend = 0;
	return ret;
}

void SpielStatistik::render( Bild &zRObj )
{
	if( !zRObj.setDrawOptions( pos, gr ) )
		return;
	la->render( zRObj );
	zRObj.setAlpha( alpha );
	if( stat )
		stat->render( zRObj );
	zRObj.releaseAlpha();
	zRObj.releaseDrawOptions();
}

void SpielStatistik::addNachrichtF( Text *t, Text *n, Text *rp, Text *rn, char a, void *ü )
{
	nachLogin->zNachrichtenListe()->addNachricht( t, n, rp, rn, a, ü );
}

void SpielStatistik::addChatF( int acc )
{
	nachLogin->zChatLeiste()->addChat( acc, 0 );
}

void SpielStatistik::addFreundF( int acc )
{
	if( !chatKlient->freundesAnfrage( acc ) )
		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Die Freundesanfrage konnte nicht gesendet werden." ), new Text( "Ok" ) );
	else
		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Freundesanfrage" ), new Text( "Es wurde eine Freundesanfrage an den Spieler gesendet." ), new Text( "Ok" ) );
}

void SpielStatistik::accountAnsehenF( int acc )
{
	if( nachLogin->zAccountAnsehenFenster()->setSpielerDetails( acc, 2 ) )
	{
		MausEreignis me = { ME_RLinks, 0, 0, 0, 0, 0 };
		nachLogin->zTitelLeiste()->druckAccountAnsehen( me );
	}
}

bool SpielStatistik::istFreundF( int acc )
{
	return nachLogin->zFreundesListe()->istFreund( acc );
}

void SpielStatistik::verlassen()
{
	if( stat )
	    stat->verlassen();
}

// constant
bool SpielStatistik::istSichtbar()
{
	return sichtbar || alpha || la->istSichtbar();
}

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

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

// Rückruf Funktionen
void spielStatistikAddNachrichtF( void *p, Text *t, Text *n, Text *rp, Text *rn, char a, void *ü )
{
	if( p )
		( (SpielStatistik*)p )->addNachrichtF( t, n, rp, rn, a, ü );
}

void spielStatistikAddChatF( void *p, int acc )
{
	if( p )
		( (SpielStatistik*)p )->addChatF( acc );
}

void spielStatistikAddFreundF( void *p, int acc )
{
	if( p )
		( (SpielStatistik*)p )->addFreundF( acc );
}

void spielStatistikAccountAnsehenF( void *p, int acc )
{
	if( p )
		( (SpielStatistik*)p )->accountAnsehenF( acc );
}

bool spielStatistikIstFreundF( void *p, int acc )
{
	if( p )
		return ( (SpielStatistik*)p )->istFreundF( acc );
	return 0;
}