#include "addressbook.h"
#include <gdk/gdkkeysyms.h>
#include <unistd.h>



#define NUM_DOT_POINTS		35


/* this defigns the base grid spacing */
#define CELL_SPACING 1

/* added the horizontal space at the beginning and end of a row*/
#define COLUMN_INSET 3

/* gives the top pixel of the given row in context of
 * the clist's voffset */
#define ROW_TOP_YPIXEL(clist, row) (((clist)->row_height * (row)) + \
                                    (((row) + 1) * CELL_SPACING) + \
                                    (clist)->voffset)



static GtkWidget *p_clist;
static gint cur_row = -1;



/******** External function declarations ********/

addr_info *get_address_details();

void open_edit_window(gint row, gchar *key);

gint (*clist_button_press)(GtkWidget *widget, GdkEventButton *event);

GtkWidget *addressbook_get_toplevel_widget();



/******** Internal function declarations ********/

static void my_draw_row(GtkCList *clist,
                        GdkRectangle *area,
                        gint row,
                        GtkCListRow *clist_row);

static gint my_clist_button_press(GtkWidget *widget,
                                  GdkEventButton *event);



/******** External function definitions ********/

void move_to_address(gint row, gboolean make_top)
{
#if (DEBUG==1)
   printf("%d: move to row %d\n", getpid(), row);
#endif

   gtk_clist_moveto(GTK_CLIST(p_clist), row, 0, make_top ? 0.0 : 0.5, 0.0);
   GTK_CLIST(p_clist)->focus_row = row;
   gtk_clist_select_row(GTK_CLIST(p_clist), row, 0);

   cur_row = row;
}



void addressbook_clist_set_function(GtkWidget *clist)
{
   GtkWidgetClass *widget_class;
   GtkCListClass *cp;

   p_clist = clist;

   widget_class = GTK_WIDGET_CLASS (((GtkObject*) (clist))->klass);
   cp = GTK_CLIST_CLASS (((GtkObject*) (clist))->klass);

   /* replace draw row function pointer */
   cp->draw_row = my_draw_row;

   /* save and replace button press/release function pointers */
   clist_button_press = widget_class->button_press_event;
   widget_class->button_press_event = my_clist_button_press;
}



/******** Internal function definitions ********/

static void
get_cell_style (GtkCList     *clist,
                GtkCListRow  *clist_row,
                gint          state,
                gint          column,
                GtkStyle    **style,
                GdkGC       **fg_gc,
                GdkGC       **bg_gc)
{
  gint fg_state;

  if ((state == GTK_STATE_NORMAL) &&
      (GTK_WIDGET (clist)->state == GTK_STATE_INSENSITIVE))
    fg_state = GTK_STATE_INSENSITIVE;
  else
    fg_state = state;

  if (clist_row->cell[column].style)
    {
      if (style)
        *style = clist_row->cell[column].style;
      if (fg_gc)
        *fg_gc = clist_row->cell[column].style->fg_gc[fg_state];
      if (bg_gc) {
        if (state == GTK_STATE_SELECTED)
          *bg_gc = clist_row->cell[column].style->bg_gc[state];
        else
          *bg_gc = clist_row->cell[column].style->base_gc[state];
      }
    }
  else if (clist_row->style)
    {
      if (style)
        *style = clist_row->style;
      if (fg_gc)
        *fg_gc = clist_row->style->fg_gc[fg_state];
      if (bg_gc) {
        if (state == GTK_STATE_SELECTED)
          *bg_gc = clist_row->style->bg_gc[state];
        else
          *bg_gc = clist_row->style->base_gc[state];
      }
    }
  else
    {
      if (style)
        *style = GTK_WIDGET (clist)->style;
      if (fg_gc)
        *fg_gc = GTK_WIDGET (clist)->style->fg_gc[fg_state];
      if (bg_gc) {
        if (state == GTK_STATE_SELECTED)
          *bg_gc = GTK_WIDGET (clist)->style->bg_gc[state];
        else
          *bg_gc = GTK_WIDGET (clist)->style->base_gc[state];
      }

      if (state != GTK_STATE_SELECTED)
        {
          if (fg_gc && clist_row->fg_set)
            *fg_gc = clist->fg_gc;
          if (bg_gc && clist_row->bg_set)
            *bg_gc = clist->bg_gc;
        }
    }
}



static void my_draw_row(GtkCList     *clist,
                        GdkRectangle *area,
                        gint          row,
                        GtkCListRow  *clist_row)
{
  GtkWidget *widget;
  GdkRectangle *rect;
  GdkRectangle row_rectangle;
  GdkRectangle cell_rectangle;
  GdkRectangle clip_rectangle;
  GdkPoint gpt[NUM_DOT_POINTS];
  gint last_column;
  gint state;
  gint i, j, x, y;

   /* Call the original event handler */
//  (*draw_row)(clist, area, row, clist_row);

  /* bail now if we arn't drawable yet */
  if (!GTK_WIDGET_DRAWABLE (clist) || row < 0 || row >= clist->rows)
    return;

  widget = GTK_WIDGET (clist);

  /* if the function is passed the pointer to the row instead of null,
   * it avoids this expensive lookup */
  if (!clist_row)
    clist_row = (g_list_nth (clist->row_list, row))->data;

  /* rectangle of the entire row */
  row_rectangle.x = 0;
  row_rectangle.y = ROW_TOP_YPIXEL (clist, row);
  row_rectangle.width = clist->clist_window_width;
  row_rectangle.height = clist->row_height;

  /* rectangle of the cell spacing above the row */
  cell_rectangle.x = 0;
  cell_rectangle.y = row_rectangle.y - CELL_SPACING;
  cell_rectangle.width = row_rectangle.width;
  cell_rectangle.height = CELL_SPACING;

  /* rectangle used to clip drawing operations, it's y and height
   * positions only need to be set once, so we set them once here.
   * the x and width are set withing the drawing loop below once per
   * column */
  clip_rectangle.y = row_rectangle.y;
  clip_rectangle.height = row_rectangle.height;

  if (clist_row->state == GTK_STATE_NORMAL)
    {
      if (clist_row->fg_set)
        gdk_gc_set_foreground (clist->fg_gc, &clist_row->foreground);
      if (clist_row->bg_set)
        gdk_gc_set_foreground (clist->bg_gc, &clist_row->background);
    }

  state = clist_row->state;

      rect = &clip_rectangle;
      gdk_draw_rectangle (clist->clist_window,
                          widget->style->base_gc[GTK_STATE_ACTIVE],
                          TRUE,
                          cell_rectangle.x,
                          cell_rectangle.y,
                          cell_rectangle.width,
                          cell_rectangle.height);

      /* the last row has to clear it's bottom cell spacing too */
      if (clist_row == clist->row_list_end->data)
        {
          cell_rectangle.y += clist->row_height + CELL_SPACING;

          gdk_draw_rectangle (clist->clist_window,
                              widget->style->base_gc[GTK_STATE_ACTIVE],
                              TRUE,
                              cell_rectangle.x,
                              cell_rectangle.y,
                              cell_rectangle.width,
                              cell_rectangle.height);
        }

  for (last_column = clist->columns - 1;
       last_column >= 0 && !clist->column[last_column].visible; last_column--)
    ;

  /* iterate and draw all the columns (row cells) and draw their contents */
  for (i = 0; i < clist->columns; i++)
    {
      GtkStyle *style;
      GdkGC *fg_gc;
      GdkGC *bg_gc;

      gint width;
      gint height;
      gint pixmap_width;
      gint offset = 0;
      gint row_center_offset;

      if (!clist->column[i].visible)
        continue;

      get_cell_style (clist, clist_row, state, i, &style, &fg_gc, &bg_gc);

      clip_rectangle.x = clist->column[i].area.x + clist->hoffset;
      clip_rectangle.width = clist->column[i].area.width;

      /* calculate clipping region clipping region */
      clip_rectangle.x -= COLUMN_INSET + CELL_SPACING;
      clip_rectangle.width += (2 * COLUMN_INSET + CELL_SPACING +
                               (i == last_column) * CELL_SPACING);

      gdk_draw_rectangle (clist->clist_window, bg_gc, TRUE,
                          rect->x, rect->y, rect->width, rect->height);

      clip_rectangle.x += COLUMN_INSET + CELL_SPACING;
      clip_rectangle.width -= (2 * COLUMN_INSET + CELL_SPACING +
                               (i == last_column) * CELL_SPACING);

      /* calculate real width for column justification */
      pixmap_width = 0;
      offset = 0;
      switch (clist_row->cell[i].type)
        {
        case GTK_CELL_TEXT:
          width = gdk_string_width (style->font,
                                    GTK_CELL_TEXT (clist_row->cell[i])->text);
          break;
        case GTK_CELL_PIXMAP:
          gdk_window_get_size (GTK_CELL_PIXMAP (clist_row->cell[i])->pixmap,
                               &pixmap_width, &height);
          width = pixmap_width;
          break;
        case GTK_CELL_PIXTEXT:
          gdk_window_get_size (GTK_CELL_PIXTEXT (clist_row->cell[i])->pixmap,
                               &pixmap_width, &height);
          width = (pixmap_width +
                   GTK_CELL_PIXTEXT (clist_row->cell[i])->spacing +
                   gdk_string_width (style->font,
                                     GTK_CELL_TEXT
                                     (clist_row->cell[i])->text));
          break;
        default:
          continue;
          break;
        }

      switch (clist->column[i].justification)
        {
        case GTK_JUSTIFY_LEFT:
          offset = clip_rectangle.x + clist_row->cell[i].horizontal;
          break;
        case GTK_JUSTIFY_RIGHT:
          offset = (clip_rectangle.x + clist_row->cell[i].horizontal +
                    clip_rectangle.width - width);
          break;
        case GTK_JUSTIFY_CENTER:
        case GTK_JUSTIFY_FILL:
          offset = (clip_rectangle.x + clist_row->cell[i].horizontal +
                    (clip_rectangle.width / 2) - (width / 2));
          break;
        };

          if (style != GTK_WIDGET (clist)->style)
            row_center_offset = (((clist->row_height - style->font->ascent -
                                  style->font->descent - 1) / 2) + 1.5 +
                                 style->font->ascent);
          else
            row_center_offset = clist->row_center_offset;

          gdk_gc_set_clip_rectangle (fg_gc, &clip_rectangle);

          gdk_draw_string(clist->clist_window, style->font, fg_gc,
                           offset,
                           row_rectangle.y + row_center_offset +
                           clist_row->cell[i].vertical,
                           GTK_CELL_TEXT (clist_row->cell[i])->text);

         x = offset;
#if (PCFB || PDA)
         y = row_rectangle.y + row_center_offset + clist_row->cell[i].vertical + 3;
#else
         y = row_rectangle.y + row_center_offset + clist_row->cell[i].vertical + 5;
#endif

         for(j = 0; j < NUM_DOT_POINTS; j++, x += 4)
         {
            gpt[j].x = x;
            gpt[j].y = y;
         }
         gdk_draw_points(clist->clist_window, fg_gc, gpt, NUM_DOT_POINTS);

         gdk_gc_set_clip_rectangle (fg_gc, NULL);
    }
}



static gint my_clist_button_press(GtkWidget *widget, GdkEventButton *event)
{
   gchar *s;
   gint row, button_actions;

   button_actions = GTK_CLIST(widget)->button_actions[event->button - 1];

   if (button_actions == GTK_BUTTON_IGNORED)
      return FALSE;

   /* Call the original event handler */
   (*clist_button_press)(widget, event);

   row = GTK_CLIST(widget)->focus_row;

   if(cur_row == row)
   {
      if(gtk_clist_get_text(GTK_CLIST(widget), row, NAME_INX, &s))
         open_edit_window(row, s);
   }
//      gtk_clist_select_row(GTK_CLIST(widget), row, -1);

   /* save the current selected row */
   cur_row = row;

   return TRUE;
}



