/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) version 3.
 *
 * 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with the program; if not, see <http://www.gnu.org/licenses/>  
 *
 *
 * Authors:
 *		Srinivasa Ragavan <sragavan@novell.com>
 *
 * Copyright (C) 2009 Novell, Inc. (www.novell.com)
 *
 */

#include <glib-object.h>
#include <glib/gi18n.h>
#include "custom-cell-renderer-toggle-pixbuf.h"

static void custom_cell_renderer_toggle_pixbuf_get_property  (GObject                    *object,
						    guint                       param_id,
						    GValue                     *value,
						    GParamSpec                 *pspec);
static void custom_cell_renderer_toggle_pixbuf_set_property  (GObject                    *object,
						    guint                       param_id,
						    const GValue               *value,
						    GParamSpec                 *pspec);
static void custom_cell_renderer_toggle_pixbuf_get_size   (GtkCellRenderer            *cell,
						 GtkWidget                  *widget,
 						 GdkRectangle               *cell_area,
						 gint                       *x_offset,
						 gint                       *y_offset,
						 gint                       *width,
						 gint                       *height);
static void custom_cell_renderer_toggle_pixbuf_render     (GtkCellRenderer            *cell,
						 GdkWindow                  *window,
						 GtkWidget                  *widget,
						 GdkRectangle               *background_area,
						 GdkRectangle               *cell_area,
						 GdkRectangle               *expose_area,
						 GtkCellRendererState        flags);
static gboolean custom_cell_renderer_toggle_pixbuf_activate  (GtkCellRenderer            *cell,
						    GdkEvent                   *event,
						    GtkWidget                  *widget,
						    const gchar                *path,
						    GdkRectangle               *background_area,
						    GdkRectangle               *cell_area,
						    GtkCellRendererState        flags);


enum {
  TOGGLED,
  LAST_SIGNAL
};

enum {
  PROP_0,
  PROP_ACTIVE,
};

static guint toggle_cell_signals[LAST_SIGNAL] = { 0 };

#define CUSTOM_CELL_RENDERER_TOGGLE_PRIVATE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), CUSTOM_TYPE_CELL_RENDERER_TOGGLE_PIXBUF, CustomCellRendererTogglePixbufPrivate))

typedef struct _CustomCellRendererTogglePixbufPrivate CustomCellRendererTogglePixbufPrivate;
struct _CustomCellRendererTogglePixbufPrivate
{
	GdkPixbuf *active;
	GdkPixbuf *inactive;
};


G_DEFINE_TYPE (CustomCellRendererTogglePixbuf, custom_cell_renderer_toggle_pixbuf, GTK_TYPE_CELL_RENDERER)

static void
custom_cell_renderer_toggle_pixbuf_init (CustomCellRendererTogglePixbuf *celltoggle)
{
  CustomCellRendererTogglePixbufPrivate *priv;

  priv = CUSTOM_CELL_RENDERER_TOGGLE_PRIVATE_GET_PRIVATE (celltoggle);

  celltoggle->active = FALSE;

  GTK_CELL_RENDERER (celltoggle)->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;
  GTK_CELL_RENDERER (celltoggle)->xpad = 2;
  GTK_CELL_RENDERER (celltoggle)->ypad = 2;

}

static void
custom_cell_renderer_toggle_pixbuf_class_init (CustomCellRendererTogglePixbufClass *class)
{
  GObjectClass *object_class = G_OBJECT_CLASS (class);
  GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (class);

  object_class->get_property = custom_cell_renderer_toggle_pixbuf_get_property;
  object_class->set_property = custom_cell_renderer_toggle_pixbuf_set_property;

  cell_class->get_size = custom_cell_renderer_toggle_pixbuf_get_size;
  cell_class->render = custom_cell_renderer_toggle_pixbuf_render;
  cell_class->activate = custom_cell_renderer_toggle_pixbuf_activate;
  
  g_object_class_install_property (object_class,
				   PROP_ACTIVE,
				   g_param_spec_boolean ("active",
							 _("Toggle state"),
							 _("The toggle state of the button"),
							 FALSE,
							 G_PARAM_READWRITE|G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));

 
  /**
   * CustomCellRendererTogglePixbuf::toggled:
   * @cell_renderer: the object which received the signal
   * @path: string representation of #GtkTreePath describing the 
   *        event location
   *
   * The ::toggled signal is emitted when the cell is toggled. 
   **/
  toggle_cell_signals[TOGGLED] =
    g_signal_new (_("toggled"),
		  G_OBJECT_CLASS_TYPE (object_class),
		  G_SIGNAL_RUN_LAST,
		  G_STRUCT_OFFSET (CustomCellRendererTogglePixbufClass, toggled),
		  NULL, NULL,
		  g_cclosure_marshal_VOID__STRING,
		  G_TYPE_NONE, 1,
		  G_TYPE_STRING);

  g_type_class_add_private (object_class, sizeof (CustomCellRendererTogglePixbufPrivate));
}

static void
custom_cell_renderer_toggle_pixbuf_get_property (GObject     *object,
				       guint        param_id,
				       GValue      *value,
				       GParamSpec  *pspec)
{
  CustomCellRendererTogglePixbuf *celltoggle = CUSTOM_CELL_RENDERER_TOGGLE_PIXBUF(object);
  CustomCellRendererTogglePixbufPrivate *priv;

  priv = CUSTOM_CELL_RENDERER_TOGGLE_PRIVATE_GET_PRIVATE (object);
  
  switch (param_id)
    {
    case PROP_ACTIVE:
      g_value_set_boolean (value, celltoggle->active);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
      break;
    }
}


static void
custom_cell_renderer_toggle_pixbuf_set_property (GObject      *object,
				       guint         param_id,
				       const GValue *value,
				       GParamSpec   *pspec)
{
  CustomCellRendererTogglePixbuf *celltoggle = CUSTOM_CELL_RENDERER_TOGGLE_PIXBUF (object);
  CustomCellRendererTogglePixbufPrivate *priv;

  priv = CUSTOM_CELL_RENDERER_TOGGLE_PRIVATE_GET_PRIVATE (object);

  switch (param_id)
    {
    case PROP_ACTIVE:
      celltoggle->active = g_value_get_boolean (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
      break;
    }
}

/**
 * custom_cell_renderer_toggle_pixbuf_new:
 *
 * Creates a new #CustomCellRendererTogglePixbuf. Adjust rendering
 * parameters using object properties. Object properties can be set
 * globally (with g_object_set()). Also, with #GtkTreeViewColumn, you
 * can bind a property to a value in a #GtkTreeModel. For example, you
 * can bind the "active" property on the cell renderer to a boolean value
 * in the model, thus causing the check button to reflect the state of
 * the model.
 *
 * Return value: the new cell renderer
 **/
GtkCellRenderer *
custom_cell_renderer_toggle_pixbuf_new (GdkPixbuf *active, GdkPixbuf *inactive)
{
  GtkCellRenderer *renderer = g_object_new (CUSTOM_TYPE_CELL_RENDERER_TOGGLE_PIXBUF, NULL);
  CustomCellRendererTogglePixbufPrivate *priv;

  priv = CUSTOM_CELL_RENDERER_TOGGLE_PRIVATE_GET_PRIVATE (renderer);
  priv->active = active;
  priv->inactive = inactive;

  return renderer;
}

static void
custom_cell_renderer_toggle_pixbuf_get_size (GtkCellRenderer *cell,
				   GtkWidget       *widget,
				   GdkRectangle    *cell_area,
				   gint            *x_offset,
				   gint            *y_offset,
				   gint            *width,
				   gint            *height)
{
  gint calc_width;
  gint calc_height;
  CustomCellRendererTogglePixbufPrivate *priv;

  priv = CUSTOM_CELL_RENDERER_TOGGLE_PRIVATE_GET_PRIVATE (cell);

  calc_width = (gint) cell->xpad * 2 + 16;// + priv->indicator_size;
  calc_height = (gint) cell->ypad * 2 + 16;// + priv->indicator_size;

  if (width)
    *width = calc_width;

  if (height)
    *height = calc_height;

  if (cell_area)
    {
      if (x_offset)
	{
	  *x_offset = ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL) ?
		       (1.0 - cell->xalign) : cell->xalign) * (cell_area->width - calc_width);
	  *x_offset = MAX (*x_offset, 0);
	}
      if (y_offset)
	{
	  *y_offset = cell->yalign * (cell_area->height - calc_height);
	  *y_offset = MAX (*y_offset, 0);
	}
    }
  else
    {
      if (x_offset) *x_offset = 0;
      if (y_offset) *y_offset = 0;
    }

  
}

static void
custom_cell_renderer_toggle_pixbuf_render (GtkCellRenderer      *cell,
				 GdkDrawable          *window,
				 GtkWidget            *widget,
				 GdkRectangle         *background_area,
				 GdkRectangle         *cell_area,
				 GdkRectangle         *expose_area,
				 GtkCellRendererState  flags)
{
  CustomCellRendererTogglePixbuf *celltoggle = (CustomCellRendererTogglePixbuf *) cell;
  CustomCellRendererTogglePixbufPrivate *priv;
  gint width, height;
  gint x_offset, y_offset;
  cairo_t *cr = gdk_cairo_create (window);
  gint sel_hlight = GPOINTER_TO_INT(g_object_get_data((GObject *)cell, "sel-highlight"));
  
  priv = CUSTOM_CELL_RENDERER_TOGGLE_PRIVATE_GET_PRIVATE (cell);

  custom_cell_renderer_toggle_pixbuf_get_size (cell, widget, cell_area,
				     &x_offset, &y_offset,
				     &width, &height);
  width -= cell->xpad*2;
  height -= cell->ypad*2;
//  printf(" %d %d %d %p %p %d %d\n", cell_area->x+x_offset + cell->xpad, cell_area->y+y_offset+cell->ypad,  celltoggle->active, priv->active, priv->inactive, width, height);
  if (width <= 0 || height <= 0)
    return;
  
  gdk_cairo_set_source_pixbuf (cr, celltoggle->active ? priv->active : priv->inactive, cell_area->x+x_offset + cell->xpad, cell_area->y+y_offset-cell->ypad);
  if (!sel_hlight) {
	  if (flags & GTK_CELL_RENDERER_PRELIT)
		cairo_paint_with_alpha (cr, 0.5);
	  else
	   	cairo_paint_with_alpha (cr, celltoggle->active ? 1.0 : 0.15);
  } else {
	   double alpha = (flags & GTK_CELL_RENDERER_SELECTED) ?    1.0 : 0.3;
	   if (flags & GTK_CELL_RENDERER_SELECTED &&  0) {
			gtk_paint_box (widget->style, window, GTK_STATE_NORMAL, GTK_SHADOW_ETCHED_OUT, NULL, NULL, "button", cell_area->x+x_offset-1, cell_area->y+y_offset-cell->ypad-2, 22, 22);

	   }
	   cairo_paint_with_alpha (cr, alpha);

  }
//  cairo_paint(cr);
  
  cairo_destroy(cr);
}

static gint
custom_cell_renderer_toggle_pixbuf_activate (GtkCellRenderer      *cell,
				   GdkEvent             *event,
				   GtkWidget            *widget,
				   const gchar          *path,
				   GdkRectangle         *background_area,
				   GdkRectangle         *cell_area,
				   GtkCellRendererState  flags)
{
  CustomCellRendererTogglePixbuf *celltoggle;
  
  celltoggle = CUSTOM_CELL_RENDERER_TOGGLE_PIXBUF (cell);
  g_signal_emit (cell, toggle_cell_signals[TOGGLED], 0, path);

  return TRUE;
}



