/*
 * Copyright 2012, Red Hat, Inc.
 * Copyright 2012, Soren Sandmann
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Author: Soren Sandmann <soren.sandmann@gmail.com>
 */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#include <gtk/gtk.h>
#include <pixman.h>
#include <stdlib.h>
#include "gtk-utils.h"

typedef struct
{
    GtkBuilder *        builder;
    pixman_image_t *	original;
    GtkAdjustment *     scale_x_adjustment;
    GtkAdjustment *     scale_y_adjustment;
    GtkAdjustment *     rotate_adjustment;
    GtkAdjustment *	subsample_adjustment;
    int                 scaled_width;
    int                 scaled_height;
} app_t;

static GtkWidget *
get_widget (app_t *app, const char *name)
{
    GtkWidget *widget = GTK_WIDGET (gtk_builder_get_object (app->builder, name));

    if (!widget)
        g_error ("Widget %s not found\n", name);

    return widget;
}

/* Figure out the boundary of a diameter=1 circle transformed into an ellipse
 * by trans. Proof that this is the correct calculation:
 *
 * Transform x,y to u,v by this matrix calculation:
 *
 *  |u|   |a c| |x|
 *  |v| = |b d|*|y|
 *
 * Horizontal component:
 *
 *  u = ax+cy (1)
 *
 * For each x,y on a radius-1 circle (p is angle to the point):
 *
 *  x^2+y^2 = 1
 *  x = cos(p)
 *  y = sin(p)
 *  dx/dp = -sin(p) = -y
 *  dy/dp = cos(p) = x
 *
 * Figure out derivative of (1) relative to p:
 *
 *  du/dp = a(dx/dp) + c(dy/dp)
 *        = -ay + cx
 *
 * The min and max u are when du/dp is zero:
 *
 *  -ay + cx = 0
 *  cx = ay
 *  c = ay/x  (2)
 *  y = cx/a  (3)
 *
 * Substitute (2) into (1) and simplify:
 *
 *  u = ax + ay^2/x
 *    = a(x^2+y^2)/x
 *    = a/x (because x^2+y^2 = 1)
 *  x = a/u (4)
 *
 * Substitute (4) into (3) and simplify:
 *
 *  y = c(a/u)/a
 *  y = c/u (5)
 *
 * Square (4) and (5) and add:
 *
 *  x^2+y^2 = (a^2+c^2)/u^2
 *
 * But x^2+y^2 is 1:
 *
 *  1 = (a^2+c^2)/u^2
 *  u^2 = a^2+c^2
 *  u = hypot(a,c)
 *
 * Similarily the max/min of v is at:
 *
 *  v = hypot(b,d)
 *
 */
static void
compute_extents (pixman_f_transform_t *trans, double *sx, double *sy)
{
    *sx = hypot (trans->m[0][0], trans->m[0][1]) / trans->m[2][2];
    *sy = hypot (trans->m[1][0], trans->m[1][1]) / trans->m[2][2];
}

typedef struct
{
    char	name [20];
    int		value;
} named_int_t;

static const named_int_t filters[] =
{
    { "Box",			PIXMAN_KERNEL_BOX },
    { "Impulse",		PIXMAN_KERNEL_IMPULSE },
    { "Linear",			PIXMAN_KERNEL_LINEAR },
    { "Cubic",			PIXMAN_KERNEL_CUBIC },
    { "Lanczos2",		PIXMAN_KERNEL_LANCZOS2 },
    { "Lanczos3",		PIXMAN_KERNEL_LANCZOS3 },
    { "Lanczos3 Stretched",	PIXMAN_KERNEL_LANCZOS3_STRETCHED },
    { "Gaussian",		PIXMAN_KERNEL_GAUSSIAN },
};

static const named_int_t repeats[] =
{
    { "None",                   PIXMAN_REPEAT_NONE },
    { "Normal",                 PIXMAN_REPEAT_NORMAL },
    { "Reflect",                PIXMAN_REPEAT_REFLECT },
    { "Pad",                    PIXMAN_REPEAT_PAD },
};

static int
get_value (app_t *app, const named_int_t table[], const char *box_name)
{
    GtkComboBox *box = GTK_COMBO_BOX (get_widget (app, box_name));

    return table[gtk_combo_box_get_active (box)].value;
}

static void
copy_to_counterpart (app_t *app, GObject *object)
{
    static const char *xy_map[] =
    {
	"reconstruct_x_combo_box", "reconstruct_y_combo_box",
	"sample_x_combo_box",      "sample_y_combo_box",
	"scale_x_adjustment",      "scale_y_adjustment",
    };
    GObject *counterpart = NULL;
    int i;

    for (i = 0; i < G_N_ELEMENTS (xy_map); i += 2)
    {
	GObject *x = gtk_builder_get_object (app->builder, xy_map[i]);
	GObject *y = gtk_builder_get_object (app->builder, xy_map[i + 1]);

	if (object == x)
	    counterpart = y;
	if (object == y)
	    counterpart = x;
    }

    if (!counterpart)
	return;
    
    if (GTK_IS_COMBO_BOX (counterpart))
    {
	gtk_combo_box_set_active (
	    GTK_COMBO_BOX (counterpart),
	    gtk_combo_box_get_active (
		GTK_COMBO_BOX (object)));
    }
    else if (GTK_IS_ADJUSTMENT (counterpart))
    {
	gtk_adjustment_set_value (
	    GTK_ADJUSTMENT (counterpart),
	    gtk_adjustment_get_value (
		GTK_ADJUSTMENT (object)));
    }
}

static double
to_scale (double v)
{
    return pow (1.15, v);
}

static void
rescale (GtkWidget *may_be_null, app_t *app)
{
    pixman_f_transform_t ftransform;
    pixman_transform_t transform;
    double new_width, new_height;
    double fscale_x, fscale_y;
    double rotation;
    pixman_fixed_t *params;
    int n_params;
    double sx, sy;

    pixman_f_transform_init_identity (&ftransform);

    if (may_be_null && gtk_toggle_button_get_active (
	    GTK_TOGGLE_BUTTON (get_widget (app, "lock_checkbutton"))))
    {
	copy_to_counterpart (app, G_OBJECT (may_be_null));
    }
    
    fscale_x = gtk_adjustment_get_value (app->scale_x_adjustment);
    fscale_y = gtk_adjustment_get_value (app->scale_y_adjustment);
    rotation = gtk_adjustment_get_value (app->rotate_adjustment);

    fscale_x = to_scale (fscale_x);
    fscale_y = to_scale (fscale_y);
    
    new_width = pixman_image_get_width (app->original) * fscale_x;
    new_height = pixman_image_get_height (app->original) * fscale_y;

    pixman_f_transform_scale (&ftransform, NULL, fscale_x, fscale_y);

    pixman_f_transform_translate (&ftransform, NULL, - new_width / 2.0, - new_height / 2.0);

    rotation = (rotation / 360.0) * 2 * M_PI;
    pixman_f_transform_rotate (&ftransform, NULL, cos (rotation), sin (rotation));

    pixman_f_transform_translate (&ftransform, NULL, new_width / 2.0, new_height / 2.0);

    pixman_f_transform_invert (&ftransform, &ftransform);

    compute_extents (&ftransform, &sx, &sy);
    
    pixman_transform_from_pixman_f_transform (&transform, &ftransform);
    pixman_image_set_transform (app->original, &transform);

    params = pixman_filter_create_separable_convolution (
        &n_params,
        sx * 65536.0 + 0.5,
	sy * 65536.0 + 0.5,
	get_value (app, filters, "reconstruct_x_combo_box"),
	get_value (app, filters, "reconstruct_y_combo_box"),
	get_value (app, filters, "sample_x_combo_box"),
	get_value (app, filters, "sample_y_combo_box"),
	gtk_adjustment_get_value (app->subsample_adjustment),
	gtk_adjustment_get_value (app->subsample_adjustment));

    pixman_image_set_filter (app->original, PIXMAN_FILTER_SEPARABLE_CONVOLUTION, params, n_params);

    pixman_image_set_repeat (
        app->original, get_value (app, repeats, "repeat_combo_box"));
    
    free (params);

    app->scaled_width = ceil (new_width);
    app->scaled_height = ceil (new_height);
    
    gtk_widget_set_size_request (
        get_widget (app, "drawing_area"), new_width + 0.5, new_height + 0.5);

    gtk_widget_queue_draw (
        get_widget (app, "drawing_area"));
}

static gboolean
on_expose (GtkWidget *da, GdkEvent *event, gpointer data)
{
    app_t *app = data;
    GdkRectangle *area = &event->expose.area;
    cairo_surface_t *surface;
    pixman_image_t *tmp;
    cairo_t *cr;
    uint32_t *pixels;

    pixels = calloc (1, area->width * area->height * 4);
    tmp = pixman_image_create_bits (
        PIXMAN_a8r8g8b8, area->width, area->height, pixels, area->width * 4);

    if (area->x < app->scaled_width && area->y < app->scaled_height)
    {
        pixman_image_composite (
            PIXMAN_OP_SRC,
            app->original, NULL, tmp,
            area->x, area->y, 0, 0, 0, 0,
            app->scaled_width - area->x, app->scaled_height - area->y);
    }

    surface = cairo_image_surface_create_for_data (
        (uint8_t *)pixels, CAIRO_FORMAT_ARGB32,
        area->width, area->height, area->width * 4);

    cr = gdk_cairo_create (da->window);

    cairo_set_source_surface (cr, surface, area->x, area->y);

    cairo_paint (cr);

    cairo_destroy (cr);
    cairo_surface_destroy (surface);
    free (pixels);
    pixman_image_unref (tmp);

    return TRUE;
}

static void
set_up_combo_box (app_t *app, const char *box_name,
                  int n_entries, const named_int_t table[])
{
    GtkWidget *widget = get_widget (app, box_name);
    GtkListStore *model;
    GtkCellRenderer *cell;
    int i;

    model = gtk_list_store_new (1, G_TYPE_STRING);
    
    cell = gtk_cell_renderer_text_new ();
    gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (widget), cell, TRUE);
    gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (widget), cell,
				    "text", 0,
				    NULL);

    gtk_combo_box_set_model (GTK_COMBO_BOX (widget), GTK_TREE_MODEL (model));
    
    for (i = 0; i < n_entries; ++i)
    {
	const named_int_t *info = &(table[i]);
	GtkTreeIter iter;

	gtk_list_store_append (model, &iter);
	gtk_list_store_set (model, &iter, 0, info->name, -1);
    }

    gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0);

    g_signal_connect (widget, "changed", G_CALLBACK (rescale), app);
}

static void
set_up_filter_box (app_t *app, const char *box_name)
{
    set_up_combo_box (app, box_name, G_N_ELEMENTS (filters), filters);
}

static char *
format_value (GtkWidget *widget, double value)
{
    return g_strdup_printf ("%.4f", to_scale (value));
}

static app_t *
app_new (pixman_image_t *original)
{
    GtkWidget *widget;
    app_t *app = g_malloc (sizeof *app);
    GError *err = NULL;

    app->builder = gtk_builder_new ();
    app->original = original;

    if (!gtk_builder_add_from_file (app->builder, "scale.ui", &err))
	g_error ("Could not read file scale.ui: %s", err->message);

    app->scale_x_adjustment =
        GTK_ADJUSTMENT (gtk_builder_get_object (app->builder, "scale_x_adjustment"));
    app->scale_y_adjustment =
        GTK_ADJUSTMENT (gtk_builder_get_object (app->builder, "scale_y_adjustment"));
    app->rotate_adjustment =
        GTK_ADJUSTMENT (gtk_builder_get_object (app->builder, "rotate_adjustment"));
    app->subsample_adjustment =
	GTK_ADJUSTMENT (gtk_builder_get_object (app->builder, "subsample_adjustment"));

    g_signal_connect (app->scale_x_adjustment, "value_changed", G_CALLBACK (rescale), app);
    g_signal_connect (app->scale_y_adjustment, "value_changed", G_CALLBACK (rescale), app);
    g_signal_connect (app->rotate_adjustment, "value_changed", G_CALLBACK (rescale), app);
    g_signal_connect (app->subsample_adjustment, "value_changed", G_CALLBACK (rescale), app);
    
    widget = get_widget (app, "scale_x_scale");
    gtk_scale_add_mark (GTK_SCALE (widget), 0.0, GTK_POS_LEFT, NULL);
    g_signal_connect (widget, "format_value", G_CALLBACK (format_value), app);
    widget = get_widget (app, "scale_y_scale");
    gtk_scale_add_mark (GTK_SCALE (widget), 0.0, GTK_POS_LEFT, NULL);
    g_signal_connect (widget, "format_value", G_CALLBACK (format_value), app);
    widget = get_widget (app, "rotate_scale");
    gtk_scale_add_mark (GTK_SCALE (widget), 0.0, GTK_POS_LEFT, NULL);

    widget = get_widget (app, "drawing_area");
    g_signal_connect (widget, "expose_event", G_CALLBACK (on_expose), app);

    set_up_filter_box (app, "reconstruct_x_combo_box");
    set_up_filter_box (app, "reconstruct_y_combo_box");
    set_up_filter_box (app, "sample_x_combo_box");
    set_up_filter_box (app, "sample_y_combo_box");

    set_up_combo_box (
        app, "repeat_combo_box", G_N_ELEMENTS (repeats), repeats);

    g_signal_connect (
	gtk_builder_get_object (app->builder, "lock_checkbutton"),
	"toggled", G_CALLBACK (rescale), app);
    
    rescale (NULL, app);
    
    return app;
}

int
main (int argc, char **argv)
{
    GtkWidget *window;
    pixman_image_t *image;
    app_t *app;
    
    gtk_init (&argc, &argv);

    if (argc < 2)
    {
	printf ("%s <image file>\n", argv[0]);
	return -1;
    }

    if (!(image = pixman_image_from_file (argv[1], PIXMAN_a8r8g8b8)))
    {
	printf ("Could not load image \"%s\"\n", argv[1]);
	return -1;
    }

    app = app_new (image);
    
    window = get_widget (app, "main");

    g_signal_connect (window, "delete_event", G_CALLBACK (gtk_main_quit), NULL);
    
    gtk_window_set_default_size (GTK_WINDOW (window), 1024, 768);
    
    gtk_widget_show_all (window);
    
    gtk_main ();

    return 0;
}
