#include "GraphicsApi.h"

#include "Bild.h"
#include "Fenster.h"
#include "Model3D.h"
#include "Model3DList.h"

using namespace Framework;

GraphicsApi::GraphicsApi(GraphicApiType typ)
    : ReferenceCounter()
{
    this->typ = typ;
    fenster = 0;
    backBufferSize = Vec2<int>(0, 0);
    fullScreen = 0;
    nextModelId = 0;
    modelList = new Model3DList();
}

GraphicsApi::~GraphicsApi()
{
#ifdef _WIN32
    modelList->release();
    if (fenster) fenster->release();
#endif
}

void GraphicsApi::initialize(
    WFenster* fenster, Vec2<int> backBufferSize, bool fullScreen)
{
#ifdef _WIN32
    if (this->fenster) this->fenster->release();
    this->fenster = fenster;
    if (!backBufferSize.x || !backBufferSize.y)
        backBufferSize = fenster ? fenster->getK�rperGr��e() : Punkt(0, 0);
#endif
    this->backBufferSize = backBufferSize;
    this->fullScreen = fullScreen;
}

void GraphicsApi::setBackBufferSize(Vec2<int> size)
{
    backBufferSize = size;
    update();
}

void GraphicsApi::setFullScreen(bool fullScreen)
{
    this->fullScreen = fullScreen;
    update();
}

void GraphicsApi::beginFrame(bool fill2D, bool fill3D, int fillColor) {}

void GraphicsApi::renderKamera(Kam3D* zKamera) {}

void GraphicsApi::renderKamera(Kam3D* zKamera, Textur* zTarget) {}

Textur* GraphicsApi::createOrGetTextur(const char* name, Bild* b)
{
    if (b) b->release();
    return 0;
}

GraphicApiType GraphicsApi::getTyp() const
{
    return typ;
}

Vec2<int> GraphicsApi::getBackBufferSize() const
{
    return backBufferSize;
}

bool GraphicsApi::isFullScreen() const
{
    return fullScreen;
}

// returns the specified model without increased reference counter
Model3DData* GraphicsApi::zModel(const char* name)
{
    cs.lock();
    Model3DData* data = modelList->zModel(name);
    cs.unlock();
    return data;
}

// returns the specified model with increased reference counter
Model3DData* GraphicsApi::getModel(const char* name)
{
    cs.lock();
    Model3DData* data = modelList->getModel(name);
    cs.unlock();
    return data;
}

// creates a new empty Model3DData object if the model does not exist yet
Model3DData* GraphicsApi::createModel(const char* name)
{
    cs.lock();
    if (modelList->hatModel(name))
    {
        cs.unlock();
        return 0;
    }
    Model3DData* model = new Model3DData(
        createVertexBuffer(), createIndexBuffer(), nextModelId++);
    modelList->addModel(model, name);
    cs.unlock();
    return dynamic_cast<Model3DData*>(model->getThis());
}

// check if a model exists
bool GraphicsApi::hasModel(const char* name)
{
    cs.lock();
    bool res = modelList->hatModel(name);
    cs.unlock();
    return res;
}