/*
 * Copyright (C) 2011 Igalia S.L.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "BrowserCellRendererVariant.h"
#include "BrowserMarshal.h"
#include <errno.h>

enum {
    PROP_0,

    PROP_VALUE,
    PROP_ADJUSTMENT
};

enum {
    CHANGED,

    LAST_SIGNAL
};

struct _BrowserCellRendererVariant {
    GtkCellRenderer parent;

    GValue *value;

    GtkCellRenderer *textRenderer;
    GtkCellRenderer *toggleRenderer;
    GtkCellRenderer *spinRenderer;
};

struct _BrowserCellRendererVariantClass {
    GtkCellRendererClass parent;
};

static guint signals[LAST_SIGNAL] = { 0 };

G_DEFINE_TYPE(BrowserCellRendererVariant, browser_cell_renderer_variant, GTK_TYPE_CELL_RENDERER)

static void browserCellRendererVariantFinalize(GObject *object)
{
    BrowserCellRendererVariant *renderer = BROWSER_CELL_RENDERER_VARIANT(object);

    g_object_unref(renderer->toggleRenderer);
    g_object_unref(renderer->spinRenderer);
    g_object_unref(renderer->textRenderer);
    if (renderer->value)
        g_boxed_free(G_TYPE_VALUE, renderer->value);

    G_OBJECT_CLASS(browser_cell_renderer_variant_parent_class)->finalize(object);
}

static void browserCellRendererVariantGetProperty(GObject *object, guint propId, GValue *value, GParamSpec *pspec)
{
    BrowserCellRendererVariant *renderer = BROWSER_CELL_RENDERER_VARIANT(object);

    switch (propId) {
    case PROP_VALUE:
        g_value_set_boxed(value, renderer->value);
        break;
    case PROP_ADJUSTMENT: {
        GtkAdjustment *adjustment = NULL;
        g_object_get(G_OBJECT(renderer->spinRenderer), "adjustment", &adjustment, NULL);
        if (adjustment) {
            g_value_set_object(value, adjustment);
            g_object_unref(adjustment);
        }
        break;
    }
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec);
    }
}

static void browserCellRendererVariantSetModeForValue(BrowserCellRendererVariant *renderer)
{
    if (!renderer->value)
        return;

    GtkCellRendererMode mode;
    if (G_VALUE_HOLDS_BOOLEAN(renderer->value))
        mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;
    else if (G_VALUE_HOLDS_STRING(renderer->value) || G_VALUE_HOLDS_UINT(renderer->value))
        mode = GTK_CELL_RENDERER_MODE_EDITABLE;
    else
        return;

    g_object_set(G_OBJECT(renderer), "mode", mode, NULL);
}

static void browserCellRendererVariantSetProperty(GObject *object, guint propId, const GValue *value, GParamSpec *pspec)
{
    BrowserCellRendererVariant *renderer = BROWSER_CELL_RENDERER_VARIANT(object);

    switch (propId) {
    case PROP_VALUE:
        if (renderer->value)
            g_boxed_free(G_TYPE_VALUE, renderer->value);
        renderer->value = g_value_dup_boxed(value);
        browserCellRendererVariantSetModeForValue(renderer);
        break;
    case PROP_ADJUSTMENT:
        g_object_set(G_OBJECT(renderer->spinRenderer), "adjustment", g_value_get_object(value), NULL);
        break;
    default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, pspec);
    }
}

static GtkCellRenderer *browserCellRendererVariantGetRendererForValue(BrowserCellRendererVariant *renderer)
{
    if (!renderer->value)
        return NULL;

    if (G_VALUE_HOLDS_BOOLEAN(renderer->value)) {
        g_object_set(G_OBJECT(renderer->toggleRenderer),
                     "active", g_value_get_boolean(renderer->value),
                     NULL);
        return renderer->toggleRenderer;
    }

    if (G_VALUE_HOLDS_STRING(renderer->value)) {
        g_object_set(G_OBJECT(renderer->textRenderer),
                     "text", g_value_get_string(renderer->value),
                     NULL);
        return renderer->textRenderer;
    }

    if (G_VALUE_HOLDS_UINT(renderer->value)) {
        gchar *text = g_strdup_printf("%u", g_value_get_uint(renderer->value));
        g_object_set(G_OBJECT(renderer->spinRenderer), "text", text, NULL);
        g_free(text);
        return renderer->spinRenderer;
    }

    return NULL;
}

static void browserCellRendererVariantCellRendererTextEdited(BrowserCellRendererVariant *renderer, const gchar *path, const gchar *newText)
{
    if (!renderer->value)
        return;

    if (!G_VALUE_HOLDS_STRING(renderer->value))
        return;

    g_value_set_string(renderer->value, newText);
    g_signal_emit(renderer, signals[CHANGED], 0, path, renderer->value);
}

static void browserCellRendererVariantCellRendererSpinEdited(BrowserCellRendererVariant *renderer, const gchar *path, const gchar *newText)
{
    if (!renderer->value)
        return;

    if (!G_VALUE_HOLDS_UINT(renderer->value))
        return;

    GtkAdjustment *adjustment;
    g_object_get(G_OBJECT(renderer->spinRenderer), "adjustment", &adjustment, NULL);
    if (!adjustment)
        return;

    errno = 0;
    gchar *endPtr;
    gdouble value = g_strtod(newText, &endPtr);
    if (errno || value > gtk_adjustment_get_upper(adjustment) || value < gtk_adjustment_get_lower(adjustment) || endPtr == newText) {
        g_warning("Invalid input for cell: %s\n", newText);
        return;
    }

    g_value_set_uint(renderer->value, (guint)value);
    g_signal_emit(renderer, signals[CHANGED], 0, path, renderer->value);
}

static gboolean browserCellRendererVariantCellRendererActivate(GtkCellRenderer *cell, GdkEvent *event, GtkWidget *widget, const gchar *path, const GdkRectangle *bgArea, const GdkRectangle *cellArea, GtkCellRendererState flags)
{
    BrowserCellRendererVariant *renderer = BROWSER_CELL_RENDERER_VARIANT(cell);

    if (!renderer->value)
        return TRUE;

    if (!G_VALUE_HOLDS_BOOLEAN(renderer->value))
        return TRUE;

    g_value_set_boolean(renderer->value, !g_value_get_boolean(renderer->value));
    g_signal_emit(renderer, signals[CHANGED], 0, path, renderer->value);

    return TRUE;
}

#if GTK_CHECK_VERSION(3, 98, 5)
static void browserCellRendererVariantCellRendererSnapshot(GtkCellRenderer *cell, GtkSnapshot *snapshot, GtkWidget *widget, const GdkRectangle *bgArea, const GdkRectangle *cellArea, GtkCellRendererState flags)
{
    GtkCellRenderer *renderer = browserCellRendererVariantGetRendererForValue(BROWSER_CELL_RENDERER_VARIANT(cell));
    if (!renderer)
        return;

    GTK_CELL_RENDERER_GET_CLASS(renderer)->snapshot(renderer, snapshot, widget, bgArea, cellArea, flags);
}
#else
static void browserCellRendererVariantCellRendererRender(GtkCellRenderer *cell, cairo_t *cr, GtkWidget *widget, const GdkRectangle *bgArea, const GdkRectangle *cellArea, GtkCellRendererState flags)
{
    GtkCellRenderer *renderer = browserCellRendererVariantGetRendererForValue(BROWSER_CELL_RENDERER_VARIANT(cell));
    if (!renderer)
        return;

    GTK_CELL_RENDERER_GET_CLASS(renderer)->render(renderer, cr, widget, bgArea, cellArea, flags);
}
#endif

static GtkCellEditable *browserCellRendererVariantCellRendererStartEditing(GtkCellRenderer *cell, GdkEvent *event, GtkWidget *widget, const gchar *path, const GdkRectangle *bgArea, const GdkRectangle *cellArea, GtkCellRendererState flags)
{
    GtkCellRenderer *renderer = browserCellRendererVariantGetRendererForValue(BROWSER_CELL_RENDERER_VARIANT(cell));
    if (!renderer)
        return NULL;

    if (!GTK_CELL_RENDERER_GET_CLASS(renderer)->start_editing)
        return NULL;

    return GTK_CELL_RENDERER_GET_CLASS(renderer)->start_editing(renderer, event, widget, path, bgArea, cellArea, flags);
}

static void browserCellRendererVariantCellRendererGetPreferredWidth(GtkCellRenderer *cell, GtkWidget *widget, gint *minimumWidth, gint *naturalWidth)
{
    GtkCellRenderer *renderer = browserCellRendererVariantGetRendererForValue(BROWSER_CELL_RENDERER_VARIANT(cell));
    if (!renderer)
        return;

    GTK_CELL_RENDERER_GET_CLASS(renderer)->get_preferred_width(renderer, widget, minimumWidth, naturalWidth);
}

static void browserCellRendererVariantCellRendererGetPreferredHeight(GtkCellRenderer *cell, GtkWidget *widget, gint *minimumHeight, gint *naturalHeight)
{
    GtkCellRenderer *renderer = browserCellRendererVariantGetRendererForValue(BROWSER_CELL_RENDERER_VARIANT(cell));
    if (!renderer)
        return;

    GTK_CELL_RENDERER_GET_CLASS(renderer)->get_preferred_height(renderer, widget, minimumHeight, naturalHeight);
}

static void browserCellRendererVariantCellRendererGetPreferredWidthForHeight(GtkCellRenderer *cell, GtkWidget *widget, gint height, gint *minimumWidth, gint *naturalWidth)
{
    GtkCellRenderer *renderer = browserCellRendererVariantGetRendererForValue(BROWSER_CELL_RENDERER_VARIANT(cell));
    if (!renderer)
        return;

    GTK_CELL_RENDERER_GET_CLASS(renderer)->get_preferred_width_for_height(renderer, widget, height, minimumWidth, naturalWidth);
}

static void browserCellRendererVariantCellRendererGetPreferredHeightForWidth(GtkCellRenderer *cell, GtkWidget *widget, gint width, gint *minimumHeight, gint *naturalHeight)
{
    GtkCellRenderer *renderer = browserCellRendererVariantGetRendererForValue(BROWSER_CELL_RENDERER_VARIANT(cell));
    if (!renderer)
        return;

    GTK_CELL_RENDERER_GET_CLASS(renderer)->get_preferred_height_for_width(renderer, widget, width, minimumHeight, naturalHeight);
}

static void browserCellRendererVariantCellRendererGetAlignedArea(GtkCellRenderer *cell, GtkWidget *widget, GtkCellRendererState flags, const GdkRectangle *cellArea, GdkRectangle *alignedArea)
{
    GtkCellRenderer *renderer = browserCellRendererVariantGetRendererForValue(BROWSER_CELL_RENDERER_VARIANT(cell));
    if (!renderer)
        return;

    GTK_CELL_RENDERER_GET_CLASS(renderer)->get_aligned_area(renderer, widget, flags, cellArea, alignedArea);
}

static void browser_cell_renderer_variant_init(BrowserCellRendererVariant *renderer)
{
    g_object_set(renderer, "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);

    renderer->toggleRenderer = gtk_cell_renderer_toggle_new();
    g_object_set(G_OBJECT(renderer->toggleRenderer), "xalign", 0.0, NULL);
    renderer->toggleRenderer = g_object_ref_sink(renderer->toggleRenderer);

    renderer->textRenderer = gtk_cell_renderer_text_new();
    g_signal_connect_swapped(renderer->textRenderer, "edited",
                             G_CALLBACK(browserCellRendererVariantCellRendererTextEdited), renderer);
    g_object_set(G_OBJECT(renderer->textRenderer), "editable", TRUE, NULL);
    renderer->textRenderer = g_object_ref_sink(renderer->textRenderer);

    renderer->spinRenderer = gtk_cell_renderer_spin_new();
    g_signal_connect_swapped(renderer->spinRenderer, "edited",
                             G_CALLBACK(browserCellRendererVariantCellRendererSpinEdited), renderer);
    g_object_set(G_OBJECT(renderer->spinRenderer), "editable", TRUE, NULL);
}

static void browser_cell_renderer_variant_class_init(BrowserCellRendererVariantClass *klass)
{
    GObjectClass *gobjectClass = G_OBJECT_CLASS(klass);
    GtkCellRendererClass *cellRendererClass = GTK_CELL_RENDERER_CLASS(klass);

    gobjectClass->get_property = browserCellRendererVariantGetProperty;
    gobjectClass->set_property = browserCellRendererVariantSetProperty;
    gobjectClass->finalize = browserCellRendererVariantFinalize;

    cellRendererClass->activate = browserCellRendererVariantCellRendererActivate;
#if GTK_CHECK_VERSION(3, 98, 5)
    cellRendererClass->snapshot = browserCellRendererVariantCellRendererSnapshot;
#else
    cellRendererClass->render = browserCellRendererVariantCellRendererRender;
#endif
    cellRendererClass->start_editing = browserCellRendererVariantCellRendererStartEditing;
    cellRendererClass->get_preferred_width = browserCellRendererVariantCellRendererGetPreferredWidth;
    cellRendererClass->get_preferred_height = browserCellRendererVariantCellRendererGetPreferredHeight;
    cellRendererClass->get_preferred_width_for_height = browserCellRendererVariantCellRendererGetPreferredWidthForHeight;
    cellRendererClass->get_preferred_height_for_width = browserCellRendererVariantCellRendererGetPreferredHeightForWidth;
    cellRendererClass->get_aligned_area = browserCellRendererVariantCellRendererGetAlignedArea;

    g_object_class_install_property(gobjectClass,
                                    PROP_VALUE,
                                    g_param_spec_boxed("value",
                                                       "Value",
                                                       "The cell renderer value",
                                                       G_TYPE_VALUE,
                                                       G_PARAM_READWRITE));
    g_object_class_install_property(gobjectClass,
                                    PROP_ADJUSTMENT,
                                    g_param_spec_object("adjustment",
                                                        "Adjustment",
                                                        "The adjustment that holds the value of the spin button",
                                                        GTK_TYPE_ADJUSTMENT,
                                                        G_PARAM_READWRITE));

    signals[CHANGED] =
        g_signal_new("changed",
                     G_TYPE_FROM_CLASS(gobjectClass),
                     G_SIGNAL_RUN_LAST,
                     0, NULL, NULL,
                     browser_marshal_VOID__STRING_BOXED,
                     G_TYPE_NONE, 2,
                     G_TYPE_STRING, G_TYPE_VALUE);
}

GtkCellRenderer *browser_cell_renderer_variant_new(void)
{
    return GTK_CELL_RENDERER(g_object_new(BROWSER_TYPE_CELL_RENDERER_VARIANT, NULL));
}

