/*
 * SPDX-FileCopyrightText: 2018-2022 Bruce Cowan <bruce@bcowan.me.uk>
 *
 * SPDX-License-Identifier: GPL-3.0-or-later
 */

#include <config.h>

#include "rugby-possibility-widget.h"

struct _RugbyPossibilityWidget
{
    GtkWidget parent_instance;

    GSettings *settings;
    RugbyPossibility *possibility;
};

G_DEFINE_TYPE (RugbyPossibilityWidget, rugby_possibility_widget, GTK_TYPE_WIDGET)

enum
{
    PROP_POSSIBILITY = 1,
    N_PROPS
};

static GParamSpec *properties[N_PROPS];

static void
rugby_possibility_widget_dispose (GObject *object)
{
    RugbyPossibilityWidget *self = RUGBY_POSSIBILITY_WIDGET (object);

    g_clear_object (&self->settings);
    g_clear_object (&self->possibility);

    G_OBJECT_CLASS (rugby_possibility_widget_parent_class)->dispose (object);
}

static void
rugby_possibility_widget_get_property (GObject    *object,
                                       unsigned    prop_id,
                                       GValue     *value,
                                       GParamSpec *pspec)
{
    RugbyPossibilityWidget *self = RUGBY_POSSIBILITY_WIDGET (object);

    switch (prop_id)
    {
        case PROP_POSSIBILITY:
            g_value_set_object (value, self->possibility);
            break;
        default:
            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
}

static void
rugby_possibility_widget_set_property (GObject      *object,
                                       unsigned      prop_id,
                                       const GValue *value,
                                       GParamSpec   *pspec)
{
    RugbyPossibilityWidget *self = RUGBY_POSSIBILITY_WIDGET (object);

    switch (prop_id)
    {
        case PROP_POSSIBILITY:
            self->possibility = g_value_dup_object (value);
            break;
        default:
            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
    }
}

static void
render_bar (GtkSnapshot  *snapshot,
            float         x,
            float         w,
            float         h,
            const GdkRGBA color)
{
    graphene_rect_t area = GRAPHENE_RECT_INIT (x, 0.0, w, h);

    GskRoundedRect rounded;
    gsk_rounded_rect_init_from_rect (&rounded,
                                     &area,
                                     h / 2.0);

    gtk_snapshot_push_rounded_clip (snapshot, &rounded);
    gtk_snapshot_append_color (snapshot,
                               &color,
                               &area);
    gtk_snapshot_pop (snapshot);

    GdkRGBA black = { 0.0, 0.0, 0.0, 0.2 };
    gtk_snapshot_append_border (snapshot,
                                &rounded,
                                (float[]) { 2.0, 2.0, 2.0, 2.0 },
                                (GdkRGBA[]) { black, black, black, black });
}

static void
rugby_possibility_widget_snapshot (GtkWidget   *widget,
                                   GtkSnapshot *snapshot)
{
    RugbyPossibilityWidget *self = RUGBY_POSSIBILITY_WIDGET (widget);

    int try_points = g_settings_get_int (self->settings, "try-points");
    int utry_points = g_settings_get_int (self->settings, "utry-points");
    int kick_points = g_settings_get_int (self->settings, "kick-points");

    int width = gtk_widget_get_width (widget);
    int height = gtk_widget_get_height (widget);
    float x = 0.0;

    int tries, utries, kicks;
    g_object_get (self->possibility,
                  "tries", &tries,
                  "utries", &utries,
                  "kicks", &kicks,
                  NULL);
    int score = tries * try_points + utries * utry_points + kicks * kick_points;

    // Tries
    float w = width / (score / (float) try_points);
    for (int i = 0; i < tries; i++)
    {
        // Green
        render_bar (snapshot, x, w, height,
                    (GdkRGBA) { 0.20, 0.82, 0.48, 1.0 });
        x += w;
    }

    // Unconverted tries
    w = width / (score / (float) utry_points);
    for (int i = 0; i < utries; i++)
    {
        // Red
        render_bar (snapshot, x, w, height,
                    (GdkRGBA) { 0.88, 0.11, 0.14, 1.0 });
        x += w;
    }

    // Unconverted kicks
    w = width / (score / (float) kick_points);
    for (int i = 0; i < kicks; i++)
    {
        // Yellow
        render_bar (snapshot, x, w, height,
                    (GdkRGBA) { 0.96, 0.83, 0.18, 1.0 });
        x += w;
    }
}

static void
rugby_possibility_widget_class_init (RugbyPossibilityWidgetClass *klass)
{
    GObjectClass *object_class = G_OBJECT_CLASS (klass);
    GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);

    object_class->dispose = rugby_possibility_widget_dispose;
    object_class->get_property = rugby_possibility_widget_get_property;
    object_class->set_property = rugby_possibility_widget_set_property;

    widget_class->snapshot = rugby_possibility_widget_snapshot;

    properties[PROP_POSSIBILITY] =
        g_param_spec_object ("possibility", "", "",
                             RUGBY_TYPE_POSSIBILITY,
                             G_PARAM_READWRITE);

    g_object_class_install_properties (object_class,
                                       N_PROPS,
                                       properties);
}

static void
rugby_possibility_widget_init (RugbyPossibilityWidget *self)
{
    self->settings = g_settings_new ("uk.me.bcowan.Rugby");
}