#include "ImSpiel.h"
#include <Fenster.h>
#include <Schrift.h>
#include "..\..\Leser\KartenLeser.h"
#include "..\..\Global\Variablen.h"

typedef SpielV* ( *DllStart )( void );

// Inhalt der ImSpielObj Klasse aus ImSpiel.h
// Konstruktor
ImSpiel::ImSpiel( Schrift *zSchrift )
	: Thread()
{
	sichtbar = 0;
	ladenFenster = 0;
	spielFenster = 0;
	schrift = zSchrift->getThis();
	ladenStatus = 0;
	karteId = 0;
	mainDll = 0;
	dllName = 0;
	rend = 0;
	ref = 1;
}

// Destruktor
ImSpiel::~ImSpiel()
{
	if( sichtbar )
		setSichtbar( 0 );
	schrift->release();
}

// nicht constant
void ImSpiel::setSichtbar( bool sichtbar )
{
	if( sichtbar && !this->sichtbar )
	{
		ladenFenster = new SpielLaden( schrift );
		spielFenster = 0;
		ladenStatus = 0;
		karteId = 0;
		mainDll = 0;
		dllName = new Text( "" );
		this->sichtbar = 1;
	}
	else if( !sichtbar && this->sichtbar )
	{
		if( ladenFenster )
			ladenFenster->release();
		if( spielFenster )
			spielFenster->release();
		if( mainDll )
			dllDateien->releaseDLL( *dllName );
		dllName->release();
		this->sichtbar = 0;
	}
}
void ImSpiel::beginnLaden( int karteId, SpielerTeamStruktur *sts )
{
	if( !sichtbar )
		return;
	ladenFenster->setSpielerTeamStruktur( sts );
	ladenFenster->setKarte( karteId );
	ladenFenster->setSichtbar( 1 );
	this->karteId = karteId;
	spielKlient->bereitZumLaden();
	rend = 1;
	start();
}

void ImSpiel::lBAddSpieler( int accountId, int spielerNummer )
{
	if( !sichtbar )
		return;
	ladenFenster->addSpieler( accountId, spielerNummer );
	rend = 1;
}

void ImSpiel::lBSetSpielerProzent( int accountId, int prozent )
{
	if( !sichtbar )
		return;
	ladenFenster->setSpielerFortschritt( accountId, prozent );
	rend = 1;
}

void ImSpiel::lBSetSpielerPing( int accountId, int ping )
{
	if( !sichtbar )
		return;
	ladenFenster->setSpielerPing( accountId, ping );
	rend = 1;
}

void ImSpiel::spielNachricht( int län, char *bytes )
{
	if( !sichtbar )
		return;
	if( ladenStatus > 1 )
		spielFenster->nachricht( län, bytes );
}

void ImSpiel::endLaden()
{
	if( !sichtbar )
		return;
	ladenFenster->setSichtbar( 0 );
}

void ImSpiel::thread()
{
	KartenLeser *reader = new KartenLeser();
	reader->setKarteId( karteId );
	Text *pfad = reader->getSpielPfad();
	pfad->anhängen( "bin/" );
	pfad->anhängen( reader->getSpielName() );
	pfad->anhängen( ".dll" );
	dllName->setText( "Spiele/" );
	dllName->anhängen( reader->getSpielName() );
	reader->release();
	dllName->anhängen( ".dll" );
	mainDll = dllDateien->ladeDLL( *dllName, *pfad );
	if( !mainDll )
	{
		Text *nachricht = new Text( "Die Spiel DLL " );
		nachricht->anhängen( pfad->getText() );
		nachricht->anhängen( " konnte nicht geladen werden.\n" );
		nachricht->anhängen( "Wenn sie nicht existiert dann installiere das Spiel neu." );
		WMessageBox( 0, new Text( "Unerwarteter Fehler" ), nachricht, MB_ICONERROR );
		//------------------------------
		exit( 0 );
	}
	pfad->release();
	DllStart getSpielKlasse = (DllStart)GetProcAddress( mainDll, "getSpielKlasse" );
	if( !getSpielKlasse )
	{
		Text *nachricht = new Text( "Die Spiel DLL " );
		nachricht->anhängen( pfad->getText() );
		nachricht->anhängen( " konnte nicht geladen werden.\n" );
		nachricht->anhängen( "Die Einstiegsfunktion getSpielKlasse() wurde nicht gefunden." );
		WMessageBox( 0, new Text( "Unerwarteter Fehler" ), nachricht, MB_ICONERROR );
		//------------------------------
		exit( 0 );
	}
    int port = 0;
    Text ip;
    infoKlient->getKartenServer( karteId, &port, &ip );
    if( kartenKlient->verbinde( port, ip ) )
        kartenKlient->downloadKarte( karteId );
	spielFenster = getSpielKlasse();
	ladenStatus = 1;
	spielFenster->setKarteId( karteId );
	spielFenster->setKlients( infoKlient->getThis(), spielKlient->getThis() );
	spielFenster->setBildschirm( hauptScreen->getThis() );
	spielFenster->setSchrift( schrift->getThis() );
	spielFenster->ladeDaten();
	ladenStatus = 2;
	run = 0;
}

bool ImSpiel::tick( double tickVal )
{
	if( !sichtbar )
		return 0;
	if( ladenStatus < 3 ) // Vor dem Spiel
		rend |= ladenFenster->tick( tickVal );
	if( ladenStatus == 2 ) // Im spiel
	{
		rend |= spielFenster->tick( tickVal );
		if( spielFenster->läuft() == 1 )
		{
			ladenStatus = 3;
			rend = 1;
		}
	}
	if( ladenStatus == 3 ) // Ende des Spiels
	{
		rend |= spielFenster->tick( tickVal );
		if( !spielFenster->läuft() )
		{
			ladenStatus = 4;
			aktion = 6; // Spiel Statistik laden (Render => new AktionsThread( 20, 0, 0, 0, 0, 0 ))
			rend = 1;
		}
	}
	bool ret = rend;
	rend = 0;
	return ret;
}

void ImSpiel::doMausEreignis( MausEreignis &me )
{
	if( !sichtbar )
		return;
	if( ladenStatus > 1 )
		spielFenster->doMausEreignis( me );
}

void ImSpiel::doTastaturEreignis( TastaturEreignis &te )
{
	if( !sichtbar )
		return;
	if( ladenStatus > 1 )
		spielFenster->doTastaturEreignis( te );
}

void ImSpiel::render( Bild &zRObj )
{
	if( !sichtbar )
		return;
	if( ladenStatus < 3 && ( !spielFenster || spielFenster->läuft() == 3 ) )
		ladenFenster->render( zRObj );
	if( ladenStatus == 3 || ladenStatus == 2 )
		spielFenster->render( zRObj );
}

// constant
int ImSpiel::getKarteId() const
{
	return karteId;
}

bool ImSpiel::istSichtbar() const
{
	return sichtbar;
}

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

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