#include "ace/Guard_T.h"
#include "ace/Thread_Mutex.h"

#include <assert.h>
#include "vn_renderer.h"
#include "Renderer.h"

struct vn_renderer_context_t
{
    videonext::media::Renderer *renderer;    
    ACE_Thread_Mutex *lock;
};

vn_renderer_context_t *vn_renderer_create(void *window)
{
    vn_renderer_context_t *ctx = 0;

    videonext::media::Renderer *renderer = new videonext::media::Renderer();

    if (renderer->init(window) == -1)
    {
        delete renderer;
        return 0;
    }
    
    ctx = (vn_renderer_context_t *)calloc(1, sizeof(vn_renderer_context_t));
    if (ctx)
    {
        ctx->renderer = renderer;
        ctx->lock = new ACE_Thread_Mutex();
    }
    else
    {
        delete renderer;
    }

    return ctx;
}

VN_PLAYER_PIXEL_FORMAT vn_renderer_get_preferred_pixel_format(vn_renderer_context_t *ctx)
{
    assert(ctx);
    return ctx->renderer->get_preferred_pixel_format(); 
}

int vn_renderer_process(vn_renderer_context_t *ctx,
                        const vn_player_frame_t *frame)
{
    assert(ctx);

    ACE_Guard<ACE_Thread_Mutex> guard(*ctx->lock);

    return ctx->renderer->process(frame); 
}

int vn_renderer_paint(vn_renderer_context_t *ctx, VN_IMAGE_FILL_MODE mode, struct vn_image_calibration_t *ic, struct vn_image_pan_zoom_t *pz)
{
    assert(ctx);

    if (ctx->lock->tryacquire() == -1)
        return 0;

    int ret = ctx->renderer->draw(mode, ic, pz);
    
    ctx->lock->release();

    return ret;
}

void vn_renderer_destroy(vn_renderer_context_t *ctx)
{
    assert(ctx);

    delete ctx->renderer;
    delete ctx->lock;
    
    free(ctx);
}

