#include "Auswahl.h"
#include "../../../Global/Initialisierung.h"
#include "../../../Global/Variablen.h"
#include <DateiSystem.h>
#include <KSGTDatei.h>

// Inhalt der Auswahl Klasse aus Auswahl.h
// Konstruktor
Auswahl::Auswahl( Schrift *zSchrift, KartenEditor *kEditor )
	: Thread()
{
	this->kEditor = kEditor;
	alpha = 255;
	sichtbar = 0;
	suchFilterT = initTextFeld( 10, 10, 70, 20, zSchrift, TextFeld::Style::Text | TextFeld::Style::VCenter, "Suchfilter:" );
	suchFilter = initTextFeld( 90, 10, 210, 20, zSchrift, TextFeld::Style::TextFeld, "" );
	initToolTip( suchFilter, "Gebe etwas vom Namen der Karte ein, nach der du suchst.", zSchrift->getThis(), hauptScreen );
	suchen = initKnopf( 310, 10, 100, 20, zSchrift, Knopf::Style::Sichtbar, "suchen" );
	sortSpalte = initAuswahlBox( 640, 10, 120, 20, zSchrift, ABSTYLE,
	{ "Name", "Spielart", "Preis (Kupfer)", "Verkauft", "Spieleranzahl" } );
	sortRichtung = initAuswahlBox( 770, 10, 120, 20, zSchrift, ABSTYLE, { "Aufsteigend", "Absteigend" } );
	karten = initObjTabelle( 10, 40, 880, 520, zSchrift, OTSTYLE, { { "Name", 220, 220, 220 }, { "Spielart", 220, 220, 220 },
	{ "Kupfer", 130, 130, 130 }, { "Verkauft", 125, 125, 125 }, { "Spieleranzahl", 140, 140, 140 },
	{ "", 20, 20, 20 } }, 20 );
	neuKarteName = initTextFeld( 10, 570, 195, 20, zSchrift, TextFeld::Style::TextFeld, "" );
    initToolTip( neuKarteName, "Name einer neuen Karte", zSchrift->getThis(), hauptScreen );
	neuKarteSpielArt = initAuswahlBox( 215, 570, 195, 20, zSchrift, ABSTYLE, {} );
	neuKarte = initKnopf( 420, 570, 120, 20, zSchrift, Knopf::Style::Sichtbar, "Karte Erstellen" );
	laden = ( Framework::Animation2D* )ladeAnimation->dublizieren();
	laden->setPosition( 425, 275 );
	laden->setSichtbar( 0 );
	schrift = zSchrift->getThis();
	aktion = 0;
	tickVal = 0;
	rend = 0;
	ref = 1;
}

// Destruktor
Auswahl::~Auswahl()
{
	if( run )
		warteAufThread( 1000 );
	if( run )
		ende();
	int anz = karten->getZeilenAnzahl();
	for( int i = 0; i < anz; i++ )
	{
		( (TextFeld*)karten->zZeichnung( 0, i ) )->release();
		( (TextFeld*)karten->zZeichnung( 1, i ) )->release();
		( (TextFeld*)karten->zZeichnung( 2, i ) )->release();
		( (TextFeld*)karten->zZeichnung( 3, i ) )->release();
		( (TextFeld*)karten->zZeichnung( 4, i ) )->release();
		if( !i )
			( (TextFeld*)karten->zZeichnung( 5, i ) )->release();
		else
			( (Knopf*)karten->zZeichnung( 5, i ) )->release();
	}
	laden->release();
	suchFilterT->release();
	suchFilter->release();
	suchen->release();
	sortSpalte->release();
	sortRichtung->release();
	karten->release();
	neuKarteName->release();
	neuKarteSpielArt->release();
	neuKarte->release();
	schrift->release();
	kEditor->release();
}

// nicht constant
void Auswahl::setSichtbar( bool sicht )
{
	sichtbar = sicht;
	if( sichtbar )
	{
		MausEreignis me;
		me.id = ME_RLinks;
		me.verarbeitet = 0;
		me.mx = suchen->getX() + 1;
		me.my = suchen->getY() + 1;
		doMausEreignis( me );
	}
}

void Auswahl::thread()
{
	laden->setSichtbar( 1 );
    if( aktion < 0 )
    {
        int port = 0;
        Text ip = "";
        if( !infoKlient->getEditorServer( 0, &port, &ip ) )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( infoKlient->getLetzterFehler() ), new Text( "Ok" ) );
            aktion = 0;
            laden->setSichtbar( 0 );
            run = 0;
            return;
        }
        bool ok = 0;
        if( editorKlient->verbinde( port, ip ) )
        {
            if( editorKlient->karteErstellen( neuKarteName->zText(), infoKlient->getSpielId( neuKarteSpielArt->zEintrag( neuKarteSpielArt->getAuswahl() )->zText()->getText() ) ) )
                ok = 1;
            editorKlient->trenne();
        }
        if( !ok )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
            aktion = 0;
            laden->setSichtbar( 0 );
            run = 0;
            return;
        }
        aktion = 0;
        laden->setSichtbar( 0 );
        run = 0;
        return;
    }
	if( aktion )
	{
        int port = 0;
        Text ip = "";
        if( !infoKlient->getEditorServer( aktion, &port, &ip ) )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( infoKlient->getLetzterFehler() ), new Text( "Ok" ) );
            aktion = 0;
            laden->setSichtbar( 0 );
            run = 0;
            return;
        }
        bool ok = 0;
        if( editorKlient->verbinde( port, ip ) )
        {
            if( editorKlient->ladeKarte( aktion ) )
                ok = 1;
        }
        if( !ok )
        {
            nachLogin->zNachrichtenListe()->addNachricht( new Text( "Fehler" ), new Text( editorKlient->getLetzterFehler() ), new Text( "Ok" ) );
            aktion = 0;
            laden->setSichtbar( 0 );
            run = 0;
            return;
        }
		kEditor->setKarte( aktion );
		aktion = 0;
		setSichtbar( 0 );
		while( alpha != 0 )
			Sleep( 100 );
		laden->setSichtbar( 0 );
		run = 0;
		return;
	}
	Array< int > *saList = infoKlient->getAccountSpielArtListe();
	if( saList )
	{
		RCArray< Text > *saNamen = new RCArray< Text >();
		int anz = saList->getEintragAnzahl();
		for( int i = 0; i < anz; i++ )
		{
			if( !saList->hat( i ) )
				continue;
			Text *name = infoKlient->getSpielName( saList->hat( i ) ? saList->get( i ) : 0 );
			if( name )
				saNamen->add( name );
		}
		neuKarteSpielArt->lockZeichnung();
		neuKarteSpielArt->setAuswahl( 0 );
		anz = neuKarteSpielArt->getEintragAnzahl();
		for( int i = 0; i < anz; i++ )
			neuKarteSpielArt->löscheEintrag( 0 );
		anz = saNamen->getEintragAnzahl();
		for( int i = 0; i < anz; i++ )
		{
			if( saNamen->z( i ) )
				neuKarteSpielArt->addEintrag( saNamen->z( i )->getText() );
		}
		neuKarteSpielArt->unlockZeichnung();
		saNamen->release();
		saList->release();
	}
	karten->lockZeichnung();
	int anz = karten->getZeilenAnzahl();
	for( int i = 1; i < anz; i++ )
	{
		( (TextFeld*)karten->zZeichnung( 0, 1 ) )->release();
		( (TextFeld*)karten->zZeichnung( 1, 1 ) )->release();
		( (TextFeld*)karten->zZeichnung( 2, 1 ) )->release();
		( (TextFeld*)karten->zZeichnung( 3, 1 ) )->release();
		( (TextFeld*)karten->zZeichnung( 4, 1 ) )->release();
		( (Knopf*)karten->zZeichnung( 5, 1 ) )->release();
		karten->removeZeile( 1 );
	}
	karten->unlockZeichnung();
	Bild *shopWeiter = bilder->get( "shop.ltdb/weiter.png" );
	if( !shopWeiter )
	{
		LTDBDatei *datei = new LTDBDatei();
		datei->setDatei( new Text( "data/client/bilder/shop.ltdb" ) );
		datei->leseDaten( 0 );
		shopWeiter = datei->laden( 0, new Text( "weiter.png" ) );
		datei->release();
		bilder->add( "shop.ltdb/weiter.png", shopWeiter->getThis() );
	}
	Array< int > *kId = new Array< int >();
	RCArray< Text > *kName = new RCArray< Text >();
	RCArray< Text > *saName = new RCArray< Text >();
	Array< int > *kupfer = new Array< int >();
	Array< int > *verkauft = new Array< int >();
	Array< int > *maxSpieler = new Array< int >();
	int kAnz = infoKlient->getKartenListe( suchFilter->zText()->getText(), (char)sortSpalte->getAuswahl(), (char)sortRichtung->getAuswahl(),
										   kId, kName, saName, kupfer, verkauft, maxSpieler );
	for( int i = 0; i < kAnz; i++ )
	{
		Text zeile;
		zeile = kId->get( i );
		karten->addZeile( zeile );
		karten->setZeichnungZ( 0, i + 1, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, kName->z( i )->getText() ) );
		karten->setZeichnungZ( 1, i + 1, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, saName->z( i )->getText() ) );
		karten->setZeichnungZ( 2, i + 1, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, Text() += kupfer->get( i ) ) );
		karten->setZeichnungZ( 3, i + 1, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, Text() += verkauft->get( i ) ) );
		karten->setZeichnungZ( 4, i + 1, initTextFeld( 0, 0, 0, 0, schrift, TextFeld::Style::Text | TextFeld::Style::VCenter, Text() += maxSpieler->get( i ) ) );
		Knopf *weiter = initKnopf( 0, 0, 0, 0, schrift, 0, "" );
		weiter->setStyle( Knopf::Style::Sichtbar | Knopf::Style::Erlaubt | Knopf::Style::Hintergrund | Knopf::Style::HBild | Knopf::Style::KlickBuffer );
		weiter->setHintergrundBildZ( shopWeiter->getThis() );
		weiter->setMausEreignisParameter( this );
		weiter->setMausEreignis( auswahlWeiterME );
		karten->setZeichnungZ( 5, i + 1, weiter );
	}
	kId->release();
	kName->release();
	saName->release();
	kupfer->release();
	verkauft->release();
	maxSpieler->release();
	shopWeiter->release();
	laden->setSichtbar( 0 );
	run = 0;
}

bool Auswahl::weiterME( Zeichnung *obj, MausEreignis &me )
{
	if( me.id != ME_RLinks )
		return 1;
	karten->lockZeichnung();
	int anz = karten->getZeilenAnzahl();
	for( int i = 1; i < anz; i++ )
	{
		if( karten->zZeichnung( 5, i ) == obj )
		{
            aktion = *karten->zZeilenName( i );
			start();
		}
	}
	karten->unlockZeichnung();
	return 1;
}

void Auswahl::doMausEreignis( MausEreignis &me )
{
	if( !sichtbar || run )
		return;
	suchFilter->doMausEreignis( me );
	bool vera = me.verarbeitet;
	suchen->doMausEreignis( me );
	if( !vera && me.verarbeitet && me.id == ME_RLinks )
	{
		aktion = 0;
		start();
	}
	int ausw = sortSpalte->getAuswahl();
	sortSpalte->doMausEreignis( me );
	if( ausw != sortSpalte->getAuswahl() )
	{
		aktion = 0;
		start();
        sortSpalte->einklappen();
	}
	ausw = sortRichtung->getAuswahl();
	sortRichtung->doMausEreignis( me );
	if( ausw != sortRichtung->getAuswahl() )
	{
		aktion = 0;
		start();
        sortRichtung->einklappen();
	}
	karten->doMausEreignis( me );
	neuKarteName->doMausEreignis( me );
	neuKarteSpielArt->doMausEreignis( me );
    vera = me.verarbeitet;
    neuKarte->doMausEreignis( me );
    if( !vera && me.verarbeitet && me.id == ME_RLinks )
    {
        aktion = -1;
        start();
    }
}

void Auswahl::doTastaturEreignis( TastaturEreignis &te )
{
	if( !sichtbar || run )
		return;
	bool vera = te.verarbeitet;
	suchFilter->doTastaturEreignis( te );
	if( !vera && te.verarbeitet && te.taste == T_Enter && te.id == TE_Release )
	{
		MausEreignis me;
		me.id = ME_RLinks;
		me.verarbeitet = 0;
		me.mx = suchen->getX() + 1;
		me.my = suchen->getY() + 1;
		doMausEreignis( me );
	}
	neuKarteName->doTastaturEreignis( te );
}

bool Auswahl::tick( double zeit )
{
	tickVal += zeit * 250;
	int val = (int)tickVal;
	if( val < 1 )
	{
		bool ret = rend;
		rend = 0;
		return ret;
	}
	if( val > 10 )
		val = 10;
	rend |= sortSpalte->tick( zeit );
	rend |= sortRichtung->tick( zeit );
	rend |= neuKarteSpielArt->tick( zeit );
	rend |= laden->tick( zeit );
	rend |= suchFilterT->tick( zeit );
	rend |= suchFilter->tick( zeit );
	rend |= suchen->tick( zeit );
	rend |= karten->tick( zeit );
	rend |= neuKarteName->tick( zeit );
	rend |= neuKarte->tick( zeit );
	if( sichtbar && alpha != 255 && !run )
	{
		if( alpha + val > 255 )
			alpha = 255;
		else
			alpha += val;
		rend = 1;
	}
	if( sichtbar && alpha != 125 && run )
	{
		if( alpha > 125 )
		{
			if( alpha - val < 125 )
				alpha = 125;
			else
				alpha -= val;
			rend = 1;
		}
		else
		{
			if( alpha + val > 125 )
				alpha = 125;
			else
				alpha += 125;
			rend = 1;
		}
	}
	if( !sichtbar && alpha != 0 )
	{
		if( alpha - val < 0 )
			alpha = 0;
		else
			alpha -= val;
		rend = 1;
	}
	bool ret = rend;
	rend = 0;
	return ret;
}

void Auswahl::render( Bild &zRObj )
{
	if( !alpha )
		return;
	zRObj.setAlpha( alpha );
	suchFilterT->render( zRObj );
	suchFilter->render( zRObj );
	suchen->render( zRObj );
	karten->render( zRObj );
	neuKarteName->render( zRObj );
	neuKarte->render( zRObj );
	neuKarteSpielArt->render( zRObj );
	sortSpalte->render( zRObj );
	sortRichtung->render( zRObj );
	zRObj.releaseAlpha();
	laden->render( zRObj );
}

// constant
bool Auswahl::istSichtbar() const
{
	return sichtbar;
}

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

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


// Ereignisse
bool auswahlWeiterME( void *p, void *obj, MausEreignis me )
{
	if( p )
		return ( (Auswahl*)p )->weiterME( (Zeichnung*)obj, me );
	return 1;
}