#include "GraphicsApi.h"
#include "Fenster.h"
#include "Bild.h"
#include "Model3DList.h"
#include "Model3D.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;
}