#include "Patcher.h"
#include <Text.h>
#include "../Global/Variablen.h"

typedef UpdaterV *( *GetUpdater )( );

// Inhalt der Patcher Klasse aus Patcher.h
// Konstruktor
Patcher::Patcher()
{
	updater = 0;
	updateDll = 0;
	läuft = 0;
	ref = 1;
}

// Destruktor
Patcher::~Patcher()
{
	if( updater )
		updater->release();
	if( updateDll )
		FreeLibrary( updateDll );
}

// nicht constant
bool Patcher::update( int dateiGruppe, bool *abbruch, FBalken *fortschritt, TextFeld *status, Text *zError )
{
	if( läuft )
	{
		zError->setText( "Es kann nur ein Update zur Zeit herruntergeladen werden." );
		fortschritt->release();
		status->release();
		return 0;
	}
	läuft = 1;
	if( !updater )
	{
		if( !updateDll )
		    updateDll = dllDateien->ladeDLL("update.dll","data/bin/update.dll" );
		if( !updateDll )
		{
			updater = 0;
			zError->setText( "Die DLL Datei 'data/bin/update.dll' wurde nicht gefunden." );
		}
		else
		{
			GetUpdater getUpdater = (GetUpdater)GetProcAddress( updateDll, "getUpdater" );
			if( !getUpdater )
			{
				updater = 0;
				zError->setText( "Der Einstiegspunkt 'getUpdater' konnte in der DLL Datei 'data/bin/update.dll' nicht gefunden." );
			}
			else
				updater = getUpdater();
		}
	}
	if( !updater )
	{
		fortschritt->release();
		status->release();
		läuft = 0;
		return 0;
	}
	UpdateParams p;
	p.abbruch = abbruch;
	p.dateiGruppe = dateiGruppe;
	p.zFortschritt = fortschritt;
	p.zStatus = status;
	int ret = updater->update( &p );
	fortschritt->release();
	status->release();
	if( ret == 1 )
		zError->setText( updater->getError() );
	läuft = 0;
	return ret != 1;
}

// constant
bool Patcher::läuftPatch() const
{
	return läuft;
}

int Patcher::getDownload() const
{
	return updater ? updater->getDownload() : 0;
}

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

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