#include "LTSKlient.h"

// Inhalt der LTSKlient Klasse aus LTSKlient.h
// Konstruktor
LTSKlient::LTSKlient( const char *ip, int port )
{
	k = new SSLKlient();
	fehler = new Text( "Keine Verbindung zum Server." );
	this->ip = new Text( ip );
	this->port = port;
	verbunden = 0;
	eingeloggt = 0;
	InitializeCriticalSection( &cs );
	ref = 1;
}

// Destruktor
LTSKlient::~LTSKlient()
{
	if( verbunden )
		trenne();
	k->release();
	ip->release();
	fehler->release();
	DeleteCriticalSection( &cs );
}

// nicht constant
void LTSKlient::lock()
{
	EnterCriticalSection( &cs );
}

void LTSKlient::unlock()
{
	LeaveCriticalSection( &cs );
}

bool LTSKlient::verbinden()
{
	if( verbunden )
		return 1;
	lock();
	bool b = k->verbinde( port, ip->getText() );
	if( !b )
	{
		fehler->setText( "Fehler beim verbinden mit dem Server.\nPort:" );
		fehler->append( port );
		fehler->append( " IP:" );
		fehler->append( ip->getText() );
	}
	verbunden = b;
	eingeloggt = 0;
	unlock();
	return b;
}

bool LTSKlient::login( const char *name, const char *passwort )
{
	if( !verbunden )
		verbinden();
	if( !verbunden )
		return 0;
	lock();
	k->sende( "\1", 1 );
	unsigned char res = 0;
	k->getNachricht( (char*)&res, 1 );
	if( res == 1 )
	{
		unsigned char län = (unsigned char)textLength( name );
		k->sende( (char*)&län, 1 );
		if( län )
			k->sende( name, län );
		län = (unsigned char)textLength( passwort );
		k->sende( (char*)&län, 1 );
		if( län )
			k->sende( passwort, län );
		k->getNachricht( (char*)&res, 1 );
	}
	if( res == 3 )
	{
		k->getNachricht( (char*)&res, 1 );
		char *txt = new char[ res + 1 ];
		k->getNachricht( txt, res );
		txt[ res ] = 0;
		fehler->setText( "Fehler während login beim Server.\nServer Rückgabe:" );
		fehler->append( txt );
		delete[] txt;
	}
	else
	{
		eingeloggt = 1;
		unlock();
		return 1;
	}
	unlock();
	return 0;
}

bool LTSKlient::logout()
{
	if( !verbunden )
		verbinden();
	if( !verbunden )
		return 0;
	lock();
	k->sende( "\2", 1 );
	unsigned char res = 0;
	k->getNachricht( (char*)&res, 1 );
	if( res == 3 )
	{
		k->getNachricht( (char*)&res, 1 );
		char *txt = new char[ res + 1 ];
		k->getNachricht( txt, res );
		txt[ res ] = 0;
		fehler->setText( "Fehler während logout beim Server.\nServer Rückgabe:" );
		fehler->append( txt );
		delete[] txt;
	}
	unlock();
	return res == 1;
}

int LTSKlient::getStatus()
{
	if( !verbunden )
		verbinden();
	if( !verbunden )
		return -1;
	lock();
	k->sende( "\x8", 1 );
	unsigned char res = 0;
	k->getNachricht( (char*)&res, 1 );
	int status = 0;
	if( res == 1 )
	{
		k->getNachricht( (char*)&res, 1 );
		if( res == 1 )
			status = 1;
	}
	else if( res == 3 )
	{
		status = -2;
		k->getNachricht( (char*)&res, 1 );
		char *txt = new char[ res + 1 ];
		k->getNachricht( txt, res );
		txt[ res ] = 0;
		fehler->setText( "Fehler während Status Request beim Server.\nServer Rückgabe:" );
		fehler->append( txt );
		delete[] txt;
	}
	unlock();
	return (int)res;
}

bool LTSKlient::stop()
{
	if( !verbunden )
		verbinden();
	if( !verbunden )
		return 0;
	lock();
	k->sende( "\5", 1 );
	unsigned char res = 0;
	k->getNachricht( (char*)&res, 1 );
	if( res == 3 )
	{
		k->getNachricht( (char*)&res, 1 );
		char *txt = new char[ res + 1 ];
		k->getNachricht( txt, res );
		txt[ res ] = 0;
		fehler->setText( "Fehler während Stoppen beim Server.\nServer Rückgabe:" );
		fehler->append( txt );
		delete[] txt;
	}
	unlock();
	return res == 1;
}

bool LTSKlient::pause()
{
	if( !verbunden )
		verbinden();
	if( !verbunden )
		return 0;
	lock();
	k->sende( "\x9", 1 );
	unsigned char res = 0;
	k->getNachricht( (char*)&res, 1 );
	if( res == 3 )
	{
		k->getNachricht( (char*)&res, 1 );
		char *txt = new char[ res + 1 ];
		k->getNachricht( txt, res );
		txt[ res ] = 0;
		fehler->setText( "Fehler während Pausieren beim Server.\nServer Rückgabe:" );
		fehler->append( txt );
		delete[] txt;
	}
	k->sende( "\1", 1 );
	k->getNachricht( (char*)&res, 1 );
	if( res == 3 )
	{
		k->getNachricht( (char*)&res, 1 );
		char *txt = new char[ res + 1 ];
		k->getNachricht( txt, res );
		txt[ res ] = 0;
		fehler->setText( "Fehler während Pausieren beim Server.\nServer Rückgabe:" );
		fehler->append( txt );
		delete[] txt;
	}
	unlock();
	return res == 1;
}

bool LTSKlient::fortsetzen()
{
	if( !verbunden )
		verbinden();
	if( !verbunden )
		return 0;
	lock();
	k->sende( "\x9", 1 );
	unsigned char res = 0;
	k->getNachricht( (char*)&res, 1 );
	if( res == 3 )
	{
		k->getNachricht( (char*)&res, 1 );
		char *txt = new char[ res + 1 ];
		k->getNachricht( txt, res );
		txt[ res ] = 0;
		fehler->setText( "Fehler während Fortsetzen beim Server.\nServer Rückgabe:" );
		fehler->append( txt );
		delete[] txt;
	}
	k->sende( "\0", 1 );
	k->getNachricht( (char*)&res, 1 );
	if( res == 3 )
	{
		k->getNachricht( (char*)&res, 1 );
		char *txt = new char[ res + 1 ];
		k->getNachricht( txt, res );
		txt[ res ] = 0;
		fehler->setText( "Fehler während Fortsetzen beim Server.\nServer Rückgabe:" );
		fehler->append( txt );
		delete[] txt;
	}
	unlock();
	return res == 1;
}

bool LTSKlient::start()
{
	if( !verbunden )
		verbinden();
	if( !verbunden )
		return 0;
	lock();
	k->sende( "\4", 1 );
	unsigned char res = 0;
	k->getNachricht( (char*)&res, 1 );
	if( res == 3 )
	{
		k->getNachricht( (char*)&res, 1 );
		char *txt = new char[ res + 1 ];
		k->getNachricht( txt, res );
		txt[ res ] = 0;
		fehler->setText( "Fehler während Starten beim Server.\nServer Rückgabe:" );
		fehler->append( txt );
		delete[] txt;
	}
	unlock();
	return res == 1;
}

bool LTSKlient::setMaxTasks( int maxC )
{
	if( !verbunden )
		verbinden();
	if( !verbunden )
		return 0;
	lock();
	k->sende( "\xA", 1 );
	unsigned char res = 0;
	k->getNachricht( (char*)&res, 1 );
	if( res == 3 )
	{
		k->getNachricht( (char*)&res, 1 );
		char *txt = new char[ res + 1 ];
		k->getNachricht( txt, res );
		txt[ res ] = 0;
		fehler->setText( "Fehler während SetMaxClients beim Server.\nServer Rückgabe:" );
		fehler->append( txt );
		delete[] txt;
	}
	k->sende( (char*)&maxC, 4 );
	k->getNachricht( (char*)&res, 1 );
	if( res == 3 )
	{
		k->getNachricht( (char*)&res, 1 );
		char *txt = new char[ res + 1 ];
		k->getNachricht( txt, res );
		txt[ res ] = 0;
		fehler->setText( "Fehler während SetMaxClients beim Server.\nServer Rückgabe:" );
		fehler->append( txt );
		delete[] txt;
	}
	unlock();
	return res == 1;
}

bool LTSKlient::beenden()
{
	if( !verbunden )
		verbinden();
	if( !verbunden )
		return 0;
	lock();
	k->sende( "\6", 1 );
	unsigned char res = 0;
	k->getNachricht( (char*)&res, 1 );
	if( res == 3 )
	{
		k->getNachricht( (char*)&res, 1 );
		char *txt = new char[ res + 1 ];
		k->getNachricht( txt, res );
		txt[ res ] = 0;
		fehler->setText( "Fehler während Beenden beim Server.\nServer Rückgabe:" );
		fehler->append( txt );
		delete[] txt;
	}
	unlock();
	if( res == 1 )
	{
		eingeloggt = 0;
		verbunden = 0;
	}
	return res == 1;
}

bool LTSKlient::terminieren()
{
	if( !verbunden )
		verbinden();
	if( !verbunden )
		return 0;
	lock();
	k->sende( "\7", 1 );
	unsigned char res = 0;
	k->getNachricht( (char*)&res, 1 );
	if( res == 3 )
	{
		k->getNachricht( (char*)&res, 1 );
		char *txt = new char[ res + 1 ];
		k->getNachricht( txt, res );
		txt[ res ] = 0;
		fehler->setText( "Fehler während Terminieren beim Server.\nServer Rückgabe:" );
		fehler->append( txt );
		delete[] txt;
	}
	unlock();
	if( res == 1 )
	{
		eingeloggt = 0;
		verbunden = 0;
	}
	return res == 1;
}

bool LTSKlient::trenne()
{
	if( !verbunden )
		return 1;
	lock();
	k->sende( "\3", 1 );
	unsigned char res = 0;
	k->getNachricht( (char*)&res, 1 );
	if( res == 3 )
	{
		k->getNachricht( (char*)&res, 1 );
		char *txt = new char[ res + 1 ];
		k->getNachricht( txt, res );
		txt[ res ] = 0;
		fehler->setText( "Fehler während Trennen beim Server.\nServer Rückgabe:" );
		fehler->append( txt );
		delete[] txt;
	}
	unlock();
	eingeloggt = 0;
	verbunden = 0;
	k->trenne();
	return res == 1;
}

void LTSKlient::abbruch()
{
	if( verbunden )
		k->trenne();
	eingeloggt = 0;
	verbunden = 0;
}

// constant
bool LTSKlient::istVerbunden() const
{
	return verbunden;
}

bool LTSKlient::istEingeloggt() const
{
	return eingeloggt;
}

const char *LTSKlient::getLetzterFehler() const
{
	return fehler->getText();
}

SSLKlient *LTSKlient::zKlient() const
{
	return k;
}