/* gtkstuff.c
 * Copyright (C) 2002-2004 Pascal Eberhard <pascal.ebo@netcourrier.com>
 *
 * 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 <string.h>

#include "common.h"

typedef struct pixbufinline_t
{
  gchar   name[64];
  gint    size;
  guint8 *pixbufinline;
} pixbufinline_t;

#include "pixbufinline.inc"

/*
pixbufinline_t pixbufinline[] = 
{
  {
    "unknown",
    sizeof(unknown),
    (guint8 *) & unknown
  },
  { NULL }
};
*/
// ----------------------------------------------------------------------------
GtkWidget *gtk_arrow_button_new(GtkArrowType arrow_type)
{
  GtkWidget *button;
  GtkWidget *arrow;
  GtkShadowType shadow_type = GTK_SHADOW_NONE;
  //GTK_SHADOW_NONE GTK_SHADOW_IN GTK_SHADOW_OUT
  //GTK_SHADOW_ETCHED_IN GTK_SHADOW_ETCHED_OUT

  button = gtk_button_new ();
  arrow = gtk_arrow_new (arrow_type, shadow_type);
  gtk_container_add (GTK_CONTAINER(button), arrow);

  // GTK_RELIEF_NORMAL GTK_RELIEF_HALF GTK_RELIEF_NONE
  //gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE);
  gtk_widget_show (button);
  gtk_widget_show (arrow);

  return button;
}

// ----------------------------------------------------------------------------
gint index_of_inline_pixbuf(gchar *name)
{
  gint i;

  g_assert(name != NULL);

  for (i=0; i<pixbufinline_count; i++)
  {
    if (strcmp(pixbufinline[i].name, name) == 0)
    {
      //TRACE("i:%d, name:%s found", i, name);
      return i;
    }
  }
  return -1;
}


// ----------------------------------------------------------------------------
GdkPixbuf* gdk_pixbuf_new_from_apwal_private(gchar *name)
{
  GdkPixbuf *pixbuf;
  GError    *err;
  gint       idx;

  g_assert(name != NULL);

  pixbuf = NULL;
  err = NULL;

  // first, check if the icon is found inline
  idx = index_of_inline_pixbuf(name);
  if (idx != -1)
  {
    pixbuf = gdk_pixbuf_new_from_inline(pixbufinline[idx].size,
                                        pixbufinline[idx].pixbufinline,
                                        TRUE/*copy_pixels*/,
                                        &err/*GError*/);
    if (pixbuf)
    {
      return pixbuf;
    }
    else
    {
      g_assert(err != NULL && err->message != NULL);
      WARN("gdk_pixbuf_new_from_inline NULL, idx:%d, name:%s, E:%s",
           idx, name, err->message);
      g_error_free(err);
      err = NULL;
    }
  }

  if (g_file_test(name, G_FILE_TEST_EXISTS))
  {
    pixbuf = gdk_pixbuf_new_from_file(name, &err/*GError*/);
    if (pixbuf)
    {
      return pixbuf;
    }
    else
    { 
      g_assert(err != NULL && err->message != NULL);
      //TRACE("gdk_pixbuf_new_from_file NULL, %s", err->message);
      g_error_free(err);
      err = NULL;
      return NULL;
    }
  }

  idx = index_of_inline_pixbuf("unknown");
  if (idx != -1)
  {
    pixbuf = gdk_pixbuf_new_from_inline(pixbufinline[idx].size,
                                        pixbufinline[idx].pixbufinline,
                                        TRUE/*copy_pixels*/,
                                        &err/*GError*/);
    if (pixbuf == NULL)
    {
      g_assert(err != NULL && err->message != NULL);
      ERR("gdk_pixbuf_new_from_inline NULL with unknown ->aoutch, idx:%d, E:%s",
           idx, err->message);
      g_error_free(err);
      err = NULL;
    }
    return pixbuf;
  }
  else
    ERR("%s", "inline pixbuf:'unknown' not found");
  return NULL;
}
// ----------------------------------------------------------------------------
GdkPixbuf* gdk_pixbuf_new_from_apwal(gchar *name, gint *rwidth, gint *rheight)
{
  GdkPixbuf *pix1;
  GdkPixbuf *pix2;
  gint       width, height;
  g_assert(name != NULL);

  pix1 = gdk_pixbuf_new_from_apwal_private(name);
  if (pix1 == NULL)
    return NULL;

  // if icon is bigger that 48 x 48 then truncate it to save memory
  width = gdk_pixbuf_get_width(pix1);
  height = gdk_pixbuf_get_height(pix1);
  if (rwidth != NULL)
    *rwidth = width;
  if (rheight != NULL)
    *rheight = height;

  if (width <= 48 && height <= 48)
    return pix1;

  width = (width > 48) ? 48 : width;
  height = (height > 48) ? 48 : height;

  pix2 = gdk_pixbuf_new(GDK_COLORSPACE_RGB/*colorspace*/, TRUE/*has_alpha*/,
                        8/*bits_per_sample*/, width, height);
  gdk_pixbuf_copy_area(pix1/*src_pixbuf*/,
                       0 /*src_x*/, 0/*src_y*/, width, height,
                       pix2/*dst_pixbuf*/,
                       0/*dst_x*/,0/*dst_y*/);
  g_object_unref(pix1);
  return pix2;
}
// ----------------------------------------------------------------------------
void gdk_pixbuf_append(GdkPixbuf *pix1, GdkPixbuf *pix2)
{
  GdkPixbuf *pixtmp;
  gint       width1, height1;
  gint       width2, height2;

  g_assert(pix1 != NULL && pix2 != NULL);
  
  width1 = gdk_pixbuf_get_width(pix1);
  height1 = gdk_pixbuf_get_height(pix1);
  width2 = gdk_pixbuf_get_width(pix2);
  height2 = gdk_pixbuf_get_height(pix2);

  if ((width1 != width2) || (height1 != height2))
  {
    pixtmp = gdk_pixbuf_scale_simple(pix2, width1, height1,
                                     GDK_INTERP_BILINEAR);
    pix2 = pixtmp;
  }
  else
    pixtmp = NULL;


  gdk_pixbuf_composite(pix2/*src*/, pix1/*dest*/,
                       0/*dest_x*/,
                       0/*dest_y*/,
                       width1/*dest_width*/,
                       height1/*dest_height*/,
                       0/*offset_x*/,
                       0/*offset_y*/,
                       1/*scale_x*/,
                       1/*scale_y*/,
                       GDK_INTERP_NEAREST/*interp_type*/,
                       255/*overall_alpha*/);

  if (pixtmp != NULL)
    g_object_unref(pixtmp);
}
// ----------------------------------------------------------------------------
// gtk_widget_modify_text on RH8 doesn't reset the color if the color arg is
// NULL. So use this wrapper to avoid the problem.
void gtk_widget_set_text_color(GtkWidget *widget, GdkColor *color)
{
  //GtkStyle     *wstyle;
  GtkRcStyle     *rcstyle;
  GtkStateType    state = GTK_STATE_NORMAL;
  GtkRcFlags      component = GTK_RC_TEXT;

  //int i;
  rcstyle = gtk_widget_get_modifier_style(widget);
  //for (i=0; i<5; i++)
  //  TRACE("%d %3d.%3d.%3d.%3d", i, rcstyle->fg[i].pixel, rcstyle->fg[i].red, rcstyle->fg[i].green, rcstyle->fg[i].blue);

  if (color != NULL)
  {
   if (component == GTK_RC_TEXT)
      rcstyle->text[state] = *color;
   else
     ERR("component%d != GTK_RC_TEXT", component);
    rcstyle->color_flags[state] |= component;
  }
  else
  {
    rcstyle->color_flags[state] &= ~component;
  }
  gtk_widget_modify_style(widget, rcstyle);
}
// ----------------------------------------------------------------------------
void gtk_widget_set_text_color_invalid(GtkWidget *widget)
{
  GdkColor color = { 0, 65535, 0, 0 } /*Red*/;
  gtk_widget_set_text_color(widget, &color);
}
// ----------------------------------------------------------------------------
void gtk_widget_set_text_color_default(GtkWidget *widget)
{
  gtk_widget_set_text_color(widget, NULL);
}
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
