#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <glib.h>
#include <gtk/gtk.h>
#include <gdk/gdk.h>
#include "customcurve.h"
#include "../../common/looperdata.h"

#define WIDTH 320
#define HEIGHT 240

void customcurve_update(GtkWidget* curve, looper_data_t* looperdata){
	looperdata_lock(looperdata);
	gtk_curve_get_vector ((GtkCurve*)curve,
		looperdata->cm_size,looperdata->customplaymode);
	looperdata_unlock(looperdata);
}

GtkWidget* customcurvedialog_get_curve(GtkWidget* dialog){
	return g_object_get_data (G_OBJECT (dialog),"curve");
}


static void menu_callback(GtkMenuItem* menuitem, GtkWidget* curve){
	gtk_curve_set_curve_type((GtkCurve*)curve,
		GPOINTER_TO_UINT(g_object_get_data (G_OBJECT(menuitem),"mode")));
}

static void normalize_callback(GtkMenuItem* menuitem, GtkWidget* curve){
	int 	j = WIDTH;
	int 	i;
	float* 	buf;
	float 	f = 0.0f;

	buf = malloc(sizeof(float) * j);
	gtk_curve_get_vector ((GtkCurve*)curve, j, buf);
	for (i=0; i < j; i++){
		f += 1.0f / *(buf + i);
	}
	f /= (float)j;
	for (i=0; i < j; i++){
                 *(buf + i) *= f;
        }
	gtk_curve_set_vector ((GtkCurve*)curve, j, buf);
	free(buf);
}

static void reset_customspeed_callback(GtkMenuItem* menuitem, GtkWidget* curve){
        int     j = WIDTH;
        int     i;
        float*  buf;

        buf = malloc(sizeof(float) * j);
        for (i=0; i < j; i++)
                 *(buf + i) = 1.;
        gtk_curve_set_vector ((GtkCurve*)curve, j, buf);
        free(buf);
}

static void reset_custompos_callback(GtkMenuItem* menuitem, GtkWidget* curve){
        int     j = WIDTH;
        int     i;
        float*  buf;

        buf = malloc(sizeof(float) * j);
        for (i=0; i < j; i++)
		*(buf + i) = (float)i / (float)j * 4.999; /* bad magic number */
		
        gtk_curve_set_vector ((GtkCurve*)curve, j, buf);
	gtk_curve_set_curve_type((GtkCurve*)curve,GTK_CURVE_TYPE_LINEAR);
        free(buf);
}

GtkWidget* customcurvedialog_new(GtkWidget* parent, looper_data_t* data, int id){
        GtkWidget       *label1;
	GtkWidget	*customcurve;
	GtkWidget	*dialog;
	GtkWidget	*topmenu;
	GtkWidget	*menu;
	GtkWidget	*menu_items;
	GtkWidget	*menubar;
	GSList 		*group = NULL;
	

	label1 = gtk_label_new ("custom curve");

	customcurve = gtk_curve_new();
	gtk_curve_set_range ((GtkCurve*)customcurve,0., WIDTH, data->cm_min, data->cm_max);
	gtk_widget_set_size_request (customcurve, WIDTH, HEIGHT);

	topmenu = gtk_menu_item_new_with_label ("drawing options");
 	menu = gtk_menu_new ();
        menu_items = gtk_radio_menu_item_new_with_label (group,"curve");
        group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menu_items));
        g_object_set_data (G_OBJECT (menu_items), 
		"mode",GUINT_TO_POINTER(GTK_CURVE_TYPE_SPLINE));
        gtk_check_menu_item_set_active ((GtkCheckMenuItem*)menu_items,FALSE);
        g_signal_connect (G_OBJECT (menu_items), "activate",
                                                G_CALLBACK (menu_callback),
                                                (gpointer)customcurve);
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_items);


        menu_items =  gtk_radio_menu_item_new_with_label (group,"free");
        group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menu_items));
        gtk_check_menu_item_set_active ((GtkCheckMenuItem*)menu_items,TRUE);
        g_object_set_data (G_OBJECT (menu_items), 
		"mode",GUINT_TO_POINTER(GTK_CURVE_TYPE_FREE));
        g_signal_connect (G_OBJECT (menu_items), "activate",
                                                G_CALLBACK (menu_callback),
                                                (gpointer)customcurve);
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_items);

	menu_items =  gtk_radio_menu_item_new_with_label (group,"linear");
        group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (menu_items));
        gtk_check_menu_item_set_active ((GtkCheckMenuItem*)menu_items,FALSE);
        g_object_set_data (G_OBJECT (menu_items),
                "mode",GUINT_TO_POINTER(GTK_CURVE_TYPE_LINEAR));
        g_signal_connect (G_OBJECT (menu_items), "activate",
                                                G_CALLBACK (menu_callback),
                                                (gpointer)customcurve);
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_items);

	menu_items = gtk_separator_menu_item_new();
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_items);

	menu_items =  gtk_menu_item_new_with_label ("normalize");
        g_signal_connect (G_OBJECT (menu_items), "activate",
                                                G_CALLBACK (normalize_callback),
                                                (gpointer)customcurve);
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_items);

	menu_items =  gtk_menu_item_new_with_label ("reset custom speed");
        g_signal_connect (G_OBJECT (menu_items), "activate",
                                                G_CALLBACK (reset_customspeed_callback),
                                                (gpointer)customcurve);
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_items);

        menu_items =  gtk_menu_item_new_with_label ("reset custom position");
        g_signal_connect (G_OBJECT (menu_items), "activate",
                                                G_CALLBACK (reset_custompos_callback),
                                                (gpointer)customcurve);
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_items);



	gtk_menu_item_set_submenu (GTK_MENU_ITEM (topmenu), menu);
	menubar = gtk_menu_bar_new();
	gtk_menu_shell_append(GTK_MENU_SHELL(menubar), topmenu);
	
	dialog = gtk_dialog_new_with_buttons ("drawing area for custom modes",
                        (GtkWindow*)parent,
                        GTK_DIALOG_DESTROY_WITH_PARENT,
			GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);

	g_object_set_data (G_OBJECT (dialog),"curve",customcurve);
	gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),label1);
	gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),customcurve);
	gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox),menubar);

	gtk_widget_show_all (dialog);
	gtk_curve_set_vector (GTK_CURVE(customcurve),
		data->cm_size,data->customplaymode);
	if (!(data->playmode == LOOP_PLAYMODE_POSITION))
		gtk_curve_set_curve_type((GtkCurve*)customcurve,GTK_CURVE_TYPE_FREE);
	else 
		gtk_curve_set_curve_type((GtkCurve*)customcurve,GTK_CURVE_TYPE_LINEAR);

	gtk_window_set_modal ((GtkWindow*)dialog, FALSE);

	return (dialog);	
}

