/* -*-c-*- -------------- mixgtk_colorsel.c :
 * Implementation of the functions declared in mixgtk_colorsel.h
 * ------------------------------------------------------------------
 *  Last change: Time-stamp: "2001-04-22 01:54:20 jao"
 * ------------------------------------------------------------------
 * Copyright (C) 2001 Free Software Foundation, Inc.
 *  
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *  
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *  
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *  
 */

#include <mixlib/mix.h>
#include "mixgtk_widgets.h"
#include "mixgtk_mixal.h"
#include "mixgtk_colorsel.h"

/* types of line colors */
#define LNO_ 3
/* colors per line */
#define ZNO_ 2


static GtkWidget *color_dialog_ = NULL;
static const char *anames_[LNO_][ZNO_] = {
  {"bpbg_area", "bpfg_area"},
  {"clbg_area", "clfg_area"},
  {"plbg_area", "plfg_area"}
};

typedef struct 
{
  GtkWidget *area;
  gboolean changed;
  GdkColor color;
} area_id_t;

static area_id_t areas_[LNO_][ZNO_];
static area_id_t *current_ = NULL;

static GtkWidget *colorseldlg_ = NULL;


void
mixgtk_colorsel_init (void)
{
  color_dialog_ = NULL;
  colorseldlg_ = NULL;
  current_ = NULL;
}

static void
set_area_color_ (GtkWidget *area, const GdkColor *color)
{
  static GdkColor gdk_color;
  
  GdkColormap *colormap = gdk_window_get_colormap (area->window);                     

  g_assert (area);
  g_assert (color);
  
  gdk_color.red = color->red;
  gdk_color.green = color->green;
  gdk_color.blue = color->blue;
  gdk_color_alloc (colormap, &gdk_color);                                       
  gdk_window_set_background (area->window, &gdk_color);                  
  gdk_window_clear (area->window);
  gtk_widget_draw (area, FALSE);
}



/* drawingarea event handler */                                                 
static gint
area_event_(GtkWidget *widget, GdkEvent  *event, gpointer areaid)
{                                                                               
  /* Check if we've received a button pressed event */                          
  if (event->type == GDK_BUTTON_PRESS)                   
    {                                               
      current_ = (area_id_t *)areaid;
      /* Show the dialog */                                                     
      gtk_widget_show (colorseldlg_);                                             
    }                                                                           
  return FALSE;                                                               
}                                                                               

/* initialise the color selection dialog */
static void
init_colorsel_ (void)
{
  int i, j;
  color_dialog_ = mixgtk_widget_factory_get_dialog (MIXGTK_COLOR_DIALOG);
  g_assert (color_dialog_ != NULL);
  colorseldlg_ = mixgtk_widget_factory_get_dialog (MIXGTK_COLORSEL_DIALOG);
  g_assert (colorseldlg_ != NULL);
  for (i = 0; i < LNO_; ++i)
    for (j = 0; j < ZNO_; ++j)
      {
	areas_[i][j].area =
	  mixgtk_widget_factory_get_child_by_name
	  (MIXGTK_COLOR_DIALOG, anames_[i][j]);
	g_assert (areas_[i][j].area != NULL);
	areas_[i][j].changed = FALSE;
	gtk_widget_set_events (areas_[i][j].area, GDK_BUTTON_PRESS_MASK);
	gtk_signal_connect (GTK_OBJECT(areas_[i][j].area), "event",
			    (GtkSignalFunc)area_event_,
			    (gpointer)&areas_[i][j]);
	
      }
}

/* gtk callbacks */
void
on_colors_activate (GtkWidget *w, gpointer p)
{
  int i, j;

  /* must show widget before changing its colors */
  if (!color_dialog_) init_colorsel_ ();
  gtk_widget_show (color_dialog_);

  for (i = 0; i < LNO_; ++i)
    for (j = 0; j < ZNO_; ++j)
      {
	areas_[i][j].changed = FALSE;
  	set_area_color_ (areas_[i][j].area, mixgtk_mixal_get_color (i, j));
      }
  current_ = NULL;
}

void
on_ok_colorseldlg_clicked (GtkWidget *widget, gpointer data)
{                                                                               
  static gdouble color[3];
  GtkWidget *colorsel = GTK_COLOR_SELECTION_DIALOG (colorseldlg_)->colorsel;
  gtk_widget_hide (colorseldlg_);
  /* Get current color */                     
  gtk_color_selection_get_color (GTK_COLOR_SELECTION (colorsel), color);
  /* Fit to a unsigned 16 bit integer (0..65535) and
   * insert into the GdkColor structure */
  current_->color.red = (guint16)(color[0]*65535.0);
  current_->color.green = (guint16)(color[1]*65535.0);
  current_->color.blue = (guint16)(color[2]*65535.0);
  set_area_color_ (current_->area, &current_->color);
  current_->changed = TRUE;
}                                                                               

void
on_cancel_colorseldlg_clicked (GtkWidget *widget, gpointer data)
{
  gtk_widget_hide (colorseldlg_);
}

void
on_colors_apply_clicked (GtkWidget *widget, gpointer data)
{
  int i, j;
  for (i = 0; i < LNO_; ++i)
    for (j = 0; j < ZNO_; ++j)
      {
	if (areas_[i][j].changed)
	  mixgtk_mixal_set_color (i, j, &areas_[i][j].color);
      }
}

void
on_colors_ok_clicked (GtkWidget *widget, gpointer data)
{
  on_colors_apply_clicked (widget, data);
  gtk_widget_hide (color_dialog_);
}

void
on_colors_cancel_clicked (GtkWidget *widget, gpointer data)
{
  gtk_widget_hide (color_dialog_);
}