#include "DLLRegister.h"

using namespace Framework;

// Content of the DLLFiles class from DLLFiles.h
// Constructor
DLLRegister::DLLRegister()
    : ReferenceCounter()
{
    dlls = new Array<DLLFile*>();
}

// Destructor
DLLRegister::~DLLRegister()
{
    cs.lock();
    int anz = dlls->getEntryCount();
    for (int i = 0; i < anz; i++)
    {
        DLLFile* tmp = dlls->get(i);
        if (tmp)
        {
            tmp->name->release();
#ifndef _DEBUG
            FreeLibrary(tmp->handle);
#endif
        }
        delete tmp;
    }
    dlls->release();
    cs.unlock();
}

// non-constant
HINSTANCE DLLRegister::loadDLL(const char* name, const char* pfad)
{
    cs.lock();
    int anz = dlls->getEntryCount();
    for (int i = 0; i < anz; i++)
    {
        DLLFile* tmp = dlls->get(i);
        if (tmp && tmp->name->isEqual(name))
        {
            tmp->ref++;
            cs.unlock();
            return tmp->handle;
        }
    }
    HINSTANCE h = LoadLibrary(pfad);
    if (!h)
    {
        cs.unlock();
        return 0;
    }
    DLLFile* dll = new DLLFile();
    dll->name = new Text(name);
    dll->handle = h;
    dll->ref = 1;
    dlls->add(dll);
    cs.unlock();
    return h;
}

void DLLRegister::releaseDLL(const char* name)
{
    cs.lock();
    int anz = dlls->getEntryCount();
    for (int i = 0; i < anz; i++)
    {
        DLLFile* tmp = dlls->get(i);
        if (tmp && tmp->name->isEqual(name))
        {
            tmp->ref--;
            if (!tmp->ref)
            {
                tmp->name->release();
#ifndef _DEBUG
                FreeLibrary(tmp->handle);
#endif
                delete tmp;
                dlls->remove(i);
            }
            cs.unlock();
            return;
        }
    }
    cs.unlock();
}