#include "FactoryClient.h"

using namespace Network;

FactoryClient::FactoryClient()
{
    client = 0;
    background = 0;
    foreground = 0;
    backgroundReader = 0;
    foregroundReader = 0;
    bgReaderUsage = 0;
    fgReaderUsage = 0;
}

FactoryClient::~FactoryClient()
{
    if( client )
        disconnect();
}

bool FactoryClient::connect( Text ip, short port, int accountId, Text secret )
{
    if( client )
        disconnect();
    client = new SSLKlient();
    if( !client->verbinde( port, ip ) )
        return false;
    if( !client->sende( "\1", 1 ) )
        return false;
    if( !client->sende( (char*)&accountId, 4 ) )
        return false;
    unsigned char len = (unsigned char)secret.getLength();
    if( !client->sende( (char*)&len, 1 ) )
        return false;
    if( !client->sende( secret, len ) )
        return false;
    char result = 0;
    if( !client->getNachricht( &result, 1 ) || result != 1 )
        return false;
    int keyLen;
    if( !client->getNachricht( (char*)&keyLen, 4 ) )
        return false;
    char* key = new char[ keyLen ];
    if( !client->getNachricht( key, keyLen ) )
        return false;
    int p;
    if( !client->getNachricht( (char*)&p, 4 ) )
        return false;
    foreground = new Klient();
    if( !foreground->verbinde( p, ip ) )
        return false;
    unsigned short l = (unsigned short)keyLen;
    if( !foreground->sende( (char*)&l, 2 ) )
        return false;
    if( !foreground->sende( key, keyLen ) )
        return false;
    bool bg = 0;
    if( !foreground->sende( (char*)&bg, 1 ) )
        return false;
    foregroundReader = new NetworkReader( foreground );
    background = new Klient();
    if( !background->verbinde( p, ip ) )
        return false;
    if( !background->sende( (char*)&l, 2 ) )
        return false;
    if( !background->sende( key, keyLen ) )
        return false;
    bg = 1;
    if( !background->sende( (char*)&bg, 1 ) )
        return false;
    backgroundReader = new NetworkReader( background );
    client->trenne();
    return true;
}

void FactoryClient::disconnect()
{
    if( client )
    {
        NetworkReader* fgReader = foregroundReader;
        NetworkReader* bgReader = backgroundReader;
        backgroundReader = 0;
        foregroundReader = 0;
        if( foreground )
            foreground->trenne();
        if( background )
            background->trenne();
        while( fgReaderUsage > 0 || bgReaderUsage > 0 )
            Sleep( 100 );
        delete fgReader;
        delete bgReader;
        client->release();
        client = 0;
        if( foreground )
            foreground->release();
        foreground = 0;
        if( background )
            background->release();
        background = 0;
    }
}

NetworkReader* FactoryClient::getNextForegroundMessage()
{
    fgReaderUsage++;
    if( !foreground )
        return 0;
    if( !foreground->hatNachricht( 0 ) )
        return 0;
    return foregroundReader;
}

NetworkReader* FactoryClient::getNextBackgroundMessage()
{
    bgReaderUsage++;
    if( !background )
        return 0;
    if( !background->hatNachricht( 0 ) )
        return 0;
    return backgroundReader;
}

void FactoryClient::endMessageReading( bool bg )
{
    if( bg )
        bgReaderUsage--;
    else
        fgReaderUsage--;
}

void FactoryClient::sendPlayerAction( void* data, unsigned short length )
{
    if( !foreground )
        return;
    cs.lock();
    length += 1;
    foreground->sende( (char*)&length, 2 );
    char msgId = 2;
    foreground->sende( &msgId, 1 );
    foreground->sende( (char*)data, length - 1 );
    cs.unlock();
}