#include "Login.h"
#include <Text.h>
#include <Schrift.h>
#include <TextFeld.h>
#include "..\Server\Patch\PatchServer.h"
#include "..\Version\Version.h"

// Inhalt der AktionThread Klasse aus Login.h
// Konstruktor
AktionThread::AktionThread( int ak, Bildschirm *zScreen, Programm *zProg )
	: Thread()
{
	this->ak = ak;
	zB = zScreen;
	zP = zProg;
	start();
}

// Destruktor
AktionThread::~AktionThread()
{

}

// nicht constant
void AktionThread::thread()
{
	zB->lock();
	switch( ak )
	{
	case 0:
		zP->removeAbschnitt( "Patch Server" );
		zP->removeAbschnitt( "Version" );
		break;
	}
	zB->unlock();
	release();
}


// Inhalt der AdminAccount Klasse aus Login.h
// Konstruktor
AdminAccount::AdminAccount( const char *name, const char *passwort )
{
	this->name = new Text( name );
	this->passwort = new Text( passwort );
	ref = 1;
}

// Destruktor
AdminAccount::~AdminAccount()
{
	name->release();
	passwort->release();
}

// nicht constant
void AdminAccount::login( const char *name, const char *passwort )
{
	this->name = new Text( name );
	this->passwort = new Text( passwort );
}

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

Text *AdminAccount::zName() const
{
	return name;
}

Text *AdminAccount::getPasswort() const
{
	return passwort->getThis();
}

Text *AdminAccount::zPasswort() const
{
	return passwort;
}

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

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


// Inhalt der Login Klasse aus Login.h
// Konstruktor
Login::Login( Schrift *s, Programm *zP, InitDatei *iDat, RessourceBild *resB, Bildschirm *b )
	: Abschnitt( b )
{
	account = 0;
	fenster = 0;
	zProg = zP;
	iD = iDat;
	rB = resB;
	schrift = s;

	f = new Fenster();
	f->setStyle( Fenster::Style::Sichtbar | Fenster::Style::Erlaubt | Fenster::Style::Rahmen | Fenster::Style::Titel | Fenster::Style::TitelBuffered );
	f->setRFarbe( 0xFFFFFFFF );
	f->setRBreite( 1 );
	f->setTitel( "Login" );
	f->setTSchriftZ( s->getThis() );
	f->setTSFarbe( 0xFFFFFFFF );
	f->setTSSize( 12 );
	f->setTAfFarbe( 0x1000FF00 );
	f->setTAfStrength( -15 );
	f->setTRFarbe( 0xFFFFFFFF );
	f->setTRBreite( 1 );
	f->zTTextFeld()->addStyle( TextFeld::Style::Sichtbar | TextFeld::Style::Center | TextFeld::Style::Rahmen );
	f->zTTextFeld()->setSize( 0, 20 );
	f->setSize( 300, 120 );

	logout = new TextFeld();
	logout->setStyle( TextFeld::Style::HCenter );
	logout->setSchriftZ( s->getThis() );
	logout->setSchriftFarbe( 0xFFFFFFFF );
	logout->setSchriftSize( 12 );
	logout->setText( "Möchtest du dich wirklich ausloggen?" );
	logout->setSize( 300, 20 );
	logout->setPosition( 0, 20 );
	f->addMember( logout->getThis() );

	name = new TextFeld();
	name->setStyle( TextFeld::Style::TextFeld );
	name->setSchriftZ( s->getThis() );
	name->setSchriftFarbe( 0xFFFFFFFF );
	name->setSchriftSize( 12 );
	name->setAlphaFeldFarbe( 0x1000FF00 );
	name->setAlphaFeldStrength( -5 );
	name->setTastaturEreignisParameter( this );
	name->setTastaturEreignis( loginNameTastaturEreignis );
	name->setSize( 200, 20 );
	name->setPosition( 50, 10 );
	name->setText( "Name" );
	name->setRahmenFarbe( 0xFFFFFFFF );
	name->setRahmenBreite( 1 );
	f->addMember( name->getThis() );

	passwort = new TextFeld();
	passwort->setStyle( TextFeld::Style::TextFeld );
	passwort->setSchriftZ( s->getThis() );
	passwort->setSchriftFarbe( 0xFFFFFFFF );
	passwort->setSchriftSize( 12 );
	passwort->setAlphaFeldFarbe( 0x1000FF00 );
	passwort->setAlphaFeldStrength( -5 );
	passwort->setTastaturEreignisParameter( this );
	passwort->setTastaturEreignis( loginPasswortTastaturEreignis );
	passwort->setSize( 200, 20 );
	passwort->setPosition( 50, 40 );
	passwort->setText( "Passwort" );
	passwort->setRahmenFarbe( 0xFFFFFFFF );
	passwort->setRahmenBreite( 1 );
	f->addMember( passwort->getThis() );

	login = new Knopf();
	login->setStyle( Knopf::Style::Normal );
	login->setText( "Login" );
	login->setSchriftZ( s->getThis() );
	login->setMausEreignisParameter( this );
	login->setMausEreignis( loginLoginMausEreignis );
	login->setSize( 150, 20 );
	login->setPosition( 75, 70 );
	f->addMember( login->getThis() );

	ref = 1;
}

// Destruktor
Login::~Login()
{
	if( fenster )
		fenster->release();
	f->release();
	name->release();
	passwort->release();
	login->release();
	if( account )
		account->release();
	logout->release();
	iD->release();
	rB->release();
	schrift->release();
}

// nicht constant
void Login::setFenster( Fenster *f )
{
	if( fenster )
		fenster->release();
	this->f->setPosition( f->getBreite() / 2 - 150, f->getHeight() / 2 - 60 );
	fenster = f;
}

void Login::setSichtbar( bool s )
{
	sichtbar = s;
	if( s )
	{
		name->addStyle( TextFeld::Style::Fokus );
		name->setAuswahl( name->zText()->getLength(), 0 );
		fenster->addMember( f->getThis() );
	}
	else
	{
		fenster->removeMember( f );
	}
}

bool Login::nameTastaturEreignis( void *obj, TastaturEreignis te )
{
	if( te.id == TE_Release )
	{
		if( te.taste == T_Enter || te.taste == T_Unten || te.taste == T_Tab )
		{
			name->removeStyle( TextFeld::Style::Fokus );
			passwort->addStyle( TextFeld::Style::Fokus );
			passwort->setAuswahl( passwort->zText()->getLength(), 0 );
		}
	}
	return 1;
}

bool Login::passwortTastaturEreignis( void *obj, TastaturEreignis te )
{
	passwort->setSchowChar( '*' );
	if( te.id == TE_Release )
	{
		if( te.taste == T_Enter )
		{
			passwort->removeStyle( TextFeld::Style::Fokus );
			MausEreignis me;
			me.id = ME_RLinks;
			me.mx = login->getX() + 1;
			me.my = login->getY() + 1;
			me.verarbeitet = 0;
			b->lock();
			login->doMausEreignis( me );
			b->unlock();
		}
	}
	return 1;
}

bool Login::loginMausEreignis( void *obj, MausEreignis me )
{
	if( me.id == ME_RLinks )
	{
		if( f->zTitel()->istGleich( "Login" ) )
		{
            MSKlient *msk = new MSKlient( iD->zWert( "MainServerIP" )->getText(), TextZuInt( iD->zWert( "MainServerPort" )->getText(), 10 ) );
            if( msk->login( name->zText()->getText(), passwort->zText()->getText() ) )
            {
                if( !account )
                    account = new AdminAccount( name->zText()->getText(), passwort->zText()->getText() );
                else
                    account->login( name->zText()->getText(), passwort->zText()->getText() );
                f->setTitel( "Logout" );
                name->removeStyle( TextFeld::Style::Sichtbar );
                passwort->removeStyle( TextFeld::Style::Sichtbar );
                logout->addStyle( TextFeld::Style::Sichtbar );
                login->setText( "Logout" );
                zProg->renameAbschnitt( "Login", "Logout" );
                // Abshnitte erstellen
                PatchServer *psA = new PatchServer( schrift->getThis(), iD->getThis(), msk->getThis(), rB->getThis(), account->getThis(), b->getThis() );
                zProg->addAbschnitt( "Patch Server", psA );
                Version *vA = new Version( schrift->getThis(), msk->getThis(), rB->getThis(), account->getThis(), b->getThis() );
                zProg->addAbschnitt( "Version", vA );
                zProg->abschnittAuswählen( "Patch Server" );
            }
            else
                WMessageBox( 0, new Text( "Fehler" ), new Text( msk->getLetzterFehler() ), MB_ICONERROR );
            msk->release();
		}
		else
		{
			new AktionThread( 0, b, zProg );
			f->setTitel( "Login" );
			name->addStyle( TextFeld::Style::Sichtbar );
			passwort->addStyle( TextFeld::Style::Sichtbar );
			logout->removeStyle( TextFeld::Style::Sichtbar );
			login->setText( "Login" );
			account = account->release();
			zProg->renameAbschnitt( "Logout", "Login" );
			name->setText( "Name" );
			passwort->setText( "Passwort" );
			passwort->setSchowChar( 0 );
		}
	}
	return 1;
}

// constant
AdminAccount *Login::getAccount() const
{
	return account ? account->getThis() : 0;
}

AdminAccount *Login::zAccount() const
{
	return account;
}

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

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

// Ereignisse
bool loginNameTastaturEreignis( void *p, void *obj, TastaturEreignis te )
{
	if( !p )
		return 0;
	return ( (Login*)p )->nameTastaturEreignis( obj, te );
}

bool loginPasswortTastaturEreignis( void *p, void *obj, TastaturEreignis te )
{
	if( !p )
		return 0;
	return ( (Login*)p )->passwortTastaturEreignis( obj, te );
}

bool loginLoginMausEreignis( void *p, void *obj, MausEreignis me )
{
	if( !p )
		return 0;
	return ( (Login*)p )->loginMausEreignis( obj, me );
}