#include "Bestenliste.h"
#include <Rahmen.h>
#include <Schrift.h>
#include <Punkt.h>
#include <Scroll.h>
#include <TastaturEreignis.h>
#include "../../Initialisierung/Initialisierung.h"
#include "..\Spieler\Spieler.h"

int getStellen( double d );

// Inhalt der BLSpieler Klasse aus Bestenliste.h
// Konstruktor
BLSpieler::BLSpieler( int sNum, Schrift *zS )
{
	this->sNum = sNum;

	rahmen = new LRahmen();
	rahmen->setRamenBreite( 1 );
	rahmen->setSize( 420, 20 );
	name = initTextFeld( 0, 0, 100, 20, zS, TextFeld::Style::Sichtbar | TextFeld::Style::Center, "" );
	punkte = initTextFeld( 100, 0, 50, 20, zS, TextFeld::Style::Sichtbar | TextFeld::Style::Center, "" );
	kills = initTextFeld( 150, 0, 40, 20, zS, TextFeld::Style::Sichtbar | TextFeld::Style::Center, "" );
	tode = initTextFeld( 190, 0, 40, 20, zS, TextFeld::Style::Sichtbar | TextFeld::Style::Center, "" );
	schadenGemacht = initTextFeld( 230, 0, 60, 20, zS, TextFeld::Style::Sichtbar | TextFeld::Style::Center, "" );
	schadenGenommen = initTextFeld( 290, 0, 60, 20, zS, TextFeld::Style::Sichtbar | TextFeld::Style::Center, "" );
	pr�zision = initTextFeld( 350, 0, 70, 20, zS, TextFeld::Style::Sichtbar | TextFeld::Style::Center, "" );

	ref = 1;
}

// Destruktor
BLSpieler::~BLSpieler()
{
	rahmen->release();
	name->release();
	punkte->release();
	kills->release();
	tode->release();
	schadenGemacht->release();
	schadenGenommen->release();
	pr�zision->release();
}

// nicht constant
bool BLSpieler::update( Spieler *zSpieler )
{
	if( sNum != zSpieler->getSpielerNummer() )
		return 0;
	rahmen->setFarbe( zSpieler->getSpielerFarbe() );
	name->setText( zSpieler->zName()->getText() );
	name->setSchriftFarbe( zSpieler->getSpielerFarbe() );
	punkte->setText( Text() += zSpieler->getPunkte() );
	punkte->setSchriftFarbe( zSpieler->getSpielerFarbe() );
	kills->setText( Text() += zSpieler->getKills() );
	kills->setSchriftFarbe( zSpieler->getSpielerFarbe() );
	tode->setText( Text() += zSpieler->getTode() );
	tode->setSchriftFarbe( zSpieler->getSpielerFarbe() );
	schadenGemacht->setText( Text() += zSpieler->getSchadenGemacht() );
	schadenGemacht->setSchriftFarbe( zSpieler->getSpielerFarbe() );
	schadenGenommen->setText( Text() += zSpieler->getSchadenBekommen() );
	schadenGenommen->setSchriftFarbe( zSpieler->getSpielerFarbe() );
	Text txt;
	double d = 100 * ( (double)zSpieler->getTreffer() / zSpieler->getSch�sse() );
	if( !zSpieler->getSch�sse() )
		d = 0;
	txt.setPrecision( getStellen( d ) + 2 );
	txt += d;
	pr�zision->setText( txt );
	pr�zision->setSchriftFarbe( zSpieler->getSpielerFarbe() );
	return 1;
}

void BLSpieler::render( int y, Bild &zRObj )
{
	if( !zRObj.setDrawOptions( 1, y, rahmen->getBreite(), rahmen->getHeight() ) )
		return;
	rahmen->render( zRObj );
	name->render( zRObj );
	punkte->render( zRObj );
	kills->render( zRObj );
	tode->render( zRObj );
	schadenGemacht->render( zRObj );
	schadenGenommen->render( zRObj );
	pr�zision->render( zRObj );
	zRObj.releaseDrawOptions();
}

// constant
int BLSpieler::getSpielerNummer() const
{
	return sNum;
}

int BLSpieler::getPunkte() const
{
	return *punkte->zText();
}

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

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

// Inhalt der BLTeam Klasse aus Bestenliste.h
// Konstruktor
BLTeam::BLTeam( int id, Schrift *s )
{
	teamId = id;
	spielerAnzahl = 0;
	schrift = s;
	spieler = new RCArray< BLSpieler >();

	rahmen = new LRahmen();
	rahmen->setRamenBreite( 1 );
	name = initTextFeld( 0, 0, 100, 20, s, TextFeld::Style::Sichtbar | TextFeld::Style::Center, "" );
	punkte = initTextFeld( 100, 0, 50, 20, s, TextFeld::Style::Sichtbar | TextFeld::Style::Center, "" );

	ref = 1;
}

// Destruktor
BLTeam::~BLTeam()
{
	schrift->release();
	rahmen->release();
	spieler->release();
	name->release();
	punkte->release();
}

// nicht constant
bool BLTeam::addSpieler( Spieler *zSpieler )
{
	bool gefunden = 0;
	for( int i = 0; i < spielerAnzahl; i++ )
	{
		if( spieler->z( i )->getSpielerNummer() == zSpieler->getSpielerNummer() )
		{
			gefunden = 1;
			break;
		}
	}
	if( gefunden )
		return 0;
	BLSpieler *tmp = new BLSpieler( zSpieler->getSpielerNummer(), schrift );
	tmp->update( zSpieler );
	spieler->set( tmp, spielerAnzahl );
	spielerAnzahl++;
	return 1;
}

bool BLTeam::updateSpieler( Spieler *zSpieler )
{
	for( int i = 0; i < spielerAnzahl; i++ )
	{
		if( spieler->z( i )->getSpielerNummer() == zSpieler->getSpielerNummer() )
		{
			spieler->z( i )->update( zSpieler );
			return 1;
		}
	}
	return 0;
}

void BLTeam::update( Team *zTeam )
{
	rahmen->setFarbe( zTeam->farbe );
	name->setSchriftFarbe( zTeam->farbe );
	name->setText( zTeam->name );
	punkte->setSchriftFarbe( zTeam->farbe );
	Text pt;
	pt += zTeam->punkte;
	pt += "/";
	pt += zTeam->maxPunkte;
	punkte->setText( pt );
}

void BLTeam::render( int y, Bild &zRObj )
{
	rahmen->setSize( 422, 21 + 20 * spielerAnzahl );
	if( !zRObj.setDrawOptions( 1, y, rahmen->getBreite(), rahmen->getHeight() ) )
		return;
	rahmen->render( zRObj );
	name->render( zRObj );
	punkte->render( zRObj );
	Array< bool > *gemahlt = new Array< bool >();
	for( int i = 0; i < spielerAnzahl; i++ )
		gemahlt->set( 0, i );
	int min = -1;
	int tmp = -1;
	for( int h = 0; h < spielerAnzahl; h++ )
	{
		min = 0x80000000;
		tmp = 0x80000000;
		for( int i = 0; i < spielerAnzahl; i++ )
		{
			if( !spieler->z( i ) )
				continue;
			if( gemahlt->hat( i ) && gemahlt->get( i ) )
				continue;
			int p = spieler->z( i )->getPunkte();
			if( p > min )
			{
				min = p;
				tmp = i;
			}
		}
		if( tmp != 0x80000000 )
		{
			gemahlt->set( 1, tmp );
			spieler->z( tmp )->render( 20 + 20 * h, zRObj );
		}
		else
			break;
	}
	gemahlt->release();
	zRObj.releaseDrawOptions();
}

// constant
int BLTeam::getSpielerAnzahl() const
{
	return spielerAnzahl;
}

int BLTeam::getPunkte() const
{
	Text *tmp = punkte->zText()->getTeilText( 0, punkte->zText()->positionVon( '/' ) );
	int ret = *tmp;
	tmp->release();
	return ret;
}

int BLTeam::getHeight() const
{
	return 21 + spielerAnzahl * 20;
}

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

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

// Inhalt der Bestenliste Klasse aus Bestenliste.h
// Konstruktor
Bestenliste::Bestenliste( Schrift *s )
{
	rahmen = new LRahmen();
	rahmen->setRamenBreite( 1 );
	rahmen->setFarbe( 0xFFFFFFFF );
	rahmen->setSize( 440, 200 );

	teams = new RCArray< BLTeam >();

	name = new TextFeld();
	name->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Center );
	name->setSchriftZ( s->getThis() );
	name->setSchriftFarbe( 0xFFFFFFFF );
	name->setSchriftSize( 12 );
	name->setText( "Name" );
	name->setSize( 100, 30 );
	name->setPosition( 0, 0 );

	punkte = new TextFeld();
	punkte->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Center );
	punkte->setSchriftZ( s->getThis() );
	punkte->setSchriftFarbe( 0xFFFFFFFF );
	punkte->setSchriftSize( 12 );
	punkte->setText( "Punkte" );
	punkte->setSize( 50, 30 );
	punkte->setPosition( 100, 0 );

	kills = new TextFeld();
	kills->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Center );
	kills->setSchriftZ( s->getThis() );
	kills->setSchriftFarbe( 0xFFFFFFFF );
	kills->setSchriftSize( 12 );
	kills->setText( "Kills" );
	kills->setSize( 40, 30 );
	kills->setPosition( 150, 0 );

	tode = new TextFeld();
	tode->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Center );
	tode->setSchriftZ( s->getThis() );
	tode->setSchriftFarbe( 0xFFFFFFFF );
	tode->setSchriftSize( 12 );
	tode->setText( "Tode" );
	tode->setSize( 40, 30 );
	tode->setPosition( 190, 0 );

	schadenGemacht = new TextFeld();
	schadenGemacht->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Center | TextFeld::Style::Mehrzeilig );
	schadenGemacht->setSchriftZ( s->getThis() );
	schadenGemacht->setSchriftFarbe( 0xFFFFFFFF );
	schadenGemacht->setSchriftSize( 12 );
	schadenGemacht->setText( "Schaden\ngemacht" );
	schadenGemacht->setSize( 60, 30 );
	schadenGemacht->setPosition( 230, 0 );

	schadenGenommen = new TextFeld();
	schadenGenommen->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Center | TextFeld::Style::Mehrzeilig );
	schadenGenommen->setSchriftZ( s->getThis() );
	schadenGenommen->setSchriftFarbe( 0xFFFFFFFF );
	schadenGenommen->setSchriftSize( 12 );
	schadenGenommen->setText( "Schaden\ngenommen" );
	schadenGenommen->setSize( 60, 30 );
	schadenGenommen->setPosition( 290, 0 );

	pr�zision = new TextFeld();
	pr�zision->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Center | TextFeld::Style::Mehrzeilig );
	pr�zision->setSchriftZ( s->getThis() );
	pr�zision->setSchriftFarbe( 0xFFFFFFFF );
	pr�zision->setSchriftSize( 12 );
	pr�zision->setText( "pr�zision" );
	pr�zision->setSize( 70, 30 );
	pr�zision->setPosition( 350, 0 );

	scroll = new VScrollBar();
	scroll->setKlickScroll( 7 );

	sichtbar = 0;
	schrift = s;
	teamAnzahl = 0;
	ref = 1;
}

// Destruktor
Bestenliste::~Bestenliste()
{
	rahmen->release();
	teams->release();
	name->release();
	punkte->release();
	kills->release();
	tode->release();
	schadenGemacht->release();
	schadenGenommen->release();
	pr�zision->release();
	scroll->release();
	schrift->release();
}

// nicht constant
void Bestenliste::setTeamAnzahl( int anz )
{
	teamAnzahl = anz;
}

void Bestenliste::addSpieler( Spieler *zSpieler )
{
	int team = zSpieler->zTeam()->id;
	if( team < 0 )
		return;
	if( !teams->z( team ) )
		teams->set( new BLTeam( team, schrift->getThis() ), team );
	teams->z( team )->addSpieler( zSpieler );
}

void Bestenliste::updateSpieler( Spieler *zSpieler )
{
	if( teams->z( zSpieler->zTeam()->id ) )
		teams->z( zSpieler->zTeam()->id )->updateSpieler( zSpieler );
}

void Bestenliste::updateTeam( Team *zTeam )
{
	if( teams->z( zTeam->id ) )
		teams->z( zTeam->id )->update( zTeam );
}

void Bestenliste::doTastaturEreignis( TastaturEreignis &te )
{
	if( te.id == TE_Press && te.taste == T_Tab )
		sichtbar = !sichtbar;
}

void Bestenliste::doMausEreignis( MausEreignis &me )
{
	if( !sichtbar )
		return;
	scroll->doMausMessage( rahmen->getBreite() - 15, 1, 15, rahmen->getHeight() - 2, me );
}

void Bestenliste::render( Bild &zRObj )
{
	if( !sichtbar )
		return;
	if( !zRObj.setDrawOptions( 0, 0, rahmen->getBreite(), rahmen->getHeight() ) )
		return;
	rahmen->render( zRObj );
	zRObj.alphaRegion( 1, 1, rahmen->getBreite() - 2, rahmen->getHeight() - 2, 0xA0000000 );
	zRObj.addScrollOffset( 0, scroll->getScroll() );
	name->render( zRObj );
	punkte->render( zRObj );
	kills->render( zRObj );
	tode->render( zRObj );
	schadenGemacht->render( zRObj );
	schadenGenommen->render( zRObj );
	pr�zision->render( zRObj );
	int yOff = 30;
	Array< bool > *gemahlt = new Array< bool >();
	for( int i = 1; i <= teamAnzahl; i++ )
		gemahlt->set( 0, i );
	int min = -1;
	int tmp = -1;
	for( int h = 0; h < teamAnzahl; h++ )
	{
		min = -1;
		tmp = -1;
		for( int i = 0; i < teamAnzahl; i++ )
		{
			if( !teams->z( i + 1 ) )
				continue;
			if( gemahlt->hat( i + 1 ) && gemahlt->get( i + 1 ) )
				continue;
			int p = teams->z( i + 1 )->getPunkte();
			if( p > min )
			{
				min = p;
				tmp = i + 1;
			}
		}
		if( tmp >= 0 )
		{
			gemahlt->set( 1, tmp );
			teams->z( tmp )->render( yOff, zRObj );
			yOff += teams->z( tmp )->getHeight();
		}
		else
			break;
	}
	gemahlt->release();
	zRObj.addScrollOffset( 0, -scroll->getScroll() );
	scroll->update( yOff, rahmen->getHeight() - 2 );
	scroll->render( rahmen->getBreite() - 16, 1, 15, rahmen->getHeight() - 2, zRObj );
	zRObj.releaseDrawOptions();
}

// constant
int Bestenliste::getTeamAnzahl() const
{
	return teamAnzahl;
}

bool Bestenliste::teamExistiert( int team ) const
{
	return teams->z( team ) != 0;
}

int Bestenliste::getTeamPunkte( int team ) const
{
	return teams->z( team ) ? teams->z( team )->getPunkte() : 0;
}

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

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