/* colorsel.c
 * geg, a GTK+ Equation Grapher
 * David Bryant 1998
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif /* HAVE_CONFIG_H */

#include <glib.h>
#include <string.h>
#include "colorsel.h"
#include "prefs.h"
#include "i18n.h"

extern struct_prefs prefs;

/* locally global data */
static GtkWidget *wi = NULL;
static GtkColorSelectionDialog *di;
static GtkColorSelection *cs;
static gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data);
static void ok_event(GtkWidget *widget, gpointer data);
static void cancel_event(GtkWidget *widget, gpointer data);

/* delete_event, deletes the colorselection dialog window, called when       */
/* dialog is closed by window manager                                        */
static gint
delete_event(GtkWidget *widget, GdkEvent *event, gpointer data)
{
  gtk_widget_destroy(wi);
  wi = NULL;
  return(TRUE);
}

/* cancel_event, much the same as delete_event, called by cancel button      */
static void
cancel_event(GtkWidget *widget, gpointer data)
{
  gtk_widget_destroy(wi);
  wi = NULL;
}

/* ok_event, gets the color selection dialog's selected color and puts it in */
/* the preview widget, then it closes the dialog, it is the callback function*/
/* for the OK button                                                         */
static void
ok_event(GtkWidget *widget, gpointer data)
{
  GtkWidget *preview;
  GdkColor color;
  gdouble values[3];
  
  preview = (GtkWidget *)data;

  gtk_color_selection_get_current_color(cs, &color);
  values[0] = color.red / 65535.0;
  values[1] = color.green / 65535.0;  
  values[2] = color.blue / 65535.0;

  if (prefs.cur_color == DEF_GRAY_COLOR || 
      prefs.cur_color == DEF_GRAY_COLOR + 1) {
    values[0] = (values[0] +  values[1] +  values[2]) / 3.0;
    values[2] = values[1] = values[0];
  }
  show_color_in_preview(preview, values);

  gtk_widget_destroy(wi);
  wi = NULL;
}

/* colorsel_event, brings up a color selector dialog and sets the color   */
/* to be the cuurent color                                                */
/* called by the little "..." buttons to the left of the preview          */
void
colorsel_event(GtkWidget *widget, gpointer data)
{
  GtkWidget *preview;

  if(wi)
    gtk_widget_destroy(wi);

  preview = (GtkWidget *)data;

  wi = gtk_color_selection_dialog_new(_("Select color"));
  gtk_signal_connect(GTK_OBJECT(wi), "delete_event", GTK_SIGNAL_FUNC(delete_event), NULL);

  /* setup window properties */
  gtk_window_set_wmclass(GTK_WINDOW(wi), "color_selection", "Geg");
  gtk_window_set_policy(GTK_WINDOW(wi), FALSE, FALSE, FALSE);
  gtk_window_position(GTK_WINDOW(wi), GTK_WIN_POS_NONE);

  di = GTK_COLOR_SELECTION_DIALOG(wi);
  cs = GTK_COLOR_SELECTION(di->colorsel);

  /* hide the help button as we wont be using it */
  gtk_widget_hide(GTK_WIDGET(di->help_button));

  gtk_signal_connect(GTK_OBJECT(di->ok_button), "clicked", GTK_SIGNAL_FUNC(ok_event), preview);
  gtk_signal_connect(GTK_OBJECT(di->cancel_button), "clicked", GTK_SIGNAL_FUNC(cancel_event), NULL);

  gtk_color_selection_set_color(cs, &prefs.rgb_value[3*prefs.cur_color]);

  gtk_widget_show(wi);
  gtk_grab_add(wi);
}

/* show_color_in_preview, paints the preview with the color specified by   */
/* the values and stores the values as data in preview's object              */
/* this function called explicitly when the user clicks OK in the color      */
/* selection dialog, and when the preferences dialog is being constructed    */
void
show_color_in_preview(GtkWidget *preview, gdouble values[])
{
  gint i, j, k;
  gint width, height;
  guchar *row;

  width = preview->allocation.width;
  height = preview->allocation.height;

  row = (guchar *)g_malloc(3 * width * sizeof(guchar));

  for(i = 0; i < height; i++) {
    for(j = 0, k = 0; j < width; j++) {
      row[k] = (guchar)(values[0] * 255);
      row[k + 1] = (guchar)(values[1] * 255);
      row[k + 2] = (guchar)(values[2] * 255);
      k += 3;
    }
    gtk_preview_draw_row(GTK_PREVIEW(preview), row, 0, i, width);
  }

  gtk_widget_queue_draw(preview);

  g_free(row);

  memcpy(&prefs.rgb_value[3*prefs.cur_color], values, 3 * sizeof(gdouble));
}
