#include "ChatLeiste.h"
#include "..\..\Global\Initialisierung.h"
#include <Bild.h>
#include <Rahmen.h>
#include <Punkt.h>
#include "..\..\Global\Variablen.h"
#include <DateiSystem.h>
#include <ToolTip.h>
#include <GSLDateiV.h>

typedef GSL::GSLDateiV *( *GetGSLDatei )( );

// Inhalt der Chat Klasse aus ChatLeiste.h
// Konstruktor
Chat::Chat( Schrift *zSchrift )
{
	Bild *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() );
	}
	Bild *schließenBild = bilder->get( "chat.ltdb/entfernen.png" );
	if( !schließenBild )
	{
		LTDBDatei *datei = new LTDBDatei();
		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
		datei->leseDaten( 0 );
		schließenBild = datei->laden( 0, new Text( "entfernen.png" ) );
		datei->release();
		bilder->add( "chat.ltdb/entfernen.png", schließenBild->getThis() );
	}
	rahmen = new LRahmen();
	rahmen->setAlpha( 1 );
	rahmen->setFarbe( 0xFFFFFFFF );
	rahmen->setRamenBreite( 1 );
	verlauf = initTextFeld( 7, 7, 184, 210, zSchrift, TextFeld::Style::TextGebiet, "" );
	verlauf->löscheStyle( TextFeld::Style::Erlaubt );
	verlauf->updateVScroll();
	nachricht = initTextFeld( 1, 220, 198, 20, zSchrift, TextFeld::Style::TextFeld, "" );
	initToolTip( nachricht, "Nachricht senden.", zSchrift->getThis(), hauptScreen );
	name = initTextFeld( 1, 250, 198, 29, zSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, "" );
	minimieren = initKnopf( 159, 255, 20, 20, 0, 0, "" );
	minimieren->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
	minimieren->setHintergrundBildZ( minimierenBild );
	initToolTip( minimieren, "Fenster einklappen.", zSchrift->getThis(), hauptScreen );
	schließen = initKnopf( 179, 255, 20, 20, 0, 0, "" );
	schließen->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
	schließen->setHintergrundBildZ( schließenBild );
	initToolTip( schließen, "Fenster schließen.", zSchrift->getThis(), hauptScreen );
	bildschirmGröße = BildschirmGröße();
	admin = 0;
	tickVal = 0;
	sichtbar = 1;
	breite = 0;
	höhe = 30;
	animation = 1;
	rend = 0;
	msgSound = 0;
	HMODULE dll = dllDateien->ladeDLL( "GSL.dll", "data/bin/GSL.dll" );
	if( dll )
	{
		GetGSLDatei getGSLDatei = (GetGSLDatei)GetProcAddress( dll, "getGSLDatei" );
		if( getGSLDatei )
		{
			GSL::GSLDateiV *sDat = getGSLDatei();
			sDat->setDatei( "data/sounds/popup.gsl" );
			sDat->leseDaten();
			msgSound = sDat->getSound( "chat.wav" );
			sDat->release();
			if( msgSound )
				msgSound->setLautstärke( 0xFFFF, 0xFFFF );
		}
		if( !msgSound )
			dllDateien->releaseDLL( "GSL.dll" );
	}
	ref = 1;
}

// Destruktor
Chat::~Chat()
{
	if( msgSound )
	{
		msgSound->release();
		dllDateien->releaseDLL( "GSL.dll" );
	}
	rahmen = rahmen->release();
	verlauf = verlauf->release();
	nachricht = nachricht->release();
	name = name->release();
	minimieren = minimieren->release();
	schließen = schließen->release();
}

// nicht constant
void Chat::setSichtbar( bool sichtbar )
{
	if( sichtbar )
		animation = 2;
	else
		animation = 3;
	this->sichtbar = sichtbar;
}

void Chat::entfernen()
{
	animation = 4;
}

void Chat::addNachricht( char *txt )
{
	if( msgSound )
	    msgSound->playSound();
	Text *n = new Text( txt );
	if( txt[ 0 ] != '\r' )
		n->anhängen( "\r0xFFFFFFFF" );
	verlauf->zSchrift()->textFormatieren( n, verlauf->getBreite() - 20, verlauf->getSchriftGröße() );
	if( n->getText()[ n->getLänge() - 1 ] != '\n' )
		n->anhängen( "\n" );
	verlauf->zText()->anhängen( n );
	if( animation != 4 )
		animation = 2;
	verlauf->updateVScroll();
	rend = 1;
}

void Chat::setAdmin()
{
	admin = 1;
	rend = 1;
}

void Chat::addSpieler( int accountId )
{
	// nur bei chatroom
}

void Chat::removeSpieler( int accountId )
{
	// nur bei chatroom
}

bool Chat::tick( double tickVal )
{
	// virtual
	return 0;
}

void Chat::doMausEreignis( MausEreignis &me )
{
	// virtual
}

void Chat::doTastaturEreignis( TastaturEreignis &te )
{
	// virtual
}

void Chat::render( int x, Bild &zRObj )
{
	// virtual
}

// constant
TextFeld *Chat::getName() const
{
	return name->getThis();
}

TextFeld *Chat::zName() const
{
	return name;
}

int Chat::getAccountId() const
{
	// nur bei chat
	return 0;
}

int Chat::getChatroomId() const
{
	// nur bei chatroom
	return 0;
}

int Chat::getBreite() const
{
	return breite;
}

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

// Reference Counting
void *Chat::getThis()
{
	// virtual
	return 0;
}

void *Chat::release()
{
	// virtual
	return 0;
}

// Inhalt der ChatFenster Klasse aus ChatLeiste.h
// Konstruktor
ChatFenster::ChatFenster( Schrift *zSchrift, int accountId )
	: Chat( zSchrift )
{
	this->accountId = accountId;
	name->setTextZ( infoKlient->getSpielerName( accountId ) );
}

// Destruktor
ChatFenster::~ChatFenster()
{

}

// nicht constant
bool ChatFenster::tick( double tickVal )
{
	rend |= schließen->tick( tickVal );
	rend |= minimieren->tick( tickVal );
	rend |= verlauf->tick( tickVal );
	rend |= nachricht->tick( tickVal );
	if( !animation )
	{
		bool ret = rend;
		rend = 0;
		return ret;
	}
	this->tickVal += tickVal * 300;
	int val = ( int )this->tickVal;
	if( val < 1 )
	{
		bool ret = rend;
		rend = 0;
		return ret;
	}
	if( val > 10 )
		val = 10;
	this->tickVal -= val;
	switch( animation )
	{
	case 1: // erstellen
	case 2: // ausfahren
		if( breite == 200 )
		{
			höhe += val;
			if( höhe > 280 )
			{
				höhe = 280;
				animation = 0;
			}
		}
		else
		{
			breite += val;
			if( breite > 200 )
				breite = 200;
		}
		rend = 1;
		break;
	case 3: // einfahren
		if( höhe == 30 )
		{
			breite -= val;
			if( breite < 100 )
			{
				breite = 100;
				animation = 0;
			}
		}
		else
		{
			höhe -= val;
			if( höhe < 30 )
				höhe = 30;
		}
		rend = 1;
		break;
	case 4: // schließen
		if( höhe == 30 )
		{
			breite -= val;
			if( breite < 0 )
			{
				nachLogin->zChatLeiste()->removeChat( this ); // delete this
				return 1;
			}
		}
		else
		{
			höhe -= val;
			if( höhe < 30 )
				höhe = 30;
		}
		rend = 1;
		break;
	}
	bool ret = rend;
	rend = 0;
	return ret;
}

void ChatFenster::doMausEreignis( MausEreignis &me )
{
	bool tmp = me.verarbeitet;
	if( me.mx < 0 || me.mx > breite || me.my < 280 - höhe || animation )
		me.verarbeitet = 1;
	verlauf->doMausEreignis( me );
	bool vera = me.verarbeitet;
	minimieren->doMausEreignis( me );
	int aktion = me.verarbeitet && !vera ? 1 : 0;
	schließen->doMausEreignis( me );
	if( !aktion )
		aktion = me.verarbeitet && !vera ? 2 : 0;
	nachricht->doMausEreignis( me );
	if( me.mx < 0 || me.mx > breite || me.my < 280 - höhe || animation )
	{
		me.verarbeitet = tmp;
		return;
	}
	if( !aktion && !sichtbar && !vera )
	{
		if( me.mx < breite && me.mx > 0 && me.my > 250 && me.my < 280 )
			aktion = 3;
	}
	switch( aktion )
	{
	case 1: // einfahren
		if( me.id == ME_RLinks )
			this->setSichtbar( 0 );
		break;
	case 2: // schließen
		if( me.id == ME_RLinks )
			animation = 4;
		break;
	case 3: // ausfahren
		if( me.id == ME_RLinks )
			this->setSichtbar( 1 );
		break;
	}
}

void ChatFenster::doTastaturEreignis( TastaturEreignis &te )
{
	bool tmp = te.verarbeitet;
	if( animation )
		te.verarbeitet = 1;
	nachricht->doTastaturEreignis( te );
	int aktion = te.verarbeitet && !tmp ? 1 : 0;
	if( animation )
	{
		te.verarbeitet = tmp;
		return;
	}
	switch( aktion )
	{
	case 1:
		if( te.id == TE_Release && te.taste == T_Enter )
		{
			if( !nachricht->zText()->getLänge() )
				break;
			nachricht->zText()->löschen( "\n" );
			if( chatKlient->chatNachricht( accountId, nachricht->zText()->getText() ) )
			{
				Text *n = new Text( nachricht->zText()->getText() );
				n->einfügen( 0, "\r0xFF00FF00" );
				n->anhängen( "\r0xFFFFFFFF" );
				verlauf->zSchrift()->textFormatieren( n, verlauf->getBreite() - 15, verlauf->getSchriftGröße() );
				if( n->getText()[ n->getLänge() - 1 ] != '\n' )
					n->anhängen( "\n" );
				verlauf->zText()->anhängen( n->getText() );
				n->release();
				verlauf->updateVScroll();
				nachricht->setText( "" );
				nachricht->setAuswahl( 0, 0 );
				rend = 1;
			}
		}
		break;
	}
}

void ChatFenster::render( int xPos, Bild &zRObj )
{
	int x = xPos;
	int y = 280 - höhe;
	int br = breite;
	int hö = höhe;
	if( !zRObj.setDrawOptions( x, y, br, hö ) )
		return;
	zRObj.alphaRegion( 0, 0, br, hö, 0xA0000000 );
	rahmen->setGröße( br, hö );
	rahmen->render( zRObj );
	zRObj.addScrollOffset( 0, 280 - höhe );
	verlauf->render( zRObj );
	nachricht->render( zRObj );
	name->render( zRObj );
	minimieren->render( zRObj );
	schließen->render( zRObj );
	zRObj.releaseDrawOptions();
}

// constant
int ChatFenster::getAccountId() const
{
	return accountId;
}

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

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

// Inhalt der ChatroomFenster Klasse aus ChatLeiste.h
// Konstruktor
ChatroomFenster::ChatroomFenster( Schrift *zSchrift, int chatroomId )
	: Chat( zSchrift )
{
	Bild *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() );
	}
	this->chatroomId = chatroomId;
	spielerName = initTextFeld( 200, 5, 120, 0, zSchrift, TextFeld::Style::TextFeld, "" );
	initToolTip( spielerName, "Name des Spielers der eingeladen werden soll.", zSchrift->getThis(), hauptScreen );
	einladen = initKnopf( 325, 5, 20, 0, 0, 0, "" );
	einladen->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
	einladen->setHintergrundBildZ( maximierenBild );
	initToolTip( einladen, "Spieler ins Chatroom einladen.", zSchrift->getThis(), hauptScreen );
	spieler = new ObjTabelle();
	spieler->setMausEreignis( _ret1ME );
	spieler->setStyle( ObjTabelle::Style::Sichtbar | ObjTabelle::Style::Rahmen | ObjTabelle::Style::VScroll | ObjTabelle::Style::Erlaubt | ObjTabelle::Style::VScroll | ObjTabelle::Style::Raster );
	spieler->setVertikalKlickScroll( 5 );
	spieler->setPosition( 200, 1 );
	spieler->setGröße( 149, 240 );
	spieler->setRasterFarbe( 0xFF555555 );
	spieler->setLinienRahmenFarbe( 0xFFFFFFFF );
	spieler->addSpalte( 0, "Name" );
	spieler->addSpalte( 1, "Freund" );
	spieler->addSpalte( 2, "Kick" );
	spieler->setSpaltenBreite( 0, 110 );
	spieler->setSpaltenBreite( 1, 20 );
	spieler->setSpaltenBreite( 2, 0 );
	schrift = zSchrift->getThis();
	name->setTextZ( infoKlient->getChatroomName( chatroomId ) );
	schließen->setPosition( schließen->getX() + 150, schließen->getY() );
	minimieren->setPosition( minimieren->getX() + 150, minimieren->getY() );
	neueSpieler = new Array< int >();
	alteSpieler = new Array< int >();
	neueSpielerAnzahl = 0;
	alteSpielerAnzahl = 0;
}

// Destruktor
ChatroomFenster::~ChatroomFenster()
{
	chatKlient->chatroomVerlassen( chatroomId );
	schrift = schrift->release();
	neueSpieler = neueSpieler->release();
	alteSpieler = alteSpieler->release();
	for( int i = 0; i < spieler->getZeilenAnzahl(); i++ )
	{
		TextFeld *name = (TextFeld*)spieler->zZeichnung( 0, 0 );
		name = name->release();
		Knopf *freund = (Knopf*)spieler->zZeichnung( 1, 0 );
		freund = freund->release();
		Knopf *entfernen = (Knopf*)spieler->zZeichnung( 2, 0 );
		entfernen = entfernen->release();
		spieler->removeZeile( 0 );
	}
	for( int i = 0; i < 3; i++ )
		spieler->removeSpalte( 0 );
	spieler = spieler->release();
	spielerName = spielerName->release();
	einladen = einladen->release();
}

// nicht constant
void ChatroomFenster::addSpieler( int accountId )
{
	Text *zeile = new Text();
	zeile->anhängen( accountId );
	if( spieler->getZeilenNummer( zeile->getText() ) >= 0 )
		return;
	Bild *einladenBild = bilder->get( "chat.ltdb/maximieren.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( "maximieren.png" ) );
		datei->release();
		bilder->add( "chat.ltdb/maximieren.png", einladenBild->getThis() );
	}
	Bild *schließenBild = bilder->get( "chat.ltdb/entfernen.png" );
	if( !schließenBild )
	{
		LTDBDatei *datei = new LTDBDatei();
		datei->setDatei( new Text( "data/client/bilder/chat.ltdb" ) );
		datei->leseDaten( 0 );
		schließenBild = datei->laden( 0, new Text( "entfernen.png" ) );
		datei->release();
		bilder->add( "chat.ltdb/entfernen.png", schließenBild->getThis() );
	}
	spieler->addZeile( zeile->getText() );
	spieler->setZeilenHöhe( zeile->getText(), 0 );
	Text *name = infoKlient->getSpielerName( accountId );
	TextFeld *sName = initTextFeld( 0, 0, 110, 20, schrift, TextFeld::Style::Sichtbar | TextFeld::Style::Text | TextFeld::Style::Center, name->getText() );
	name = name->release();
	spieler->setZeichnungZ( "Name", zeile->getText(), sName );
	Knopf *freund = initKnopf( 0, 0, 20, 20, 0, 0, "" );
	freund->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HAlpha | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
	freund->setHintergrundBildZ( einladenBild->getThis() );
	freund->setMausEreignisParameter( this );
	freund->setMausEreignis( chatroomFensterFreundME );
	initToolTip( freund, "Freundeseinladung an den Spieler schicken.", schrift->getThis(), hauptScreen );
	spieler->setZeichnungZ( "Freund", zeile->getText(), freund );
	Knopf *entfernen = initKnopf( 0, 0, 0, 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( schließenBild );
	entfernen->setMausEreignisParameter( this );
	entfernen->setMausEreignis( chatroomFensterEntfernenME );
	initToolTip( entfernen, "Spieler aus Chatroom entfernen.", schrift->getThis(), hauptScreen );
	spieler->setZeichnungZ( "Kick", zeile->getText(), entfernen );
	neueSpieler->add( accountId, neueSpielerAnzahl );
	neueSpielerAnzahl++;
	zeile = zeile->release();
	rend = 1;
}

void ChatroomFenster::removeSpieler( int accountId )
{
	Text *zeile = new Text();
	zeile->anhängen( accountId );
	if( spieler->getZeilenNummer( zeile ) >= 0 )
	{
		alteSpieler->add( accountId, alteSpielerAnzahl );
		alteSpielerAnzahl++;
		rend = 1;
	}
}

bool ChatroomFenster::tick( double tickVal )
{
	rend |= schließen->tick( tickVal );
	rend |= minimieren->tick( tickVal );
	rend |= einladen->tick( tickVal );
	rend |= spieler->tick( tickVal );
	rend |= spielerName->tick( tickVal );
	rend |= verlauf->tick( tickVal );
	rend |= nachricht->tick( tickVal );
	this->tickVal += tickVal * 300;
	int val = ( int )this->tickVal;
	if( val < 1 )
	{
		bool ret = rend;
		rend = 0;
		return ret;
	}
	if( val > 10 )
		val = 10;
	this->tickVal -= val;
	switch( animation )
	{
	case 1: // erstellen
	case 2: // ausfahren
		if( breite == 350 )
		{
			höhe += val;
			if( höhe > 280 )
			{
				höhe = 280;
				animation = 0;
			}
		}
		else
		{
			breite += val;
			if( breite > 350 )
				breite = 350;
		}
		rend = 1;
		break;
	case 3: // einfahren
		if( höhe == 30 )
		{
			breite -= val;
			if( breite < 100 )
			{
				breite = 100;
				animation = 0;
			}
		}
		else
		{
			höhe -= val;
			if( höhe < 30 )
				höhe = 30;
		}
		rend = 1;
		break;
	case 4: // schließen
		if( höhe == 30 )
		{
			breite -= val;
			if( breite < 0 )
			{
				nachLogin->zChatLeiste()->removeChat( this ); // delete this
				return 1;
			}
		}
		else
		{
			höhe -= val;
			if( höhe < 30 )
				höhe = 30;
		}
		rend = 1;
		break;
	}
	Text *zeile = new Text( "" );
	for( int i = 0; i < neueSpielerAnzahl; i++ )
	{
		int id = neueSpieler->hat( i ) ? neueSpieler->get( i ) : 0;
		zeile->anhängen( id );
		int z = spieler->getZeilenNummer( zeile->getText() );
		spieler->setZeilenHöhe( z, spieler->getZeilenHöhe( z ) + val / 2 );
		if( spieler->getZeilenHöhe( z ) > 20 )
		{
			spieler->setZeilenHöhe( z, 20 );
			neueSpieler->lösche( i );
			neueSpielerAnzahl--;
			i--;
		}
		zeile->setText( "" );
		rend = 1;
	}
	for( int i = 0; i < alteSpielerAnzahl; i++ )
	{
		int id = alteSpieler->hat( i ) ? alteSpieler->get( i ) : 0;
		zeile->anhängen( id );
		int z = spieler->getZeilenNummer( zeile->getText() );
		spieler->setZeilenHöhe( z, spieler->getZeilenHöhe( z ) - val / 2 );
		if( spieler->getZeilenHöhe( z ) <= 0 )
		{
			TextFeld *name = (TextFeld*)spieler->zZeichnung( 0, z );
			name = name->release();
			Knopf *freund = (Knopf*)spieler->zZeichnung( 1, z );
			freund = freund->release();
			Knopf *entfernen = (Knopf*)spieler->zZeichnung( 2, z );
			entfernen = entfernen->release();
			spieler->removeZeile( z );
			alteSpieler->lösche( i );
			alteSpielerAnzahl--;
			i--;
		}
		zeile->setText( "" );
		rend = 1;
	}
	zeile = zeile->release();
	if( admin )
	{
		if( spielerName->getHöhe() != 20 )
		{
			spielerName->setGröße( spielerName->getBreite(), spielerName->getHöhe() + val / 2 );
			einladen->setGröße( einladen->getBreite(), einladen->getHöhe() + val / 2 );
			spieler->setPosition( spieler->getX(), spieler->getY() + val / 2 );
			spieler->setGröße( spieler->getBreite(), spieler->getHöhe() - val / 2 );
			if( spielerName->getHöhe() >= 20 )
			{
				spielerName->setGröße( spielerName->getBreite(), 20 );
				einladen->setGröße( einladen->getBreite(), 20 );
				spieler->setPosition( spieler->getX(), 30 );
				spieler->setGröße( spieler->getBreite(), 210 );
			}
			rend = 1;
		}
		if( spieler->getSpaltenBreite( 2 ) != 20 )
		{
			spieler->setSpaltenBreite( 2, spieler->getSpaltenBreite( 2 ) + val / 2 );
			spieler->setSpaltenBreite( 0, spieler->getSpaltenBreite( 0 ) - val / 2 );
			if( spieler->getSpaltenBreite( 2 ) > 20 )
			{
				spieler->setSpaltenBreite( 2, 20 );
				spieler->setSpaltenBreite( 0, 90 );
			}
			rend = 1;
		}
	}
	bool ret = rend;
	rend = 0;
	return ret;
}

void ChatroomFenster::doMausEreignis( MausEreignis &me )
{
	bool tmp = me.verarbeitet;
	if( me.mx < 0 || me.mx > breite || me.my < 280 - höhe || animation )
		me.verarbeitet = 1;
	verlauf->doMausEreignis( me );
	bool vera = me.verarbeitet;
	minimieren->doMausEreignis( me );
	int aktion = me.verarbeitet && !vera ? 1 : 0;
	schließen->doMausEreignis( me );
	if( !aktion )
		aktion = me.verarbeitet && !vera ? 2 : 0;
	einladen->doMausEreignis( me );
	if( !aktion )
		aktion = me.verarbeitet && !vera ? 4 : 0;
	nachricht->doMausEreignis( me );
	spielerName->doMausEreignis( me );
	spieler->doMausEreignis( me );
	if( me.mx < 0 || me.mx > breite || me.my < 280 - höhe || animation )
	{
		me.verarbeitet = tmp;
		return;
	}
	if( !aktion && !sichtbar && !vera )
	{
		if( me.mx < breite && me.mx > 0 && me.my > 250 && me.my < 280 )
			aktion = 3;
	}
	switch( aktion )
	{
	case 1: // einfahren
		if( me.id == ME_RLinks )
			this->setSichtbar( 0 );
		break;
	case 2: // schließen
		if( me.id == ME_RLinks )
			animation = 4;
		break;
	case 3: // ausfahren
		if( me.id == ME_RLinks )
			this->setSichtbar( 1 );
		break;
	case 4: // einladen
		if( me.id != ME_RLinks )
			break;
		if( spielerName->zText()->getLänge() )
		{
			int accountId = infoKlient->getAccountId( spielerName->zText()->getText() );
			if( accountId )
			{
				if( chatKlient->chatroomEinladung( accountId, chatroomId ) )
				{
					nachLogin->zNachrichtenListe()->addNachricht( new Text( "Chatroom Einladung" ), new Text( "Es wurde eine Chatroom Einladung an den Spieler gesendet." ),
																  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
					spielerName->setText( "" );
					spielerName->setAuswahl( 0, 0 );
					rend = 1;
				}
			}
			else
			{
				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Der Spieler wurde nicht gefunden." ),
															  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
			}
		}
		break;
	}
}

void ChatroomFenster::doTastaturEreignis( TastaturEreignis &te )
{
	bool tmp = te.verarbeitet;
	if( animation )
		te.verarbeitet = 1;
	nachricht->doTastaturEreignis( te );
	int aktion = te.verarbeitet && !tmp ? 1 : 0;
	if( admin )
	{
		spielerName->doTastaturEreignis( te );
		if( !aktion )
			aktion = te.verarbeitet && !tmp ? 2 : 0;
	}
	if( animation )
	{
		te.verarbeitet = tmp;
		return;
	}
	switch( aktion )
	{
	case 1:
		if( te.id == TE_Release && te.taste == T_Enter )
		{
			nachricht->zText()->löschen( "\n" );
			chatKlient->chatroomNachricht( chatroomId, nachricht->zText()->getText() );
			nachricht->setText( "" );
			nachricht->setAuswahl( 0, 0 );
			rend = 1;
		}
		break;
	case 2:
		if( te.id == TE_Release && te.taste == T_Enter )
		{
			if( !spielerName->zText()->getLänge() )
				break;
			int accountId = infoKlient->getAccountId( spielerName->zText()->getText() );
			if( accountId )
			{
				if( chatKlient->chatroomEinladung( accountId, chatroomId ) )
				{
					nachLogin->zNachrichtenListe()->addNachricht( new Text( "Chatroom Einladung" ), new Text( "Es wurde eine Chatroom Einladung an den Spieler gesendet." ),
																  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
					spielerName->setText( "" );
					spielerName->setAuswahl( 0, 0 );
					rend = 1;
				}
			}
			else
			{
				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( "Der Spieler wurde nicht gefunden." ),
															  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
			}
		}
		break;
	}
}

void ChatroomFenster::render( int xPos, Bild &zRObj )
{
	int x = xPos;
	int y = 280 - höhe;
	int br = breite;
	int hö = höhe;
	if( !zRObj.setDrawOptions( x, y, br, hö ) )
		return;
	zRObj.alphaRegion( 0, 0, br, hö, 0x88000000 );
	rahmen->setGröße( br, hö );
	rahmen->render( zRObj );
	zRObj.addScrollOffset( 0, 280 - höhe );
	verlauf->render( zRObj );
	nachricht->render( zRObj );
	spieler->render( zRObj );
	name->render( zRObj );
	minimieren->render( zRObj );
	schließen->render( zRObj );
	if( spielerName->getHöhe() )
	{
		spielerName->render( zRObj );
		einladen->render( zRObj );
	}
	zRObj.releaseDrawOptions();
}

bool ChatroomFenster::druckFreund( void *obj, MausEreignis &me )
{
	if( me.id == ME_RLinks )
	{
		Punkt p = spieler->getZeichnungPosition( (Zeichnung*)obj );
		if( p.y >= 0 )
		{
			int accountId = TextZuInt( spieler->zZeilenName( p.y )->getText(), 10 );
			if( chatKlient->freundesAnfrage( accountId ) )
			{
				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Freundes Einladung" ), new Text( "Es wurde eine Freundesanfrage an den Spieler gesendet." ),
															  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
			}
		}
		return 0;
	}
	return 1;
}

bool ChatroomFenster::druckEntfernen( void *obj, MausEreignis &me )
{
	if( me.id == ME_RLinks && admin )
	{
		Punkt p = spieler->getZeichnungPosition( (Zeichnung*)obj );
		if( p.y >= 0 )
		{
			int accountId = TextZuInt( spieler->zZeilenName( p.y )->getText(), 10 );
			if( chatKlient->chatroomKick( chatroomId, accountId ) )
			{
				nachLogin->zNachrichtenListe()->addNachricht( new Text( "Kick" ), new Text( "Der Spieler musste das Chatroom verlassen." ),
															  new Text( "Ok" ), 0, NachrichtType::nachricht, 0 );
			}
		}
		return 0;
	}
	return 1;
}

// constant
int ChatroomFenster::getChatroomId() const
{
	return chatroomId;
}

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

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

// Inhalt der ChatLeisteObj Klasse aus ChatLeiste.h
// Konstruktor
ChatLeisteObj::ChatLeisteObj( Schrift *zSchrift )
	: Zeichnung()
{
	schrift = zSchrift->getThis();
	chats = new RCArray< Chat >();
	hsb = new HScrollBar();
	bildschirmGröße = BildschirmGröße();
	anzahl = 0;
	ref = 1;
	nowME = -1;
}

// Destruktor
ChatLeisteObj::~ChatLeisteObj()
{
	chats = chats->release();
	hsb = hsb->release();
	schrift = schrift->release();
}

// nicht constant
void ChatLeisteObj::chatNachricht( int vonAccount, char *txt )
{
	if( !vonAccount )
		return;
	lockZeichnung();
	bool gefunden = 0;
	for( int i = 0; i < anzahl; i++ )
	{
		Chat *tmp = chats->z( i );
		if( tmp->getAccountId() == vonAccount )
		{
			tmp->addNachricht( txt );
			gefunden = 1;
			break;
		}
	}
	if( !gefunden )
	{
		addChat( vonAccount, 0 );
		chatNachricht( vonAccount, txt );
	}
	unlockZeichnung();
}

void ChatLeisteObj::chatroomNachricht( int chatroomId, char *txt )
{
	lockZeichnung();
	bool gefunden = 0;
	for( int i = 0; i < anzahl; i++ )
	{
		Chat *tmp = chats->z( i );
		if( tmp->getChatroomId() == chatroomId )
		{
			tmp->addNachricht( txt );
			gefunden = 1;
			break;
		}
	}
	if( !gefunden )
	{
		addChat( 0, chatroomId );
		chatroomNachricht( chatroomId, txt );
	}
	unlockZeichnung();
}

void ChatLeisteObj::addChat( int accountId, int chatroomId )
{
	lockZeichnung();
	bool gefunden = 0;
	if( accountId )
	{
		for( int i = 0; i < anzahl; i++ )
		{
			Chat *tmp = chats->z( i );
			if( tmp->getAccountId() == accountId )
			{
				tmp->setSichtbar( 1 );
				gefunden = 1;
				break;
			}
		}
		if( !gefunden )
		{
			ChatFenster *neu = new ChatFenster( schrift, accountId );
			chats->add( neu, anzahl );
			anzahl++;
			rend = 1;
		}
	}
	else if( chatroomId )
	{
		for( int i = 0; i < anzahl; i++ )
		{
			Chat *tmp = chats->z( i );
			if( tmp->getChatroomId() == chatroomId )
			{
				tmp->setSichtbar( 1 );
				gefunden = 1;
				break;
			}
		}
		if( !gefunden )
		{
			ChatroomFenster *neu = new ChatroomFenster( schrift, chatroomId );
			chats->add( neu, anzahl );
			anzahl++;
			rend = 1;
		}
	}
	unlockZeichnung();
}

void ChatLeisteObj::removeChat( int accountId, int chatroomId )
{
	lockZeichnung();
	if( accountId )
	{
		for( int i = 0; i < anzahl; i++ )
		{
			Chat *tmp = chats->z( i );
			if( tmp->getAccountId() == accountId )
				tmp->entfernen();
		}
	}
	else if( chatroomId )
	{
		for( int i = 0; i < anzahl; i++ )
		{
			Chat *tmp = chats->z( i );
			if( tmp->getChatroomId() == chatroomId )
				tmp->entfernen();
		}
	}
	rend = 1;
	unlockZeichnung();
}

void ChatLeisteObj::removeChat( Chat *zChat )
{
	lockZeichnung();
	for( int i = 0; i < anzahl; i++ )
	{
		if( chats->z( i ) == zChat )
		{
			chats->lösche( i );
			anzahl--;
			rend = 1;
			break;
		}
	}
	unlockZeichnung();
}

void ChatLeisteObj::removeAll()
{
	lockZeichnung();
	chats->leeren();
	anzahl = 0;
	rend = 1;
	unlockZeichnung();
}

void ChatLeisteObj::addSpieler( int chatroomId, int accountId )
{
	if( !chatroomId || !accountId )
		return;
	lockZeichnung();
	for( int i = 0; i < anzahl; i++ )
	{
		Chat *tmp = chats->z( i );
		if( tmp->getChatroomId() == chatroomId )
		{
			tmp->addSpieler( accountId );
			break;
		}
	}
	unlockZeichnung();
}

void ChatLeisteObj::removeSpieler( int chatroomId, int accountId )
{
	lockZeichnung();
	if( !chatroomId || !accountId )
		return;
	for( int i = 0; i < anzahl; i++ )
	{
		Chat *tmp = chats->z( i );
		if( tmp->getChatroomId() == chatroomId )
		{
			tmp->removeSpieler( accountId );
			break;
		}
	}
	unlockZeichnung();
}

void ChatLeisteObj::setChatroomAdmin( int chatroomId )
{
	lockZeichnung();
	for( int i = 0; i < anzahl; i++ )
	{
		Chat *tmp = chats->z( i );
		if( tmp->getChatroomId() == chatroomId )
		{
			tmp->setAdmin();
			break;
		}
	}
	unlockZeichnung();
}

bool ChatLeisteObj::tick( double tickVal )
{
	rend |= hsb->getRend();
	rend |= nachLogin->zChatLeiste()->tick( tickVal );
	for( int i = 0; i < anzahl; i++ )
		rend |= chats->z( i )->tick( tickVal );
	bool ret = rend;
	rend = 0;
	return ret;
}

void ChatLeisteObj::doTastaturEreignis( TastaturEreignis &te )
{
	for( int i = 0; i < anzahl; i++ )
		chats->z( i )->doTastaturEreignis( te );
}

void ChatLeisteObj::doMausEreignis( MausEreignis &me )
{
	int mx = me.mx;
	int my = me.my;
	me.my += 250;
	me.mx += hsb->getScrollData()->anzeigeBeginn;
	for( int i = 0; i < anzahl; i++ )
	{
		Chat *tmp = chats->z( i );
		nowME = i;
		tmp->doMausEreignis( me );
		nowME = -1;
		me.mx -= tmp->getBreite();
	}
	me.mx = mx;
	me.my = my;
	hsb->doMausMessage( 1, 30, bildschirmGröße.x - 20, 20, me );
}

void ChatLeisteObj::render( Bild &zRObj )
{
	int x = pos.x;
	int y = pos.y;
	int br = bildschirmGröße.x - 20;
	int hö = 300;
	if( !zRObj.setDrawOptionsErzwingen( x, y - 250, br, hö ) )
		return;
	int breite = 0;
	for( int i = 0; i < anzahl; i++ )
	{
		Chat *tmp = chats->z( i );
		tmp->render( breite - ( hsb ? hsb->getScrollData()->anzeigeBeginn : 0 ), zRObj );
		breite += tmp->getBreite();
	}
	if( hsb )
	{
		hsb->update( breite, bildschirmGröße.x - 22 );
		hsb->render( 0, 280, bildschirmGröße.x - 22, 20, zRObj );
	}
	zRObj.releaseDrawOptions();
}

// constant

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

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

// Inhalt der ChatLeiste Klasse aus ChatLeiste.h
// Konstruktor
ChatLeiste::ChatLeiste( Schrift *zSchrift, Fenster *zNachLoginFenster )
{
	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() );
	}
	bildschirmGröße = BildschirmGröße();
	fenster = initFenster( 20 - bildschirmGröße.x, bildschirmGröße.y - 50, bildschirmGröße.x, 50, 0, Fenster::Style::Sichtbar | Fenster::Style::Erlaubt | Fenster::Style::KörperHintergrund | Fenster::Style::Rahmen, "" );
	fenster->setKBgFarbe( 0xFF000000 );
	minMax = initKnopf( bildschirmGröße.x - 21, 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( chatLeisteMinMaxME );
	initToolTip( minMax, "Chat Leiste minimieren.", zSchrift->getThis(), hauptScreen );
	fenster->addMember( minMax );
	chatLeiste = new ChatLeisteObj( zSchrift );
	fenster->addMember( chatLeiste );
	zNachLoginFenster->addMember( fenster );
	tickVal = 0;
	animation = 1;
	ref = 1;
	rend = 0;
	chatKlient->chatNachrichtAnfrage();
}

// Destruktor
ChatLeiste::~ChatLeiste()
{
	minimierenBild = minimierenBild->release();
	maximierenBild = maximierenBild->release();
	fenster = fenster->release();
	minMax = minMax->release();
	chatLeiste = chatLeiste->release();
}

// nicht constant
void ChatLeiste::chatNachricht( int vonAccount, char *txt )
{
	chatLeiste->chatNachricht( vonAccount, txt );
}

void ChatLeiste::chatroomNachricht( int chatroomId, int vonAccount, char *txt )
{
	chatLeiste->chatroomNachricht( chatroomId, txt );
}

void ChatLeiste::addChat( int accountId, int chatroomId )
{
	chatLeiste->addChat( accountId, chatroomId );
}

void ChatLeiste::removeChat( int accountId, int chatroomId )
{
	chatLeiste->removeChat( accountId, chatroomId );
}

void ChatLeiste::removeChat( Chat *zChat )
{
	chatLeiste->removeChat( zChat );
}

void ChatLeiste::removeAll()
{
	chatLeiste->removeAll();
}

void ChatLeiste::addSpieler( int chatroomId, int accountId )
{
	chatLeiste->addSpieler( chatroomId, accountId );
}

void ChatLeiste::removeSpieler( int chatroomId, int accountId )
{
	chatLeiste->removeSpieler( chatroomId, accountId );
}

void ChatLeiste::setChatroomAdmin( int chatroomId )
{
	chatLeiste->setChatroomAdmin( chatroomId );
}

bool ChatLeiste::tick( double tickVal )
{
	this->tickVal += tickVal * 500;
	int val = ( int )this->tickVal;
	if( val < 1 )
	{
		bool ret = rend;
		rend = 0;
		return ret;
	}
	if( val > 16 )
		val = 16;
	this->tickVal -= val;
	switch( animation )
	{
	case 1: // einfahren
		if( fenster->getX() < 0 )
			fenster->setPosition( fenster->getX() + val, fenster->getY() );
		else
		{
			fenster->setPosition( 0, fenster->getY() );
			animation = 0;
		}
		rend = 1;
		break;
	case 2: // ausfahren
		if( fenster->getX() + fenster->getBreite() > 21 )
			fenster->setPosition( fenster->getX() - val, fenster->getY() );
		else
		{
			fenster->setPosition( 21 - fenster->getBreite(), fenster->getY() );
			animation = 0;
		}
		rend = 1;
		break;
	}
	bool ret = rend;
	rend = 0;
	return ret;
}

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

// constant

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

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

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

bool chatroomFensterFreundME( void *p, void *obj, MausEreignis me )
{
	return ( (ChatroomFenster*)p )->druckFreund( obj, me );
}

bool chatroomFensterEntfernenME( void *p, void *obj, MausEreignis me )
{
	return ( (ChatroomFenster*)p )->druckEntfernen( obj, me );
}