#include <gui/progress_bar.h>
#include <gui.h>
#include <gui_private.h>
#include <gfx.h>

static short progress_width(const struct gui_progress_bar *const pb)
{
    return pb->progress ? ((short)pb->progress * pb->w)
        / (short)GUI_PROGRESS_BAR_MAX : 0;
}

static void set_fg_params(const struct gui_progress_bar *const pb,
    struct rect *const r, const short x, const short y)
{
    r->x = x;
    r->y = y;
    r->w = progress_width(pb);
    r->h = pb->h;
    r->r = pb->fg.r;
    r->g = pb->fg.g;
    r->b = pb->fg.b;
}

static void set_bg_params(const struct gui_progress_bar *const pb,
    struct rect *const r, const short x, const short y)
{
    const short w = progress_width(pb);

    r->x = x + w;
    r->y = y;
    r->w = pb->w - w;
    r->h = pb->h;
    r->r = pb->bg.r;
    r->g = pb->bg.g;
    r->b = pb->bg.b;
}

static int render_common(const struct gui_progress_bar *const pb,
    const short x, const short y, void (*init)(struct rect *))
{
    {
        rect_get_or_ret(fg, -1);
        init(fg);
        set_fg_params(pb, fg, x, y);
        rect_sort(fg);
    }

    {
        rect_get_or_ret(bg, -1);
        init(bg);
        set_bg_params(pb, bg, x, y);
        rect_sort(bg);
    }

    return 0;
}

static int render_op(const struct gui_progress_bar *const pb,
    const short x, const short y)
{
    return render_common(pb, x, y, rect_init);
}

static int render_stp(const struct gui_progress_bar *const pb,
    const short x, const short y)
{
    return render_common(pb, x, y, semitrans_rect_init);
}

static int render(const struct gui_common *const g)
{
    const struct gui_progress_bar *const pb =
        (const struct gui_progress_bar *)g;
    short x, y;

    gui_coords(&pb->common, &x, &y);

    if (pb->stp)
        return render_stp(pb, x, y);

    return render_op(pb, x, y);
}

void gui_progress_bar_init(struct gui_progress_bar *const pb)
{
    static const struct gui_common_cb cb =
    {
        .render = render
    };

    *pb = (const struct gui_progress_bar)
    {
        .common =
        {
            .cb = &cb
        }
    };
}
