#include "AccountSpielPartner.h"
#include "../../../Global/Initialisierung.h"
#include "../../../Global/Variablen.h"
#include <Rahmen.h>
#include <DateiSystem.h>
#include <ToolTip.h>
#include <Punkt.h>

#define HATSTYLE( b )  ( daten->style | (b) ) == daten->style

// Inhalt der AccountSPListeEintrag Klasse aus AccountSpielPartner.h
// Konstruktor
AccountSPListeEintrag::AccountSPListeEintrag( AccountSPListeEintragDaten *daten, Schrift *zSchrift )
	: daten( daten ),
  ram( new LRahmen() ),
  members( new RCArray< AccountSPListeEintrag >() ),
  name( initTextFeld( 5, 0, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Name" ) ),
  anzahl( initTextFeld( 110, 0, 100, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center, "Spiele: " ) ),
  prozent( initFBalken( 220, 0, 400, 20, zSchrift, FBalken::Style::normal ) ),
  details( initKnopf( 580, 0, 20, 20, 0, 0, "" ) ),
  ausklappen( bilder->get( "account.ltdb/ausklappen.png" ) ),
  einklappen( bilder->get( "account.ltdb/einklappen.png" ) ),
  sortSpalte( new Text( "Name" ) ),
  sortAbsteigend( 0 ),
  tickVal( 0 ),
  rend( 0 ),
  ref( 1 )
{
	if( !einklappen )
	{
		LTDBDatei *datei = new LTDBDatei();
		datei->setDatei( new Text( "data/client/bilder/account.ltdb" ) );
		datei->leseDaten( 0 );
		einklappen = datei->laden( 0, new Text( "einklappen.png" ) );
		datei->release();
		bilder->add( "account.ltdb/einklappen.png", einklappen->getThis() );
	}
	if( !ausklappen )
	{
		LTDBDatei *datei = new LTDBDatei();
		datei->setDatei( new Text( "data/client/bilder/account.ltdb" ) );
		datei->leseDaten( 0 );
		ausklappen = datei->laden( 0, new Text( "ausklappen.png" ) );
		datei->release();
		bilder->add( "account.ltdb/ausklappen.png", ausklappen->getThis() );
	}
	details->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
	details->setHintergrundBildZ( ausklappen->getThis() );
	initToolTip( details, "Details anzeigen.", zSchrift->getThis(), hauptScreen );
	ram->setFarbe( 0xFFFFFFFF );
	ram->setRamenBreite( 1 );
	ram->setGröße( 0, 20 );
	if( daten->name )
		name->setText( daten->name->getText() );
	anzahl->zText()->anhängen( daten->anzahl );
	zSchrift->lock();
	zSchrift->setSchriftGröße( 12 );
	name->setGröße( zSchrift->getTextBreite( name->zText() ) + 5, name->getHöhe() );
	anzahl->setPosition( ( name->getX() + name->getBreite() + 10 ) < 100 ? 100 : ( name->getX() + name->getBreite() + 10 ), anzahl->getY() );
	anzahl->setGröße( zSchrift->getTextBreite( anzahl->zText() ) + 5, anzahl->getHöhe() );
	zSchrift->unlock();
	prozent->setPosition( ( anzahl->getX() + anzahl->getBreite() + 10 ) < 200 ? 200 : ( anzahl->getX() + anzahl->getBreite() + 10 ), prozent->getY() );
	prozent->setAktionAnzahl( 100 );
	prozent->aktionPlus( daten->prozent );
}

// Destruktor
AccountSPListeEintrag::~AccountSPListeEintrag()
{
	ram->release();
	members->release();
	name->release();
	anzahl->release();
	prozent->release();
	details->release();
	ausklappen->release();
	einklappen->release();
	sortSpalte->release();
	daten->name->release();
	delete daten;
}

// privat
int AccountSPListeEintrag::getReihenfolge( int *arr )
{
	int anz = members->getEintragAnzahl();
	if( !anz || !HATSTYLE( ASPLEDStyle::Ausklappbar ) )
		return 0;
	int ret = 0;
	bool *fertig = new bool[ anz ];
	ZeroMemory( fertig, anz );
	for( int i = 0; i < anz; i++ )
	{
		int index = -1;
		int minMax = 0;
		Text minMaxT;
		for( int j = 0; j < anz; j++ )
		{
			AccountSPListeEintrag *tmp = members->z( j );
			if( sortSpalte->istGleich( "Name" ) && !fertig[ j ] && ( index < 0 ||
				( sortAbsteigend && *tmp->zDaten()->name > minMaxT ) || ( !sortAbsteigend && *tmp->zDaten()->name < minMaxT ) ) )
			{
				minMaxT = tmp->zDaten()->name->getText();
				index = j;
			}
			else if( sortSpalte->istGleich( "Spiele" ) && !fertig[ j ] && ( index < 0 ||
				( sortAbsteigend && tmp->zDaten()->anzahl > minMax ) || ( !sortAbsteigend && tmp->zDaten()->anzahl < minMax ) ) )
			{
				minMax = tmp->zDaten()->anzahl;
				index = j;
			}
			else if( sortSpalte->istGleich( "Prozent" ) && !fertig[ j ] && ( index < 0 ||
				( sortAbsteigend && tmp->zDaten()->prozent > minMax ) || ( !sortAbsteigend && tmp->zDaten()->prozent < minMax ) ) )
			{
				minMax = tmp->zDaten()->prozent;
				index = j;
			}
		}
		if( index < 0 )
			break;
		fertig[ index ] = 1;
		arr[ ret ] = index;
		ret++;
	}
	delete[] fertig;
	return ret;
}

// nicht constant
void AccountSPListeEintrag::addMember( AccountSPListeEintrag *e )
{
	members->add( e );
	rend = 1;
}

void AccountSPListeEintrag::setSortSpalte( char *sp )
{
	sortSpalte->setText( sp );
	if( HATSTYLE( ASPLEDStyle::Ausklappbar ) )
	{
		int anz = members->getEintragAnzahl();
		for( int i = 0; i < anz; i++ )
			members->z( i )->setSortSpalte( sp );
	}
	rend = 1;
}

void AccountSPListeEintrag::setSortRichtung( bool absteigend )
{
	sortAbsteigend = absteigend;
	if( HATSTYLE( ASPLEDStyle::Ausklappbar ) )
	{
		int anz = members->getEintragAnzahl();
		for( int i = 0; i < anz; i++ )
			members->z( i )->setSortRichtung( absteigend );
	}
	rend = 1;
}

bool AccountSPListeEintrag::tick( double tickVal )
{
	rend |= details->tick( tickVal );
	int anz = members->getEintragAnzahl();
	for( int i = 0; i < anz; i++ )
		rend |= members->z( i )->tick( tickVal );
	this->tickVal += tickVal * 150;
	int val = ( int )this->tickVal;
	this->tickVal -= val;
	if( val )
	{
		if( details->zHintergrundBild() == ausklappen && ram->getHöhe() != 20 )
		{
			if( ram->getHöhe() - val < 20 )
				ram->setGröße( ram->getBreite(), 20 );
			else
				ram->setGröße( ram->getBreite(), ram->getHöhe() - val );
			rend = 1;
		}
		if( details->zHintergrundBild() == einklappen )
		{
			int maxHö = 20;
			for( int i = 0; i < anz; i++ )
				maxHö += 5 + members->z( i )->getHöhe();
			if( maxHö > 20 )
				maxHö += 5;
			if( ram->getHöhe() > maxHö )
			{
				if( ram->getHöhe() - val < maxHö )
					ram->setGröße( ram->getBreite(), maxHö );
				else
					ram->setGröße( ram->getBreite(), ram->getHöhe() - val );
				rend = 1;
			}
			if( ram->getHöhe() < maxHö )
			{
				if( ram->getHöhe() + val > maxHö )
					ram->setGröße( ram->getBreite(), maxHö );
				else
					ram->setGröße( ram->getBreite(), ram->getHöhe() + val );
				rend = 1;
			}
		}
	}
	bool ret = rend;
	rend = 0;
	return ret;
}

void AccountSPListeEintrag::doMausEreignis( MausEreignis &me )
{
	int mx = me.mx;
	int my = me.my;
	bool vera = 0;
	if( me.mx < 0 || me.my < 0 || me.mx > ram->getBreite() || me.my > ram->getHöhe() )
	{
		vera = 1;
		me.verarbeitet = 1;
	}
	if( HATSTYLE( ASPLEDStyle::Ausklappbar ) )
	{
		bool ok = me.verarbeitet;
		details->doMausEreignis( me );
		if( !ok && me.verarbeitet && me.id == ME_RLinks )
		{
			if( details->zHintergrundBild() == ausklappen )
			{
				details->setHintergrundBildZ( einklappen->getThis() );
				details->zToolTip()->setText( "Karten verbergen." );
			}
			else
			{
				details->setHintergrundBildZ( ausklappen->getThis() );
				details->zToolTip()->setText( "Karten anzeigen." );
			}
		}
	}
	if( ram->getHöhe() > 20 )
	{
		int anz = members->getEintragAnzahl();
		int *rf = new int[ anz ];
		int rfAnz = getReihenfolge( rf );
		me.my -= 25;
		for( int i = 0; i < rfAnz; i++ )
		{
			members->z( rf[ i ] )->doMausEreignis( me );
			me.my -= members->z( rf[ i ] )->getHöhe() + 5;
		}
		delete[] rf;
	}
	me.mx = mx;
	me.my = my;
	if( vera )
		me.verarbeitet = 0;
}

void AccountSPListeEintrag::render( int xOff, int yOff, int breite, Bild &zRObj )
{
	ram->setGröße( breite, ram->getHöhe() );
	details->setPosition( ram->getBreite() - 20, details->getY() );
	if( !zRObj.setDrawOptions( xOff, yOff, breite, ram->getHöhe() ) )
		return;
	name->render( zRObj );
	anzahl->render( zRObj );
	prozent->render( zRObj );
	if( HATSTYLE( ASPLEDStyle::Ausklappbar ) )
		details->render( zRObj );
	ram->render( zRObj );
	if( ram->getHöhe() > 20 )
	{
		zRObj.drawLinieH( 0, 20, ram->getBreite(), ram->getFarbe() );
		int anz = members->getEintragAnzahl();
		int *rf = new int[ anz ];
		int rfAnz = getReihenfolge( rf );
		yOff = 0;
		for( int i = 0; i < rfAnz; i++ )
		{
			members->z( rf[ i ] )->render( 5, yOff + 25, breite - 10, zRObj );
			yOff += 5 + members->z( rf[ i ] )->getHöhe();
		}
		delete[] rf;
	}
	zRObj.releaseDrawOptions();
}

// constant
int AccountSPListeEintrag::getHöhe() const
{
	return ram->getHöhe();
}

AccountSPListeEintragDaten *AccountSPListeEintrag::zDaten() const
{
	return daten;
}

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

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


// Inhalt der AccountSPListe Klasse aus AccountSpielPartner.h
// Konstruktor
AccountSPListe::AccountSPListe( Schrift *zSchrift )
	: Zeichnung(),
  schrift( zSchrift->getThis() ),
  ram( new LRahmen() ),
  scroll( new VScrollBar() ),
  skp( new RCArray< AccountSPListeEintrag >() ),
  spk( new RCArray< AccountSPListeEintrag >() ),
  psk( new RCArray< AccountSPListeEintrag >() ),
  gruppierung( new Text( "Spieler/Spiel/Karte" ) ),
  sortSpalte( new Text( "Name" ) ),
  sortAbsteigend( 0 ),
  rend( 0 ),
  ref( 1 )
{
	pos = Punkt( 10, 40 );
	ram->setGröße( 760, 380 );
	ram->setFarbe( 0xFFFFFFFF );
	ram->setRamenBreite( 1 );
}

// Destruktor
AccountSPListe::~AccountSPListe()
{
	schrift->release();
	ram->release();
	scroll->release();
	skp->release();
	spk->release();
	psk->release();
	gruppierung->release();
	sortSpalte->release();
}

// privat
int AccountSPListe::getReihenfolge( int *arr )
{
	RCArray< AccountSPListeEintrag > *members = 0;
	if( gruppierung->istGleich( "Spiel/Karte/Spieler" ) )
		members = skp;
	if( gruppierung->istGleich( "Spiel/Spieler/Karte" ) )
		members = spk;
	if( gruppierung->istGleich( "Spieler/Spiel/Karte" ) )
		members = psk;
	int anz = members->getEintragAnzahl();
	if( !anz )
		return 0;
	int ret = 0;
	bool *fertig = new bool[ anz ];
	ZeroMemory( fertig, anz );
	for( int i = 0; i < anz; i++ )
	{
		int index = -1;
		int minMax = 0;
		Text minMaxT;
		for( int j = 0; j < anz; j++ )
		{
			AccountSPListeEintrag *tmp = members->z( j );
			if( sortSpalte->istGleich( "Name" ) && !fertig[ j ] && ( index < 0 ||
				( sortAbsteigend && *tmp->zDaten()->name > minMaxT ) || ( !sortAbsteigend && *tmp->zDaten()->name < minMaxT ) ) )
			{
				minMaxT = tmp->zDaten()->name->getText();
				index = j;
			}
			else if( sortSpalte->istGleich( "Spiele" ) && !fertig[ j ] && ( index < 0 ||
				( sortAbsteigend && tmp->zDaten()->anzahl > minMax ) || ( !sortAbsteigend && tmp->zDaten()->anzahl < minMax ) ) )
			{
				minMax = tmp->zDaten()->anzahl;
				index = j;
			}
			else if( sortSpalte->istGleich( "Prozent" ) && !fertig[ j ] && ( index < 0 ||
				( sortAbsteigend && tmp->zDaten()->prozent > minMax ) || ( !sortAbsteigend && tmp->zDaten()->prozent < minMax ) ) )
			{
				minMax = tmp->zDaten()->prozent;
				index = j;
			}
		}
		if( index < 0 )
			break;
		fertig[ index ] = 1;
		arr[ ret ] = index;
		ret++;
	}
	delete[] fertig;
	return ret;
}

// nicht constant
void AccountSPListe::reset()
{
	lockZeichnung();
	skp->leeren();
	spk->leeren();
	psk->leeren();
	unlockZeichnung();
}

void AccountSPListe::ladeDaten( int accId )
{
	Array< int > *spieler = new Array< int >();
	Array< int > *karten = new Array< int >();
	Array< int > *anzahl = new Array< int >();
	if( infoKlient->getSpielPartnerListe( accId, spieler, karten, anzahl ) )
	{
		int anz = spieler->getEintragAnzahl();
		int spielerAnzahl = 0;
		int spielArtAnzahl = 0;
		int anzahlGesammt = 0;
		Array< int > *spielerUnique = new Array< int >();
		Array< int > *spielArt = new Array< int >();
		for( int i = 0; i < anz; i++ )
		{ // Spiel Art Ids ermitteln
			anzahlGesammt += anzahl->get( i );
			if( spieler->hat( i ) && spielerUnique->getWertIndex( spieler->get( i ) ) < 0 )
			{
				spielerUnique->set( spieler->get( i ), spielerAnzahl );
				spielerAnzahl++;
			}
			if( !spielArt->hat( i ) )
			{
				spielArtAnzahl++;
				int id = infoKlient->getSpielId( karten->get( i ) );
				for( int j = i; j < anz; j++ )
				{
					if( karten->get( j ) == karten->get( i ) )
						spielArt->set( id, j );
				}
			}
		}
		spielerUnique->release();
		// Spiel/Karte/Spieler Tabelle initialisieren
		Array< int > *spielArtVera = new Array< int >();
		for( int i = 0; i < spielArtAnzahl; i++ )
		{ // Spiel Arten Einträge
			int id = 0;
			for( int j = 0; j < anz; j++ )
			{
				if( spielArtVera->getWertIndex( spielArt->get( j ) ) < 0 )
				{
					id = spielArt->get( j );
					spielArtVera->add( id );
					break;
				}
			}
			if( !id )
				break;
			AccountSPListeEintragDaten *tmp = new AccountSPListeEintragDaten();
			tmp->id = id;
			tmp->name = infoKlient->getSpielName( tmp->id );
			tmp->style = ASPLEDStyle::SpielArt | ASPLEDStyle::Ausklappbar;
			tmp->anzahl = 0;
			for( int j = 0; j < anz; j++ )
			{
				if( spielArt->get( j ) == tmp->id )
					tmp->anzahl += anzahl->get( j );
			}
			tmp->prozent = tmp->anzahl * 100 / anzahlGesammt;
			AccountSPListeEintrag *spielE = new AccountSPListeEintrag( tmp, schrift );
			skp->add( spielE );
			Array< int > *kartenVera = new Array< int >();
			for( int j = 0; j < anz; j++ )
			{ // Karten Einträge
				int id = 0;
				for( int k = 0; k < anz; k++ )
				{
					if( spielArt->get( k ) == tmp->id )
					{
						if( kartenVera->getWertIndex( karten->get( k ) ) < 0 )
						{
							id = karten->get( k );
							kartenVera->add( id );
							break;
						}
					}
				}
				if( !id )
					break;
				AccountSPListeEintragDaten *tmpk = new AccountSPListeEintragDaten();
				tmpk->id = id;
				tmpk->name = infoKlient->getKarteName( tmpk->id );
				tmpk->style = ASPLEDStyle::Ausklappbar | ASPLEDStyle::Karte;
				tmpk->anzahl = 0;
				for( int k = 0; k < anz; k++ )
				{
					if( karten->get( k ) == tmpk->id )
						tmpk->anzahl += anzahl->get( k );
				}
				tmpk->prozent = tmpk->anzahl * 100 / tmp->anzahl;
				AccountSPListeEintrag *karteE = new AccountSPListeEintrag( tmpk, schrift );
				spielE->addMember( karteE );
				Array< int > *spielerVera = new Array< int >();
				for( int k = 0; k < anz; k++ )
				{ // Spieler Einträge
					int id = 0;
					int gAnz = 0;
					for( int l = 0; l < anz; l++ )
					{
						if( karten->get( l ) == tmpk->id )
						{
							if( spielerVera->getWertIndex( spieler->get( l ) ) < 0 )
							{
								id = spieler->get( l );
								spielerVera->add( id );
								gAnz = anzahl->get( l );
								break;
							}
						}
					}
					if( !id )
						break;
					AccountSPListeEintragDaten *tmps = new AccountSPListeEintragDaten();
					tmps->id = id;
					tmps->name = infoKlient->getSpielerName( tmps->id );
					tmps->style = ASPLEDStyle::Spieler;
					tmps->anzahl = gAnz;
					tmps->prozent = tmps->anzahl * 100 / tmpk->anzahl;
					karteE->addMember( new AccountSPListeEintrag( tmps, schrift ) );
				}
				spielerVera->release();
			}
			kartenVera->release();
		}
		spielArtVera->leeren();
		// Spiel/Spieler/Karte Tabelle initialisieren
		for( int i = 0; i < spielArtAnzahl; i++ )
		{ // Spiel Arten Einträge
			int id = 0;
			for( int j = 0; j < anz; j++ )
			{
				if( spielArtVera->getWertIndex( spielArt->get( j ) ) < 0 )
				{
					id = spielArt->get( j );
					spielArtVera->add( id );
					break;
				}
			}
			if( !id )
				break;
			AccountSPListeEintragDaten *tmp = new AccountSPListeEintragDaten();
			tmp->id = id;
			tmp->name = infoKlient->getSpielName( tmp->id );
			tmp->style = ASPLEDStyle::SpielArt | ASPLEDStyle::Ausklappbar;
			tmp->anzahl = 0;
			for( int j = 0; j < anz; j++ )
			{
				if( spielArt->get( j ) == tmp->id )
					tmp->anzahl += anzahl->get( j );
			}
			tmp->prozent = tmp->anzahl * 100 / anzahlGesammt;
			AccountSPListeEintrag *spielE = new AccountSPListeEintrag( tmp, schrift );
			spk->add( spielE );
			Array< int > *spielerVera = new Array< int >();
			for( int j = 0; j < anz; j++ )
			{ // Spieler Einträge
				int id = 0;
				for( int k = 0; k < anz; k++ )
				{
					if( spielArt->get( k ) == tmp->id )
					{
						if( spielerVera->getWertIndex( spieler->get( k ) ) < 0 )
						{
							id = spieler->get( k );
							spielerVera->add( id );
							break;
						}
					}
				}
				if( !id )
					break;
				AccountSPListeEintragDaten *tmps = new AccountSPListeEintragDaten();
				tmps->id = id;
				tmps->name = infoKlient->getSpielerName( tmps->id );
				tmps->style = ASPLEDStyle::Ausklappbar | ASPLEDStyle::Spieler;
				tmps->anzahl = 0;
				for( int k = 0; k < anz; k++ )
				{
					if( spieler->get( k ) == tmps->id && spielArt->get( k ) == tmp->id )
						tmps->anzahl += anzahl->get( k );
				}
				tmps->prozent = tmps->anzahl * 100 / tmp->anzahl;
				AccountSPListeEintrag *spielerE = new AccountSPListeEintrag( tmps, schrift );
				spielE->addMember( spielerE );
				Array< int > *karteVera = new Array< int >();
				for( int k = 0; k < anz; k++ )
				{ // Karten Einträge
					int id = 0;
					int gAnz = 0;
					for( int l = 0; l < anz; l++ )
					{
						if( spieler->get( l ) == tmps->id && spielArt->get( l ) == tmp->id )
						{
							if( karteVera->getWertIndex( karten->get( l ) ) < 0 )
							{
								id = karten->get( l );
								karteVera->add( id );
								gAnz = anzahl->get( l );
								break;
							}
						}
					}
					if( !id )
						break;
					AccountSPListeEintragDaten *tmpk = new AccountSPListeEintragDaten();
					tmpk->id = id;
					tmpk->name = infoKlient->getKarteName( tmpk->id );
					tmpk->style = ASPLEDStyle::Karte;
					tmpk->anzahl = gAnz;
					tmpk->prozent = tmpk->anzahl * 100 / tmps->anzahl;
					spielerE->addMember( new AccountSPListeEintrag( tmpk, schrift ) );
				}
				karteVera->release();
			}
			spielerVera->release();
		}
		spielArtVera->release();
		// Spieler/Spiel/Karte Tabelle initialisieren
		Array< int > *spielerVera = new Array< int >();
		for( int i = 0; i < spielerAnzahl; i++ )
		{ // Spieler Einträge
			int id = 0;
			for( int j = 0; j < anz; j++ )
			{
				if( spielerVera->getWertIndex( spieler->get( j ) ) < 0 )
				{
					id = spieler->get( j );
					spielerVera->add( id );
					break;
				}
			}
			if( !id )
				break;
			AccountSPListeEintragDaten *tmp = new AccountSPListeEintragDaten();
			tmp->id = id;
			tmp->name = infoKlient->getSpielerName( tmp->id );
			tmp->style = ASPLEDStyle::Spieler | ASPLEDStyle::Ausklappbar;
			tmp->anzahl = 0;
			for( int j = 0; j < anz; j++ )
			{
				if( spieler->get( j ) == tmp->id )
					tmp->anzahl += anzahl->get( j );
			}
			tmp->prozent = tmp->anzahl * 100 / anzahlGesammt;
			AccountSPListeEintrag *spielerE = new AccountSPListeEintrag( tmp, schrift );
			psk->add( spielerE );
			Array< int > *spielVera = new Array< int >();
			for( int j = 0; j < anz; j++ )
			{ // Spiel Einträge
				int id = 0;
				for( int k = 0; k < anz; k++ )
				{
					if( spieler->get( k ) == tmp->id )
					{
						if( spielVera->getWertIndex( spielArt->get( k ) ) < 0 )
						{
							id = spielArt->get( k );
							spielVera->add( id );
							break;
						}
					}
				}
				if( !id )
					break;
				AccountSPListeEintragDaten *tmps = new AccountSPListeEintragDaten();
				tmps->id = id;
				tmps->name = infoKlient->getSpielName( tmps->id );
				tmps->style = ASPLEDStyle::Ausklappbar | ASPLEDStyle::SpielArt;
				tmps->anzahl = 0;
				for( int k = 0; k < anz; k++ )
				{
					if( spieler->get( k ) == tmp->id && spielArt->get( k ) == tmps->id )
						tmps->anzahl += anzahl->get( k );
				}
				tmps->prozent = tmps->anzahl * 100 / tmp->anzahl;
				AccountSPListeEintrag *spielE = new AccountSPListeEintrag( tmps, schrift );
				spielerE->addMember( spielE );
				Array< int > *karteVera = new Array< int >();
				for( int k = 0; k < anz; k++ )
				{ // Karte Einträge
					int id = 0;
					int gAnz = 0;
					for( int l = 0; l < anz; l++ )
					{
						if( spieler->get( l ) == tmp->id && spielArt->get( l ) == tmps->id )
						{
							if( karteVera->getWertIndex( karten->get( l ) ) < 0 )
							{
								id = karten->get( l );
								karteVera->add( id );
								gAnz = anzahl->get( l );
								break;
							}
						}
					}
					if( !id )
						break;
					AccountSPListeEintragDaten *tmpk = new AccountSPListeEintragDaten();
					tmpk->id = id;
					tmpk->name = infoKlient->getKarteName( tmpk->id );
					tmpk->style = ASPLEDStyle::Karte;
					tmpk->anzahl = gAnz;
					tmpk->prozent = tmpk->anzahl * 100 / tmps->anzahl;
					spielE->addMember( new AccountSPListeEintrag( tmpk, schrift ) );
				}
				karteVera->release();
			}
			spielVera->release();
		}
		spielerVera->release();
		spielArt->release();
	}
	else
		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Die Spielpartner dieses Spielers konnten nicht ermittelt werden." ), new Text( "Ok" ) );
	spieler->release();
	karten->release();
	anzahl->release();
}

void AccountSPListe::setGruppierung( char *gp )
{
	lockZeichnung();
	gruppierung->setText( gp );
	rend = 1;
	unlockZeichnung();
}

void AccountSPListe::setSortSpalte( char *sp )
{
	lockZeichnung();
	sortSpalte->setText( sp );
	int anz = skp->getEintragAnzahl();
	for( int i = 0; i < anz; i++ )
		skp->z( i )->setSortSpalte( sp );
	anz = spk->getEintragAnzahl();
	for( int i = 0; i < anz; i++ )
		spk->z( i )->setSortSpalte( sp );
	anz = psk->getEintragAnzahl();
	for( int i = 0; i < anz; i++ )
		psk->z( i )->setSortSpalte( sp );
	rend = 1;
	unlockZeichnung();
}

void AccountSPListe::setSortRichtung( bool absteigend )
{
	lockZeichnung();
	sortAbsteigend = absteigend;
	int anz = skp->getEintragAnzahl();
	for( int i = 0; i < anz; i++ )
		skp->z( i )->setSortRichtung( absteigend );
	anz = spk->getEintragAnzahl();
	for( int i = 0; i < anz; i++ )
		spk->z( i )->setSortRichtung( absteigend );
	anz = psk->getEintragAnzahl();
	for( int i = 0; i < anz; i++ )
		psk->z( i )->setSortRichtung( absteigend );
	rend = 1;
	unlockZeichnung();
}

bool AccountSPListe::tick( double tickVal )
{
	lockZeichnung();
	RCArray< AccountSPListeEintrag > *members = 0;
	if( gruppierung->istGleich( "Spiel/Karte/Spieler" ) )
		members = skp;
	if( gruppierung->istGleich( "Spiel/Spieler/Karte" ) )
		members = spk;
	if( gruppierung->istGleich( "Spieler/Spiel/Karte" ) )
		members = psk;
	int anz = members->getEintragAnzahl();
	int *rf = new int[ anz ];
	int rfAnz = getReihenfolge( rf );
	for( int i = 0; i < rfAnz; i++ )
		rend |= members->z( rf[ i ] )->tick( tickVal );
	delete[] rf;
	unlockZeichnung();
	rend |= scroll->getRend();
	bool ret = rend;
	rend = 0;
	return ret;
}

void AccountSPListe::doMausEreignis( MausEreignis &me )
{
	bool vera = 0;
	if( me.mx - pos.x <= 0 || me.mx - pos.x >= ram->getBreite() || me.my - pos.y <= 0 || me.my - pos.y >= ram->getHöhe() )
	{
		vera = 1;
		me.verarbeitet = 1;
	}
	int mx = me.mx, my = me.my;
	me.mx -= pos.x;
	me.my -= pos.y;
	scroll->doMausMessage( ram->getBreite() - 16, 1, 15, ram->getHöhe() - 2, me );
	me.mx -= 10;
	me.my -= 10 - scroll->getScrollData()->anzeigeBeginn;
	lockZeichnung();
	RCArray< AccountSPListeEintrag > *members = 0;
	if( gruppierung->istGleich( "Spiel/Karte/Spieler" ) )
		members = skp;
	if( gruppierung->istGleich( "Spiel/Spieler/Karte" ) )
		members = spk;
	if( gruppierung->istGleich( "Spieler/Spiel/Karte" ) )
		members = psk;
	int anz = members->getEintragAnzahl();
	int *rf = new int[ anz ];
	int rfAnz = getReihenfolge( rf );
	for( int i = 0; i < rfAnz; i++ )
	{
		members->z( rf[ i ] )->doMausEreignis( me );
		me.my -= members->z( rf[ i ] )->getHöhe() + 10;
	}
	delete[] rf;
	unlockZeichnung();
	me.mx = mx, me.my = my;
	if( vera )
		me.verarbeitet = 0;
}

void AccountSPListe::render( Bild &zRObj )
{
	if( !zRObj.setDrawOptions( pos, ram->getGröße() ) )
		return;
	ram->render( zRObj );
	scroll->render( ram->getBreite() - 16, 1, 15, ram->getHöhe() - 2, zRObj );
	if( !zRObj.setDrawOptions( 1, 1, ram->getBreite() - 15, ram->getHöhe() - 2 ) )
	{
		zRObj.releaseDrawOptions();
		return;
	}
	int anzHö = 10;
	lockZeichnung();
	RCArray< AccountSPListeEintrag > *members = 0;
	if( gruppierung->istGleich( "Spiel/Karte/Spieler" ) )
		members = skp;
	if( gruppierung->istGleich( "Spiel/Spieler/Karte" ) )
		members = spk;
	if( gruppierung->istGleich( "Spieler/Spiel/Karte" ) )
		members = psk;
	int anz = members->getEintragAnzahl();
	int *rf = new int[ anz ];
	int rfAnz = getReihenfolge( rf );
	for( int i = 0; i < rfAnz; i++ )
	{
		members->z( rf[ i ] )->render( 10, anzHö - scroll->getScrollData()->anzeigeBeginn, ram->getBreite() - 36, zRObj );
		anzHö += members->z( rf[ i ] )->getHöhe() + 10;
	}
	delete[] rf;
	unlockZeichnung();
	scroll->update( anzHö, ram->getHöhe() - 2 );
	zRObj.releaseDrawOptions();
	zRObj.releaseDrawOptions();
}

// constant

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

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


// Inhalt der AccountSpielPartner Klasse aus AccountSpielPartner.h
// Konstruktor
AccountSpielPartner::AccountSpielPartner( Schrift *zSchrift )
	: Thread(),
  spielPartnerF( initFenster( 810, 40, 780, 450, zSchrift, Fenster::Style::Sichtbar | Fenster::Style::Titel | Fenster::Style::TitelBuffered | Fenster::Style::Rahmen | Fenster::Style::Erlaubt, "Spielpartner von " ) ),
  gruppAusw( initAuswahlBox( 10, 10, 150, 20, zSchrift, ABSTYLE, { "Spieler/Spiel/Karte", "Spiel/Karte/Spieler", "Spiel/Spieler/Karte" } ) ),
  sortSpalte( initAuswahlBox( 170, 10, 150, 20, zSchrift, ABSTYLE, { "Name", "Spiele", "Prozent" } ) ),
  sortRichtung( initAuswahlBox( 330, 10, 150, 20, zSchrift, ABSTYLE, { "Aufwärts", "Abwärts" } ) ),
  liste( new AccountSPListe( zSchrift ) ),
  status( 0 ),
  accId( 0 ),
  animation( 0 ),
  alpha( 255 ),
  tickVal( 0 ),
  rend( 0 ),
  ref( 1 )
{
	initToolTip( gruppAusw, "Wähle Gruppierung aus, nach der die Daten angezeigt werden sollen.", zSchrift->getThis(), hauptScreen );
	initToolTip( sortSpalte, "Wähle aus, nach welcher Spalte die\nTabelle sortiert werden soll.", zSchrift->getThis(), hauptScreen );
	initToolTip( sortRichtung, "Wähle aus, Ob Aufwärts oder Abwärts sortiert werden soll.", zSchrift->getThis(), hauptScreen );
	spielPartnerF->addMember( liste );
	spielPartnerF->addMember( gruppAusw );
	spielPartnerF->addMember( sortSpalte );
	spielPartnerF->addMember( sortRichtung );
	spielPartnerF->setMausEreignis( _ret1ME );
}

// Destruktor
AccountSpielPartner::~AccountSpielPartner()
{
	spielPartnerF->release();
	gruppAusw->release();
	sortSpalte->release();
	sortRichtung->release();
	liste->release();
}

// nicht constant
void AccountSpielPartner::reset()
{
	liste->reset();
}

void AccountSpielPartner::ladeStatistik( int accId )
{
	if( this->accId == accId )
		return;
	this->status = 0;
	if( run )
	{
		warteAufThread( 1000 );
		ende();
	}
	if( ( animation | 0x1 ) == animation )
	{
		animation |= 0x4;
		this->accId = accId;
		this->status = 1;
		return;
	}
	if( this->accId )
		reset();
	this->accId = accId;
	start();
	this->status = 1;
}

void AccountSpielPartner::thread()
{
	Text *name = infoKlient->getSpielerName( accId );
	if( name )
	{
		name->einfügen( 0, "Spielpartner von " );
		spielPartnerF->setTitel( *name );
		name->release();
	}
	liste->ladeDaten( accId );
	animation &= ~0x4;
	status = 2;
	run = 0;
}

void AccountSpielPartner::setSichtbar( bool sichtbar, bool nachRechts )
{
	if( sichtbar )
	{
		if( ( animation | 0x1 ) != animation || ( ( nachRechts && ( animation | 0x2 ) != animation ) || !nachRechts && ( animation | 0x2 ) == animation ) )
		{
			if( nachRechts )
				spielPartnerF->setPosition( -810, 40 );
			else
				spielPartnerF->setPosition( 810, 40 );
		}
		animation |= 0x1;
	}
	else
		animation &= ~0x1;
	if( nachRechts )
		animation |= 0x2;
	else
		animation &= ~0x2;
}

bool AccountSpielPartner::tick( double zeit )
{
	rend |= spielPartnerF->tick( zeit );
	tickVal += zeit;
	int valA = (int)( tickVal * 150 );
	int valB = (int)( tickVal * 500 );
	tickVal -= valA / 150.0;
	if( valA )
	{
		if( ( animation | 0x4 ) == animation && alpha )
		{
			if( alpha - valA <= 0 )
				alpha = 0;
			else
				alpha -= valA;
			rend = 1;
			if( !alpha )
			{
				reset();
				start();
			}
		}
		if( ( animation | 0x4 ) != animation && alpha != 255 )
		{
			if( alpha + valA >= 255 )
				alpha = 255;
			else
				alpha += valA;
			rend = 1;
		}
	}
	if( valB )
	{
		if( ( animation | 0x1 ) == animation )
		{ // Sichtbar
			if( ( animation | 0x2 ) == animation )
			{ // Nach Rechts
				if( spielPartnerF->getX() != 10 )
				{
					if( spielPartnerF->getX() + valB > 10 )
						spielPartnerF->setPosition( 10, spielPartnerF->getY() );
					else
						spielPartnerF->setPosition( spielPartnerF->getX() + valB, spielPartnerF->getY() );
					rend = 1;
				}
			}
			else
			{ // Nach Links
				if( spielPartnerF->getX() != 10 )
				{
					if( spielPartnerF->getX() - valB < 10 )
						spielPartnerF->setPosition( 10, spielPartnerF->getY() );
					else
						spielPartnerF->setPosition( spielPartnerF->getX() - valB, spielPartnerF->getY() );
					rend = 1;
				}
			}
		}
		else
		{ // Unsichtbar
			if( ( animation | 0x2 ) == animation )
			{ // Nach Rechts
				if( spielPartnerF->getX() != 810 )
				{
					if( spielPartnerF->getX() + valB > 810 )
						spielPartnerF->setPosition( 810, spielPartnerF->getY() );
					else
						spielPartnerF->setPosition( spielPartnerF->getX() + valB, spielPartnerF->getY() );
					rend = 1;
				}
			}
			else
			{ // Nach Links
				if( spielPartnerF->getX() != -810 )
				{
					if( spielPartnerF->getX() - valB < -810 )
						spielPartnerF->setPosition( -810, spielPartnerF->getY() );
					else
						spielPartnerF->setPosition( spielPartnerF->getX() - valB, spielPartnerF->getY() );
					rend = 1;
				}
			}
		}
	}
	bool ret = rend;
	rend = 0;
	return ret;
}

void AccountSpielPartner::doMausEreignis( MausEreignis &me )
{
	int gruppAuswS = gruppAusw->getAuswahl();
	int sortSpalteS = sortSpalte->getAuswahl();
	int sortRichtungS = sortRichtung->getAuswahl();
	spielPartnerF->doMausEreignis( me );
	if( gruppAusw->getAuswahl() != gruppAuswS )
	{
		liste->setGruppierung( gruppAusw->zEintrag( gruppAusw->getAuswahl() )->zText()->getText() );
		gruppAusw->einklappen();
	}
	if( sortSpalte->getAuswahl() != sortSpalteS )
	{
		liste->setSortSpalte( sortSpalte->zEintrag( sortSpalte->getAuswahl() )->zText()->getText() );
		sortSpalte->einklappen();
	}
	if( sortRichtung->getAuswahl() != sortRichtungS )
	{
		liste->setSortRichtung( sortRichtung->getAuswahl() != 0 );
		sortRichtung->einklappen();
	}
}

void AccountSpielPartner::render( Bild &zRObj )
{
	zRObj.setAlpha( alpha );
	spielPartnerF->render( zRObj );
	zRObj.releaseAlpha();
}

// constant
int AccountSpielPartner::getStatus() const
{
	return status;
}

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

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