#include "Variablen.h"
#include "Render.h"
#include <Globals.h>
#include <TastaturEreignis.h>
#include "..\Aktionen\AktionsThread.h"

// Inhalt der Render Klasse aus Render.h
// Konstruktor 
Render::Render( Schrift *schrift )
    : Thread()
{
	exit = 0;
	bildschirm = 0;
	ref = 1;
	time = new ZeitMesser();
	tickval = 1.0 / 60;
	fps = new Fps();
	fps->setSchriftZ( schrift );
	fps->setSFarbe( 0xFFFFFFFF );
	deckAlpha = 0;
	inAnimation = 0;
	exit = 0;
}

// Destruktor 
Render::~Render()
{
	if( bildschirm )
		bildschirm = bildschirm->release();
	time = time->release();
	fps = fps->release();
}

// nicht constant 
void Render::setBildschirm( Bildschirm *bildschirm ) // setzt den Bildschirm
{
	this->bildschirm = bildschirm;
}

void Render::thread() // Render Schleife
{
	bool fpsAdd = 0;
	time->messungStart();
	double ausgleich = 0;
	while( !exit )
	{
		if( bildschirm )
		{
			if( Framework::getTastenStand( T_F1 ) )
			{
				if( !fpsAdd )
				{
					bildschirm->addMember( fps );
					fpsAdd = 1;
				}
			}
			else
			{
				if( fpsAdd )
				{
					bildschirm->removeMember( fps );
					fpsAdd = 0;

				}
			}
			if( _render == 1 )
			{
				bildschirm->render();
				bildschirm->tick( tickval );
			}
			else
				Sleep( 100 );
		}
		else
			Sleep( 100 );
		ausgleich += 1.0 / 30 - tickval;
		if( ausgleich > 0 )
			Sleep( (int)( ausgleich * 1000 ) );
		time->messungEnde();
		time->messungStart();
		tickval = time->getSekunden();
		switch( aktion )
		{
		case 1: // Chat Client neu verbinden
			if( 1 )
			{
				bool verbunden = chatClient && chatClient->istVerbunden();
                if( verbunden )
                {
                    chatClient->trenne( 0 );
                    if( cmProcessor )
                        cmProcessor = cmProcessor->release();
                    chatClient->verbinde();
                    cmProcessor = new ChatMessageProcessor();
                }
				aktion = 0;
			}
			break;
		case 2: // Login Oberfl�che erschenen lassen (Programmstart)
			if( !inAnimation )
			{
				deckAlpha = 250;
				bildschirm->setdeckFarbe( deckAlpha << 24 );
				bildschirm->setOnTop( 1 );
				vorLogin->setSichtbar( 1 );
				inAnimation = 1;
				aktion = 0;
			}
			break;
		case 3: // Ausloggen
			new AktionsThread( 4, 0, 0, 0, 0, 0 );
			aktion = 0;
			break;
		case 4: // Client wurde gekickt, zur login Oberfl�che wechseln
			new AktionsThread( 5, 0, 0, 0, 0, 0 );
			aktion = 0;
			break;
		case 5: // Spiel Laden
			new AktionsThread( 19, 0, 0, 0, 0, 0 );
			aktion = 0;
			break;
		case 6: // Nach dem Spiel die Statistik laden
			new AktionsThread( 20, 0, 0, 0, 0, 0 );
			aktion = 0;
			break;
		case 7: // Spiel Aufzeichnung betreten
			new AktionsThread( 21, 0, 0, 0, 0, 0 );
			aktion = 0;
			break;
		case 8: // Spiel Aufzeichnung / Editor verlassen
			new AktionsThread( 22, 0, 0, 0, 0, 0 );
			aktion = 0;
			break;
        case 9: // Editor betreten
            new AktionsThread( 23, 0, 0, 0, 0, 0 );
            aktion = 0;
            break;
		}
		if( inAnimation )
		{
			deckAlpha -= 25;
			bildschirm->setdeckFarbe( deckAlpha << 24 );
			if( deckAlpha == 0 )
			{
				bildschirm->setOnTop( 0 );
				inAnimation = 0;
			}
		}
	}
	time->messungEnde();
}

void Render::beginn() // beginnt rendering
{
	exit = 0;
	start();
}

void Render::beenden() // exit = 1;
{
	exit = 1;
	WaitForSingleObject( threadHandle, 5000 );
}

// constant
Bildschirm *Render::getBildschirm() // gibt den Bildschirm zur�ck
{
	return bildschirm ? bildschirm->getThis() : 0;
}

Bildschirm *Render::zBildschirm()
{
	return bildschirm;
}

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

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