#include "FreundesListe.h"
#include "..\..\Global\Variablen.h"
#include "..\..\Global\Initialisierung.h"
#include <Rahmen.h>
#include <AlphaFeld.h>
#include <MausEreignis.h>
#include <Scroll.h>
#include <Punkt.h>
#include <DateiSystem.h>
#include <Tooltip.h>

// Inhalt der FreundData Klasse aus FreundesListe.h
// Konstruktor
FreundData::FreundData( int accountId, LRahmen *rahmen, AlphaFeld *auswahlBuffer, Schrift *zSchrift )
	: Thread()
{
	Bild *entfernenBild = bilder->get( "chat.ltdb/entfernen.png" );
	if( !entfernenBild )
	{
		LTDBDatei *datei = new LTDBDatei();
		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
		datei->leseDaten( 0 );
		entfernenBild = datei->laden( 0, new Text( "entfernen.png" ) );
		datei->release();
		bilder->add( "chat.ltdb/entfernen.png", entfernenBild->getThis() );
	}
	Bild *ansehenBild = bilder->get( "chat.ltdb/ansehen.png" );
	if( !ansehenBild )
	{
		LTDBDatei *datei = new LTDBDatei();
		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
		datei->leseDaten( 0 );
		ansehenBild = datei->laden( 0, new Text( "ansehen.png" ) );
		datei->release();
		bilder->add( "chat.ltdb/ansehen.png", ansehenBild->getThis() );
	}
	Bild *nachrichtBild = bilder->get( "chat.ltdb/nachricht.png" );
	if( !nachrichtBild )
	{
		LTDBDatei *datei = new LTDBDatei();
		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
		datei->leseDaten( 0 );
		nachrichtBild = datei->laden( 0, new Text( "nachricht.png" ) );
		datei->release();
		bilder->add( "chat.ltdb/nachricht.png", nachrichtBild->getThis() );
	}
	Bild *einladenBild = bilder->get( "chat.ltdb/neuerfreund.png" );
	if( !einladenBild )
	{
		LTDBDatei *datei = new LTDBDatei();
		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
		datei->leseDaten( 0 );
		einladenBild = datei->laden( 0, new Text( "neuerfreund.png" ) );
		datei->release();
		bilder->add( "chat.ltdb/neuerfreund.png", einladenBild->getThis() );
	}
	this->accountId = accountId;
	this->rahmen = rahmen;
	this->auswahlBuffer = auswahlBuffer;
	name = new TextFeld();
	name->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Center );
	name->setSchriftZ( zSchrift->getThis() );
	name->setSchriftFarbe( 0xFFFFFFFF );
	name->setSchriftGröße( 12 );
	name->setText( "" );
	name->setGröße( 200, 20 );
	name->setPosition( 25, 1 );
	status = new TextFeld();
	status->setStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Center );
	status->setSchriftZ( zSchrift->getThis() );
	status->setSchriftFarbe( 0xFFFF0000 );
	status->setSchriftGröße( 12 );
	status->setText( "offline" );
	status->setGröße( 200, 20 );
	status->setPosition( 25, 24 );
	entfernen = initKnopf( 228, 49, 20, 20, 0, 0, "" );
	entfernen->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
	entfernen->setHintergrundBildZ( entfernenBild );
	initToolTip( entfernen, "Freund entfernen.", zSchrift->getThis(), hauptScreen );
	ansehen = initKnopf( 208, 49, 20, 20, 0, 0, "" );
	ansehen->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
	ansehen->setHintergrundBildZ( ansehenBild );
	initToolTip( ansehen, "Account ansehen.", zSchrift->getThis(), hauptScreen );
	nachricht = initKnopf( 188, 49, 20, 20, 0, 0, "" );
	nachricht->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
	nachricht->setHintergrundBildZ( nachrichtBild );
	initToolTip( nachricht, "Nachricht senden.", zSchrift->getThis(), hauptScreen );
	einladen = initKnopf( 168, 49, 20, 20, 0, 0, "" );
	einladen->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
	einladen->setHintergrundBildZ( einladenBild );
	initToolTip( einladen, "Spieler in Gruppe einladen.\nDies kann nur der Gruppen Administrator.", zSchrift->getThis(), hauptScreen );
	online = 0;
	einladenSichtbar = 0;
	ausgewählt = 0;
	höhe = 0;
	animation = 1;
	auswahlAlpha = 0;
	tickVal = 0;
	rend = 0;
	ref = 1;
	start();
}

// Destruktor
FreundData::~FreundData()
{
	rahmen = rahmen->release();
	auswahlBuffer = auswahlBuffer->release();
	name = name->release();
	status = status->release();
	entfernen = entfernen->release();
	ansehen = ansehen->release();
	nachricht = nachricht->release();
	einladen = einladen->release();
}

// nicht constant
void FreundData::thread()
{
	if( infoKlient )
	{
		Text *n = infoKlient->getSpielerName( accountId );
		name->setTextZ( n );
	}
	run = 0;
}

void FreundData::setName( char *txt )
{
	name->setText( txt );
	rend = 1;
}

void FreundData::setStatus( char *txt )
{
	status->setText( txt );
	rend = 1;
}

void FreundData::setOnline( bool online )
{
	this->online = online;
	if( online )
	{
		status->setSchriftFarbe( 0xFF00FF00 );
		status->setText( "online" );
	}
	else
	{
		status->setSchriftFarbe( 0xFFFF0000 );
		status->setText( "offline" );
	}
	einladen->setStyle( Knopf::Style::Erlaubt, einladenSichtbar && online );
	rend = 1;
}

void FreundData::setAusgewählt( bool ausw )
{
	if( animation != 3 )
	{
		ausgewählt = ausw;
		if( ausw )
			animation = 2;
		else
			animation = 1;
	}
}

void FreundData::löschen()
{
	animation = 3;
}

void FreundData::zeigeEinladeKnopf( bool zeigen )
{
	einladenSichtbar = zeigen;
	einladen->setStyle( Knopf::Style::Erlaubt, einladenSichtbar && online );
	rend = 1;
}

void FreundData::doMausEreignis( MausEreignis &me )
{
	if( animation != 3 )
	{
		bool tmp = 0;
		if( me.my > höhe || !ausgewählt )
		{
			tmp = me.verarbeitet;
			me.verarbeitet = 1;
		}
		char aktion = 0;
		bool vera = me.verarbeitet;
		nachricht->doMausEreignis( me );
		aktion = me.verarbeitet && !vera ? 1 : 0;
		ansehen->doMausEreignis( me );
		if( !aktion )
			aktion = me.verarbeitet && !vera ? 2 : 0;
		entfernen->doMausEreignis( me );
		if( !aktion )
			aktion = me.verarbeitet && !vera ? 3 : 0;
		einladen->doMausEreignis( me );
		if( !aktion )
			aktion = me.verarbeitet && !vera ? 4 : 0;
		if( me.my > höhe || !ausgewählt )
		{
			me.verarbeitet = tmp;
			return;
		}
		switch( aktion )
		{
		case 1:
			// Nachricht senden
			if( me.id == ME_RLinks )
				nachLogin->zChatLeiste()->addChat( accountId, 0 );
			break;
		case 2:
			// profil ansehen
			if( me.id == ME_RLinks )
			{
				if( nachLogin->zAccountAnsehenFenster()->setSpielerDetails( accountId, 2 ) )
				{
					MausEreignis me = { ME_RLinks, 0, 0, 0, 0, 0 };
					nachLogin->zTitelLeiste()->druckAccountAnsehen( me );
				}
			}
			break;
		case 3:
			// freund entfernen
			if( me.id == ME_RLinks )
			{
				int *id = new int;
				*id = accountId;
				Text *nachricht = new Text( "Möchtest du deine Freundschaft mit " );
				nachricht->anhängen( name->zText()->getText() );
				nachricht->anhängen( " wirklich beenden?" );
				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Bist du dir Sicher?" ), nachricht, new Text( "ja" ),
															  new Text( "abbrechen" ), NachrichtType::freundEntfernen, id );
			}
			break;
		case 4: // In Gruppe einladen
			if( me.id == ME_RLinks )
			{
				if( !anmeldungKlient->gruppeSpielerEinladen( accountId, nachLogin->zSpielenFenster()->getGruppeId() ) )
				{
					nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( anmeldungKlient->getLetzterFehler() ),
																  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
				}
			}
		default:
			// nichts
			break;
		}
	}
}

bool FreundData::tick( double tickVal )
{
	rend |= name->tick( tickVal );
	rend |= status->tick( tickVal );
	rend |= entfernen->tick( tickVal );
	rend |= ansehen->tick( tickVal );
	rend |= nachricht->tick( tickVal );
	rend |= einladen->tick( tickVal );
	this->tickVal += tickVal * 100;
	int val = ( int )this->tickVal;
	if( val < 1 )
	{
		bool ret = rend;
		rend = 0;
		return ret;
	}
	if( val > 4 )
		val = 4;
	this->tickVal -= val;
	switch( animation )
	{
	case 1:
		if( höhe != 50 )
		{
			if( höhe > 50 )
			{
				höhe -= val;
				if( höhe < 50 )
					höhe = 50;
			}
			else
			{
				höhe += val;
				if( höhe > 50 )
					höhe = 50;
			}
			rend = 1;
		}
		else
			animation = 0;
		break;
	case 2:
		if( höhe != 70 )
		{
			höhe += val;
			if( höhe > 70 )
				höhe = 70;
			rend = 1;
		}
		else
			animation = 0;
		break;
	case 3:
		höhe -= val;
		if( höhe <= 0 )
		{
			nachLogin->zFreundesListe()->removeMember( this ); // delete this
			return 1;
		}
		rend = 1;
		break;
	}
	if( ausgewählt && auswahlAlpha < 50 )
	{
		if( auswahlAlpha + val > 50 )
			auswahlAlpha = 50;
		else
			auswahlAlpha += val;
		rend = 1;
	}
	else if( !ausgewählt && auswahlAlpha > 0 )
	{
		if( auswahlAlpha - val < 0 )
			auswahlAlpha = 0;
		else
			auswahlAlpha -= val;
		rend = 1;
	}
	bool ret = rend;
	rend = 0;
	return ret;
}

void FreundData::render( int yPos, Bild &zRObj )
{
	int br = 250;
	if( !zRObj.setDrawOptions( 0, yPos, br, höhe ) )
		return;
	rahmen->setGröße( br, höhe );
	rahmen->render( zRObj );
	int rbr = rahmen->getRBreite();
	if( !zRObj.setDrawOptions( rbr, rbr, br - rbr * 2, höhe - rbr * 2 ) )
	{
		zRObj.releaseDrawOptions();
		return;
	}
	if( auswahlAlpha > 0 )
	{
		auswahlBuffer->setFarbe( 0x0000FF00 | ( ( (int)auswahlAlpha << 24 ) & 0xFF000000 ) );
		auswahlBuffer->setGröße( br - rbr * 2, höhe - rbr * 2 );
		auswahlBuffer->render( zRObj );
	}
	name->render( zRObj );
	status->render( zRObj );
	einladen->render( zRObj );
	nachricht->render( zRObj );
	ansehen->render( zRObj );
	entfernen->render( zRObj );
	zRObj.releaseDrawOptions();
	zRObj.releaseDrawOptions();
}

// constant
bool FreundData::istOnline() const
{
	return online;
}

bool FreundData::istAusgewählt() const
{
	return ausgewählt;
}

char *FreundData::zName() const
{
	return name->zText()->getText();
}

Text *FreundData::getName() const
{
	return name->getText();
}

char *FreundData::zStatus() const
{
	return status->zText()->getText();
}

Text *FreundData::getStatus() const
{
	return status->getText();
}

int FreundData::getAccountId() const
{
	return accountId;
}

int FreundData::getHöhe() const
{
	return höhe;
}

// reference Counting
FreundData *FreundData::getThis()
{
	ref++;
	return this;
}

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

// Inhalt der FreundesListeObj Klasse aus FreundesListe.h
// Konstruktor
FreundesListeObj::FreundesListeObj( Schrift *zSchrift )
	: Zeichnung()
{
	members = new RCArray< FreundData >();
	schrift = zSchrift->getThis();
	memberRahmen = new LRahmen();
	memberRahmen->setFarbe( 0xFFFFFFFF );
	memberRahmen->setRamenBreite( 1 );
	auswahlBuffer = new AlphaFeld();
	auswahlBuffer->setStärke( -2 );
	auswahlBuffer->setPosition( 1, 1 );
	vsb = new VScrollBar();
	vsb->setKlickScroll( 10 );
	bildschirmGröße = BildschirmGröße();
	vsb->update( 0, bildschirmGröße.y - 200 );
	memberNummer = 0;
	einladenSichtbar = 0;
	ref = 1;
}

// Destruktor
FreundesListeObj::~FreundesListeObj()
{
	members = members->release();
	schrift = schrift->release();
	memberRahmen = memberRahmen->release();
	auswahlBuffer = auswahlBuffer->release();
	vsb = vsb->release();
}

// nicht constant
void FreundesListeObj::addMember( int accountId )
{
	FreundData *tmp = new FreundData( accountId, memberRahmen->getThis(), auswahlBuffer->getThis(), schrift );
	members->add( tmp, memberNummer );
	memberNummer++;
	if( einladenSichtbar )
		tmp->zeigeEinladeKnopf( 1 );
	rend = 1;
}

void FreundesListeObj::removeMember( int accountId )
{
	for( int i = 0; i < memberNummer; i++ )
	{
		FreundData *tmp = members->z( i );
		if( tmp->getAccountId() == accountId )
		{
			tmp->löschen();
			break;
		}
	}
}

void FreundesListeObj::removeMember( FreundData *member )
{
	for( int i = 0; i < memberNummer; i++ )
	{
		if( members->z( i ) == member )
		{
			members->lösche( i );
			memberNummer--;
			rend = 1;
			break;
		}
	}
}

void FreundesListeObj::removeAll()
{
	members->leeren();
	memberNummer = 0;
	rend = 1;
}

void FreundesListeObj::setName( int accountId, char *txt )
{
	for( int i = 0; i < memberNummer; i++ )
	{
		FreundData *tmp = members->z( i );
		if( tmp->getAccountId() == accountId )
		{
			tmp->setName( txt );
			break;
		}
	}
}

void FreundesListeObj::setStatus( int accountId, char *txt )
{
	for( int i = 0; i < memberNummer; i++ )
	{
		FreundData *tmp = members->z( i );
		if( tmp->getAccountId() == accountId )
		{
			tmp->setStatus( txt );
			break;
		}
	}
}

void FreundesListeObj::setOnline( int accountId, bool online )
{
	for( int i = 0; i < memberNummer; i++ )
	{
		FreundData *tmp = members->z( i );
		if( tmp->getAccountId() == accountId )
		{
			tmp->setOnline( online );
			break;
		}
	}
}

void FreundesListeObj::zeigeEinladeKnopf( bool zeigen )
{
	einladenSichtbar = zeigen;
	for( int i = 0; i < memberNummer; i++ )
	{
		FreundData *tmp = members->z( i );
		tmp->zeigeEinladeKnopf( zeigen );
	}
}

bool FreundesListeObj::tick( double tickVal )
{
	rend |= vsb->getRend();
	rend |= nachLogin->zFreundesListe()->tick( tickVal );
	for( int i = 0; i < memberNummer; i++ )
	{
		FreundData *tmp = members->z( i );
		if( tmp )
			rend |= tmp->tick( tickVal );
	}
	bool ret = rend;
	rend = 0;
	return ret;
}

void FreundesListeObj::doMausEreignis( MausEreignis &me )
{
	int my = me.my;
	me.my -= pos.y;
	if( me.mx <= 250 && me.mx > 0 && me.my >= 0 )
	{
		me.my += vsb->getScrollData()->anzeigeBeginn;
		for( int i = 0; i < memberNummer; i++ )
		{
			FreundData *tmp = members->z( i );
			if( tmp )
			{
				if( me.my > 0 && me.my < tmp->getHöhe() )
					tmp->setAusgewählt( 1 );
				else
					tmp->setAusgewählt( 0 );
				tmp->doMausEreignis( me );
				me.my -= tmp->getHöhe();
			}
		}
		me.my -= vsb->getScrollData()->anzeigeBeginn;
	}
	else
	{
		me.my += vsb->getScrollData()->anzeigeBeginn;
		for( int i = 0; i < memberNummer; i++ )
		{
			FreundData *tmp = members->z( i );
			if( tmp )
			{
				tmp->setAusgewählt( 0 );
				tmp->doMausEreignis( me );
				me.my -= tmp->getHöhe();
			}
		}
		me.my -= vsb->getScrollData()->anzeigeBeginn;
	}
	me.my = my;
	vsb->doMausMessage( 250, pos.y, 20, gr.y, me );
}

void FreundesListeObj::render( Bild &zrObj )
{
	if( !zrObj.setDrawOptions( pos.x, pos.y, gr.x, gr.y ) )
		return;
	int höhe = 0;
	for( int i = 0; i < memberNummer; i++ )
	{
		FreundData *tmp = members->z( i );
		tmp->render( höhe, zrObj );
		höhe += tmp->getHöhe();
	}
	vsb->update( höhe, gr.y );
	vsb->render( 250, 0, 20, gr.y, zrObj );
	zrObj.releaseDrawOptions();
}

// constant
bool FreundesListeObj::istFreund( int accId ) const
{
	for( int i = 0; i < memberNummer; i++ )
	{
		FreundData *tmp = members->z( i );
		if( tmp->getAccountId() == accId )
			return 1;
	}
	return 0;
}

// reference Counting
FreundesListeObj *FreundesListeObj::getThis()
{
	ref++;
	return this;
}

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

// Inhalt der FreundesListe Klasse aus FreundesListe.h
// Konstruktor
FreundesListe::FreundesListe( Schrift *zSchrift, Fenster *zNachLoginFenster )
	: Thread()
{
	minimierenBild = bilder->get( "chat.ltdb/minimieren.png" );
	if( !minimierenBild )
	{
		LTDBDatei *datei = new LTDBDatei();
		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
		datei->leseDaten( 0 );
		minimierenBild = datei->laden( 0, new Text( "minimieren.png" ) );
		datei->release();
		bilder->add( "chat.ltdb/minimieren.png", minimierenBild->getThis() );
	}
	maximierenBild = bilder->get( "chat.ltdb/maximieren.png" );
	if( !maximierenBild )
	{
		LTDBDatei *datei = new LTDBDatei();
		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
		datei->leseDaten( 0 );
		maximierenBild = datei->laden( 0, new Text( "maximieren.png" ) );
		datei->release();
		bilder->add( "chat.ltdb/maximieren.png", maximierenBild->getThis() );
	}
	Bild *neuerFreundBild = bilder->get( "chat.ltdb/neuerfreund.png" );
	if( !neuerFreundBild )
	{
		LTDBDatei *datei = new LTDBDatei();
		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
		datei->leseDaten( 0 );
		neuerFreundBild = datei->laden( 0, new Text( "neuerfreund.png" ) );
		datei->release();
		bilder->add( "chat.ltdb/neuerfreund.png", neuerFreundBild->getThis() );
	}

	bildschirmGröße = BildschirmGröße();

	fenster = new Fenster();
	fenster->setStyle( Fenster::Style::Sichtbar | Fenster::Style::Erlaubt | Fenster::Style::Rahmen | Fenster::Style::KörperHintergrund );
	fenster->setGröße( 270, 20 );
	fenster->setRFarbe( 0xFFFFFFFF );
	fenster->setKBgFarbe( 0xFF000000 );
	fenster->setPosition( -250, 100 );

	minMax = initKnopf( 249, 1, 20, 20, 0, 0, "" );
	minMax->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
	minMax->setHintergrundBildZ( minimierenBild->getThis() );
	minMax->setMausEreignisParameter( this );
	minMax->setMausEreignis( freundesListeMinMaxME );
	initToolTip( minMax, "Freundes Leiste minimieren.", zSchrift->getThis(), hauptScreen );
	fenster->addMember( minMax );

	überschrift = initTextFeld( 0, 5, 250, 25, zSchrift, TextFeld::Style::Text | TextFeld::Style::Center | TextFeld::Style::Sichtbar, "Freunde" );
	überschrift->setSchriftGröße( 15 );
	fenster->addMember( überschrift );

	accountName = initTextFeld( 25, 40, 200, 20, zSchrift, TextFeld::Style::TextFeld | TextFeld::Style::Sichtbar, "" );
	accountName->setTastaturEreignisParameter( this );
	accountName->setTastaturEreignis( freundesListeNameTE );
	initToolTip( accountName, "Mit diesem Namen bist du bei anderen Spielern sichtbar.", zSchrift->getThis(), hauptScreen );
	fenster->addMember( accountName );

	LTDBDatei *chatBilder = new LTDBDatei();
	chatBilder->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
	chatBilder->leseDaten( 0 );
	Bild *neuerChatBild = chatBilder->laden( 0, new Text( "neuerchat.png" ) );
	chatBilder = chatBilder->release();

	neuerFreund = initKnopf( 5, 75, 20, 20, 0, 0, "" );
	neuerFreund->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::HAlpha | Knopf::Style::KlickBuffer );
	neuerFreund->setHintergrundBildZ( neuerFreundBild );
	neuerFreund->setMausEreignisParameter( this );
	neuerFreund->setMausEreignis( freundesListeNeuerFreundME );
	initToolTip( neuerFreund, "Freundesanfrage senden.", zSchrift->getThis(), hauptScreen );
	fenster->addMember( neuerFreund );

	neuerChat = initKnopf( 30, 75, 20, 20, 0, 0, "" );
	neuerChat->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::HAlpha | Knopf::Style::KlickBuffer );
	neuerChat->setHintergrundBildZ( neuerChatBild );
	neuerChat->setMausEreignisParameter( this );
	neuerChat->setMausEreignis( freundesListeNeuerChatME );
	initToolTip( neuerChat, "Nachricht senden.", zSchrift->getThis(), hauptScreen );
	fenster->addMember( neuerChat );

	neuerFreundFenster = initFenster( 0, 100, 270, 0, 0, Fenster::Style::Erlaubt | Fenster::Style::Rahmen, 0 );
	neuerFreundSpielerName = initTextFeld( 5, 5, 235, 20, zSchrift, TextFeld::Style::Sichtbar | TextFeld::Style::TextFeld, "Spieler Name" );
	neuerFreundSpielerName->setTastaturEreignisParameter( this );
	neuerFreundSpielerName->setTastaturEreignis( freundesListeNeuerFreundSpielerNameTE );
	initToolTip( neuerFreundSpielerName, "Name des Spielers an den eine Freundesanfrage gesendet werden soll.", zSchrift->getThis(), hauptScreen );
	neuerFreundFenster->addMember( neuerFreundSpielerName );
	neuerFreundFertig = initKnopf( 245, 5, 20, 20, 0, 0, "" );
	neuerFreundFertig->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::HAlpha | Knopf::Style::KlickBuffer );
	neuerFreundFertig->setHintergrundBildZ( maximierenBild->getThis() );
	neuerFreundFertig->setMausEreignisParameter( this );
	neuerFreundFertig->setMausEreignis( freundesListeNeuerFreundFertigME );
	initToolTip( neuerFreundFertig, "Diesem Spieler eine Freundesanfrage senden.", zSchrift->getThis(), hauptScreen );
	neuerFreundFenster->addMember( neuerFreundFertig );
	fenster->addMember( neuerFreundFenster );

	neuerChatFenster = initFenster( 0, 100, 270, 0, 0, Fenster::Style::Erlaubt | Fenster::Style::Rahmen, 0 );
	neuerChatName = initTextFeld( 5, 5, 235, 20, zSchrift, TextFeld::Style::Sichtbar | TextFeld::Style::TextFeld, "Spieler Name" );
	neuerChatName->setTastaturEreignisParameter( this );
	neuerChatName->setTastaturEreignis( freundesListeNeuerChatNameTE );
	initToolTip( neuerChatName, "Name des Spielers an den eine Nachricht gesendet werden soll.", zSchrift->getThis(), hauptScreen );
	neuerChatFenster->addMember( neuerChatName );
	neuerChatFertig = initKnopf( 245, 5, 20, 20, 0, 0, "" );
	neuerChatFertig->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::HAlpha | Knopf::Style::KlickBuffer );
	neuerChatFertig->setHintergrundBildZ( maximierenBild->getThis() );
	neuerChatFertig->setMausEreignisParameter( this );
	neuerChatFertig->setMausEreignis( freundesListeNeuerChatFertigME );
	initToolTip( neuerChatFertig, "Diesem Spieler eine Nachricht senden.", zSchrift->getThis(), hauptScreen );
	neuerChatFenster->addMember( neuerChatFertig );
	neuesChatroomName = initTextFeld( 5, 30, 235, 20, zSchrift, TextFeld::Style::Sichtbar | TextFeld::Style::TextFeld, "Chatroom Name" );
	neuesChatroomName->setTastaturEreignisParameter( this );
	neuesChatroomName->setTastaturEreignis( freundesListeNeuesChatroomNameTE );
	initToolTip( neuesChatroomName, "Name des Chatroom dem du beitreten möchtest.", zSchrift->getThis(), hauptScreen );
	neuerChatFenster->addMember( neuesChatroomName );
	neuesChatroomFertig = initKnopf( 245, 30, 20, 20, 0, 0, "" );
	neuesChatroomFertig->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::HAlpha | Knopf::Style::KlickBuffer );
	neuesChatroomFertig->setHintergrundBildZ( maximierenBild->getThis() );
	neuesChatroomFertig->setMausEreignisParameter( this );
	neuesChatroomFertig->setMausEreignis( freundesListeNeuesChatroomFertigME );
	initToolTip( neuesChatroomFertig, "Chatroom erstellen oder beitreten.", zSchrift->getThis(), hauptScreen );
	neuerChatFenster->addMember( neuesChatroomFertig );
	fenster->addMember( neuerChatFenster );

	freundesListe = new FreundesListeObj( zSchrift );
	freundesListe->setPosition( 0, 100 );
	freundesListe->setGröße( 270, bildschirmGröße.y - 200 );
	fenster->addMember( freundesListe );

	zNachLoginFenster->addMember( fenster );
	animation = 1;
	tickVal = 0;
	ref = 1;
	neuerFreundSichtbar = 0;
	neuerChatSichtbar = 0;
	rend = 0;

	start();
}

// Destruktor
FreundesListe::~FreundesListe()
{
	ende();
	fenster = fenster->release();
	minimierenBild = minimierenBild->release();
	maximierenBild = maximierenBild->release();
	minMax = minMax->release();
	überschrift = überschrift->release();
	accountName = accountName->release();
	freundesListe = freundesListe->release();
	neuerFreund = neuerFreund->release();
	neuerChat = neuerChat->release();
	neuerFreundFenster = neuerFreundFenster->release();
	neuerFreundSpielerName = neuerFreundSpielerName->release();
	neuerFreundFertig = neuerFreundFertig->release();
	neuerChatFenster = neuerChatFenster->release();
	neuerChatName = neuerChatName->release();
	neuerChatFertig = neuerChatFertig->release();
	neuesChatroomName = neuesChatroomName->release();
	neuesChatroomFertig = neuesChatroomFertig->release();
}

// nicht constant
void FreundesListe::addMember( int accountId )
{
	freundesListe->addMember( accountId );
}

void FreundesListe::removeMember( int accountId )
{
	freundesListe->removeMember( accountId );
}

void FreundesListe::removeMember( FreundData *member )
{
	freundesListe->removeMember( member );
}

void FreundesListe::removeAll()
{
	freundesListe->removeAll();
}

void FreundesListe::setName( int accountId, char *txt )
{
	freundesListe->setName( accountId, txt );
}

void FreundesListe::setStatus( int accountId, char *txt )
{
	freundesListe->setStatus( accountId, txt );
}

void FreundesListe::setOnline( int accountId, bool online )
{
	freundesListe->setOnline( accountId, online );
}

void FreundesListe::setAnimation( int animation )
{
	this->animation = animation;
}

void FreundesListe::thread()
{
	bool err = 1;
	if( infoKlient && loginKlient )
	{
		Text *name = infoKlient->getSpielerName( loginKlient->getAccountId() );
		if( name )
		{
			accountName->setText( name->getText() );
			name->release();
			err = 0;
		}
	}
	if( err && nachLogin->zNachrichtenListe() )
	{
		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
													   new Text( "Dein Accountname konnte nicht ermittelt werden." ),
													   new Text( "Ok" ),
													   0,
													   NachrichtType::nachricht,
													   0 );
	}
	err = 0;
	if( ( !chatKlient || !chatKlient->freundesListeAnfragen() ) && nachLogin->zNachrichtenListe() )
	{
		nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ),
													   new Text( "Deine Freunde konnten nicht geladen werden." ),
													   new Text( "Ok" ),
													   0,
													   NachrichtType::nachricht,
													   0 );
	}
	run = 0;
}

void FreundesListe::zeigeEinladeKnopf( bool zeigen )
{
	freundesListe->zeigeEinladeKnopf( zeigen );
}

bool FreundesListe::tick( double tickVal )
{
	this->tickVal += tickVal * 400;
	int val = ( int )this->tickVal;
	if( val < 1 )
	{
		bool ret = rend;
		rend = 0;
		return ret;
	}
	if( val > 14 )
		val = 14;
	this->tickVal -= val;
	switch( animation )
	{
	case 1:
		if( fenster->getX() < 0 )
		{
			fenster->setPosition( fenster->getX() + val, fenster->getY() );
			if( fenster->getX() > 0 )
				fenster->setPosition( 0, fenster->getY() );
		}
		else if( fenster->getHöhe() < bildschirmGröße.y - 100 )
		{
			fenster->setGröße( fenster->getBreite(), fenster->getHöhe() + val );
			if( fenster->getHöhe() > bildschirmGröße.y - 100 )
				fenster->setGröße( fenster->getBreite(), bildschirmGröße.y - 100 );
		}
		else
			animation = 0;
		rend = 1;
		break;
	case 2:
		if( fenster->getHöhe() > 20 )
		{
			fenster->setGröße( fenster->getBreite(), fenster->getHöhe() - val );
			if( fenster->getHöhe() < 20 )
				fenster->setGröße( fenster->getBreite(), 20 );
		}
		else if( fenster->getX() > -250 )
		{
			fenster->setPosition( fenster->getX() - val, fenster->getY() );
			if( fenster->getX() < -250 )
				fenster->setPosition( -250, fenster->getY() );
		}
		else
			animation = 0;
		rend = 1;
		break;
	}
	if( neuerFreundSichtbar )
	{
		if( neuerFreundFenster->getHöhe() != 30 && neuerChatFenster->hatStyleNicht( Fenster::Style::Sichtbar ) )
		{
			neuerFreundFenster->addStyle( Fenster::Style::Sichtbar );
			neuerFreundFenster->setGröße( neuerFreundFenster->getBreite(), neuerFreundFenster->getHöhe() + val );
			freundesListe->setPosition( freundesListe->getX(), freundesListe->getY() + val );
			freundesListe->setGröße( freundesListe->getBreite(), freundesListe->getHöhe() - val );
			if( neuerFreundFenster->getHöhe() > 30 )
			{
				neuerFreundFenster->setGröße( neuerFreundFenster->getBreite(), 30 );
				freundesListe->setPosition( freundesListe->getX(), 130 );
				freundesListe->setGröße( freundesListe->getBreite(), bildschirmGröße.y - 230 );
			}
			rend = 1;
		}
	}
	else
	{
		if( neuerFreundFenster->hatStyle( Fenster::Style::Sichtbar ) )
		{
			neuerFreundFenster->setGröße( neuerFreundFenster->getBreite(), neuerFreundFenster->getHöhe() - val );
			freundesListe->setPosition( freundesListe->getX(), freundesListe->getY() - val );
			freundesListe->setGröße( freundesListe->getBreite(), freundesListe->getHöhe() + val );
			if( neuerFreundFenster->getHöhe() < 0 )
			{
				neuerFreundFenster->setGröße( neuerFreundFenster->getBreite(), 0 );
				neuerFreundFenster->löscheStyle( Fenster::Style::Sichtbar );
				freundesListe->setPosition( freundesListe->getX(), 100 );
				freundesListe->setGröße( freundesListe->getBreite(), bildschirmGröße.y - 200 );
			}
			rend = 1;
		}
	}
	if( neuerChatSichtbar )
	{
		if( neuerChatFenster->getHöhe() != 55 && neuerFreundFenster->hatStyleNicht( Fenster::Style::Sichtbar ) )
		{
			neuerChatFenster->addStyle( Fenster::Style::Sichtbar );
			neuerChatFenster->setGröße( neuerChatFenster->getBreite(), neuerChatFenster->getHöhe() + val );
			freundesListe->setPosition( freundesListe->getX(), freundesListe->getY() + val );
			freundesListe->setGröße( freundesListe->getBreite(), freundesListe->getHöhe() - val );
			if( neuerChatFenster->getHöhe() > 55 )
			{
				neuerChatFenster->setGröße( neuerChatFenster->getBreite(), 55 );
				freundesListe->setPosition( freundesListe->getX(), 155 );
				freundesListe->setGröße( freundesListe->getBreite(), bildschirmGröße.y - 255 );
			}
			rend = 1;
		}
	}
	else
	{
		if( neuerChatFenster->hatStyle( Fenster::Style::Sichtbar ) )
		{
			neuerChatFenster->setGröße( neuerChatFenster->getBreite(), neuerChatFenster->getHöhe() - val );
			freundesListe->setPosition( freundesListe->getX(), freundesListe->getY() - val );
			freundesListe->setGröße( freundesListe->getBreite(), freundesListe->getHöhe() + val );
			if( neuerChatFenster->getHöhe() < 0 )
			{
				neuerChatFenster->setGröße( neuerChatFenster->getBreite(), 0 );
				neuerChatFenster->löscheStyle( Fenster::Style::Sichtbar );
				freundesListe->setPosition( freundesListe->getX(), 100 );
				freundesListe->setGröße( freundesListe->getBreite(), bildschirmGröße.y - 200 );
			}
			rend = 1;
		}
	}
	bool ret = rend;
	rend = 0;
	return ret;
}

bool FreundesListe::druckMinMax( MausEreignis &me )
{
	if( me.id == ME_RLinks )
	{
		if( minMax->zHintergrundBild() == minimierenBild )
		{
			animation = 2;
			minMax->setHintergrundBildZ( maximierenBild->getThis() );
			minMax->zToolTip()->setText( "Freundes Leiste maximieren." );
		}
		else
		{
			animation = 1;
			minMax->setHintergrundBildZ( minimierenBild->getThis() );
			minMax->zToolTip()->setText( "Freundes Leiste minimieren." );
		}
	}
	return 1;
}

bool FreundesListe::druckName( TastaturEreignis &te )
{
	if( te.id == TE_Release && te.taste == T_Enter )
		chatKlient->accountNameÄndern( accountName->zText()->getText() );
	return 1;
}

bool FreundesListe::druckNeuerFreund( MausEreignis &me )
{
	if( me.id == ME_RLinks )
	{
		neuerChatSichtbar = 0;
		neuerFreundSichtbar = !neuerFreundSichtbar;
	}
	return 1;
}

bool FreundesListe::druckNeuerChat( MausEreignis &me )
{
	if( me.id == ME_RLinks )
	{
		neuerFreundSichtbar = 0;
		neuerChatSichtbar = !neuerChatSichtbar;
	}
	return 1;
}

bool FreundesListe::druckNeuerFreundSpielerName( TastaturEreignis &te )
{
	if( !neuerFreundSichtbar )
		return 0;
	if( te.id == TE_Release && te.taste == T_Enter )
	{
		MausEreignis me = { ME_RLinks, 0, 0, 0 };
		druckNeuerFreundFertig( me );
	}
	return 1;
}

bool FreundesListe::druckNeuerFreundFertig( MausEreignis &me )
{
	if( !neuerFreundSichtbar )
		return 0;
	if( me.id == ME_RLinks )
	{
		if( neuerFreundSpielerName->zText()->getLänge() )
		{
			int accountId = infoKlient->getAccountId( neuerFreundSpielerName->zText()->getText() );
			if( accountId )
			{
				if( chatKlient->freundesAnfrage( accountId ) )
				{
					nachLogin->zNachrichtenListe()->addNachricht( new Text( "Freundesanfrage" ), new Text( "Es wurde eine Anfrage an den Spieler gesendet." ),
																  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
					neuerFreundSichtbar = 0;
				}
			}
			else
				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Der Spieler wurde nicht gefunden." ),
				new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
		}
	}
	return 1;
}

bool FreundesListe::druckNeuerChatName( TastaturEreignis &te )
{
	if( !neuerChatSichtbar )
		return 0;
	if( te.id == TE_Release && te.taste == T_Enter )
	{
		MausEreignis me = { ME_RLinks, 0, 0, 0 };
		druckNeuerChatFertig( me );
	}
	return 1;
}

bool FreundesListe::druckNeuerChatFertig( MausEreignis &me )
{
	if( !neuerChatSichtbar )
		return 0;
	if( me.id == ME_RLinks )
	{
		if( neuerChatName->zText()->getLänge() )
		{
			int accountId = infoKlient->getAccountId( neuerChatName->zText()->getText() );
			if( accountId )
			{
				nachLogin->zChatLeiste()->addChat( accountId, 0 );
				neuerChatSichtbar = 0;
			}
			else
				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Der Spieler wurde nicht gefunden." ),
				new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
		}
	}
	return 1;
}

bool FreundesListe::druckNeuesChatroomName( TastaturEreignis &te )
{
	if( !neuerChatSichtbar )
		return 0;
	if( te.id == TE_Release && te.taste == T_Enter )
	{
		MausEreignis me = { ME_RLinks, 0, 0, 0 };
		druckNeuesChatroomFertig( me );
	}
	return 1;
}

bool FreundesListe::druckNeuesChatroomFertig( MausEreignis &me )
{
	if( !neuerChatSichtbar )
		return 0;
	if( me.id == ME_RLinks )
	{
		if( neuesChatroomName->zText()->getLänge() )
		{
			int chatroomId = infoKlient->getChatroomId( neuesChatroomName->zText()->getText() );
			if( chatroomId )
			{
				if( chatKlient->chatroomBetreten( chatroomId ) )
				{
					nachLogin->zChatLeiste()->addChat( 0, chatroomId );
					neuerChatSichtbar = 0;
				}
			}
			else
			{
				chatroomId = chatKlient->chatroomErstellen( neuesChatroomName->zText()->getText() );
				if( chatroomId )
				{
					nachLogin->zChatLeiste()->addChat( 0, chatroomId );
					neuerChatSichtbar = 0;
				}
			}
		}
	}
	return 1;
}

// constant
bool FreundesListe::istFreund( int accId ) const
{
	return freundesListe->istFreund( accId );
}

// reference Counting
FreundesListe *FreundesListe::getThis()
{
	ref++;
	return this;
}

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

// Nachrichten
bool freundesListeMinMaxME( void *p, void *obj, MausEreignis me )
{
	return ( (FreundesListe*)p )->druckMinMax( me );
}

bool freundesListeNameTE( void *p, void *obj, TastaturEreignis te )
{
	return ( (FreundesListe*)p )->druckName( te );
}

bool freundesListeNeuerFreundME( void *p, void *obj, MausEreignis me )
{
	return ( (FreundesListe*)p )->druckNeuerFreund( me );
}

bool freundesListeNeuerChatME( void *p, void *obj, MausEreignis me )
{
	return ( (FreundesListe*)p )->druckNeuerChat( me );
}

bool freundesListeNeuerFreundSpielerNameTE( void *p, void *obj, TastaturEreignis te )
{
	return ( (FreundesListe*)p )->druckNeuerFreundSpielerName( te );
}

bool freundesListeNeuerFreundFertigME( void *p, void *obj, MausEreignis me )
{
	return ( (FreundesListe*)p )->druckNeuerFreundFertig( me );
}

bool freundesListeNeuerChatNameTE( void *p, void *obj, TastaturEreignis te )
{
	return ( (FreundesListe*)p )->druckNeuerChatName( te );
}

bool freundesListeNeuerChatFertigME( void *p, void *obj, MausEreignis me )
{
	return ( (FreundesListe*)p )->druckNeuerChatFertig( me );
}

bool freundesListeNeuesChatroomNameTE( void *p, void *obj, TastaturEreignis te )
{
	return ( (FreundesListe*)p )->druckNeuesChatroomName( te );
}

bool freundesListeNeuesChatroomFertigME( void *p, void *obj, MausEreignis me )
{
	return ( (FreundesListe*)p )->druckNeuesChatroomFertig( me );
}