#include "DLLDateien.h"

// Inhalt der DLLDateien Klasse aus DLLDateien.h
// Konstruktor
DLLDateien::DLLDateien()
{
	dlls = new Array< DLLDatei* >();
	ref = 1;
}

// Destruktor
DLLDateien::~DLLDateien()
{
    cs.lock();
	int anz = dlls->getEintragAnzahl();
	for( int i = 0; i < anz; i++ )
	{
		DLLDatei *tmp = dlls->get( i );
		if( tmp )
		{
			tmp->name->release();
			FreeLibrary( tmp->handle );
		}
		delete tmp;
	}
	dlls->release();
    cs.unlock();
}

// nicht constant
HINSTANCE DLLDateien::ladeDLL( char *name, char *pfad )
{
    cs.lock();
	int anz = dlls->getEintragAnzahl();
	for( int i = 0; i < anz; i++ )
	{
		DLLDatei *tmp = dlls->get( i );
		if( tmp && tmp->name->istGleich( name ) )
		{
			tmp->ref++;
            cs.unlock();
			return tmp->handle;
		}
	}
	HINSTANCE h = LoadLibrary( pfad );
	if( !h )
		return 0;
	DLLDatei *dll = new DLLDatei();
	dll->name = new Text( name );
	dll->handle = h;
	dll->ref = 1;
	dlls->add( dll );
    cs.unlock();
	return h;
}

void DLLDateien::releaseDLL( char *name )
{
    cs.lock();
	int anz = dlls->getEintragAnzahl();
	for( int i = 0; i < anz; i++ )
	{
		DLLDatei *tmp = dlls->get( i );
		if( tmp && tmp->name->istGleich( name ) )
		{
			tmp->ref--;
			if( !tmp->ref )
			{
				tmp->name->release();
				FreeLibrary( tmp->handle );
				delete tmp;
				dlls->remove( i );
			}
            cs.unlock();
			return;
		}
	}
    cs.unlock();
}

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

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