/* $Id: seekgraph.cc,v 1.17 2003/11/22 04:55:29 bergo Exp $ */

/*

    eboard - chess client
    http://eboard.sourceforge.net
    Copyright (C) 2000-2003 Felipe Paulo Guazzi Bergo
    bergo@seul.org

    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 <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "seekgraph.h"
#include "global.h"
#include "eboard.h"

static void skg_refresh(GtkWidget *w, gpointer data) {
  if (global.protocol)
    global.protocol->refreshSeeks();
}

static gint skg_sort_num(GtkCList *clist,
			 gconstpointer ptr1, gconstpointer ptr2)
{
  char *t1, *t2;
  int i1, i2;

  GtkCListRow *row1 = (GtkCListRow *) ptr1;
  GtkCListRow *row2 = (GtkCListRow *) ptr2;

  t1 = GTK_CELL_TEXT (row1->cell[clist->sort_column])->text;
  t2 = GTK_CELL_TEXT (row2->cell[clist->sort_column])->text;

  i1 = atoi(t1);
  i2 = atoi(t2);

  if (i1<i2) return -1;
  if (i1>i2) return 1;
  return 0;
}

static gint skg_sort_time(GtkCList *clist,
			 gconstpointer ptr1, gconstpointer ptr2)
{
  char t1[20], t2[20];
  char *p;
  int i1, i2, j1, j2;

  GtkCListRow *row1 = (GtkCListRow *) ptr1;
  GtkCListRow *row2 = (GtkCListRow *) ptr2;

  strncpy(t1, GTK_CELL_TEXT (row1->cell[clist->sort_column])->text, 19);
  strncpy(t2, GTK_CELL_TEXT (row2->cell[clist->sort_column])->text, 19);
  t1[19]=t2[19]=0;

  p=strtok(t1, " \t");
  if (p) {
    i1=atoi(p);
    p=strtok(0," \t");
    if (p) j1=atoi(p); else j1=0;
  } else i1=j1=0;

  p=strtok(t2, " \t");
  if (p) {
    i2=atoi(p);
    p=strtok(0," \t");
    if (p) j2=atoi(p); else j2=0;
  } else i2=j2=0;

  if (i1<i2) return -1;
  if (i1>i2) return 1;
  if (j1<j2) return -1;
  if (j1>j2) return 1;
  return 0;
}


SeekAd::SeekAd() {
  id=32767;
  rated=false;
  automatic=false;
  formula=false;
  clock=incr=0;
}

int SeekAd::operator==(int v) {
  return(id==v);
}

const char ** SeekAd::getListLine() {
  static const char *ll[10];
  static char z[3][32];

  global.debug("SeekAd","getListLine");

  // id name rating (info) (clock+inc) type rated color range a/f
  // 0  1    2      3      4           5    6     7     8     9
  
  sprintf(z[0],"%d",id);
  sprintf(z[1],"%d %d",clock,incr);
  
  ll[0]=z[0];
  ll[1]=player.c_str();
  ll[2]=rating.c_str();
  ll[3]=flags.c_str();
  ll[4]=z[1];
  ll[5]=kind.c_str();
  ll[6]=rated?_("rated"):
              _("unrated");
  ll[7]=color.c_str();
  ll[8]=range.c_str();

  strcpy(z[2],automatic?"- / ":"m / ");
  strcat(z[2],formula?"f":"-");
  ll[9]=z[2];

  return(ll);
}

SeekGraph::SeekGraph() {
  static char * skg_col_titles[10] = {
    N_("Id"),
    N_("Player"),
    N_("Rating"),
    N_("Flags"),
    N_("Time"),
    N_("Variant"),
    N_("Rated"),
    N_("Color"),
    N_("Rating Range"),
    N_("Manual/Formula") };

  GtkWidget *sw,*h,*pb, *rb;
  int i;

  SortCol=5; // variant
  SortDirection=0;

  Count=0;
  widget=gtk_vbox_new(FALSE,0);

  sw=gtk_scrolled_window_new(NULL,NULL);
  clist=gtk_clist_new(10);
  gtk_clist_set_shadow_type(GTK_CLIST(clist),GTK_SHADOW_IN);
  gtk_clist_set_selection_mode(GTK_CLIST(clist),GTK_SELECTION_SINGLE);
  gtk_clist_set_selection_mode(GTK_CLIST(clist),GTK_SELECTION_SINGLE);

  // id name rating (info) (clock+inc) type rated color range a/f
  // 0  1    2      3      4           5    6     7     8     9

  for(i=0;i<10;i++)
    gtk_clist_set_column_title(GTK_CLIST(clist),i,
			       eboard_gettext(skg_col_titles[i]));

  gtk_clist_column_titles_active(GTK_CLIST(clist));
  gtk_clist_column_titles_show(GTK_CLIST(clist));

  gtk_clist_set_sort_column(GTK_CLIST(clist),SortCol);
  gtk_clist_set_sort_type(GTK_CLIST(clist),SortDirection?GTK_SORT_ASCENDING:GTK_SORT_DESCENDING);
  gtk_clist_set_auto_sort(GTK_CLIST(clist),TRUE);

  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
                                 GTK_POLICY_AUTOMATIC,
                                 GTK_POLICY_AUTOMATIC);

  updateFont();

  gtk_container_add(GTK_CONTAINER(sw),clist);  

  for(i=0;i<10;i++)
    gtk_clist_set_column_min_width(GTK_CLIST(clist),i,48);
  gtk_clist_columns_autosize(GTK_CLIST(clist));

  gtk_box_pack_start(GTK_BOX(widget),sw,TRUE,TRUE,0);
  Gtk::show(sw,clist,0);

  h=gtk_hbox_new(FALSE,4);
  pb=gtk_button_new_with_label(_(" Play Selected "));
  rb=gtk_button_new_with_label(_(" Refresh "));
  gtk_box_pack_start(GTK_BOX(widget),h,FALSE,FALSE,4);
  gtk_box_pack_end(GTK_BOX(h),pb,FALSE,FALSE,4);
  gtk_box_pack_end(GTK_BOX(h),rb,FALSE,FALSE,4);
  gtk_widget_set_sensitive(pb,FALSE);

  Gtk::show(h,pb,rb,0);
  gtk_signal_connect(GTK_OBJECT(clist),"select_row",
		     GTK_SIGNAL_FUNC(skg_select),(gpointer)this);

  gtk_signal_connect(GTK_OBJECT(clist),"click_column",
		     GTK_SIGNAL_FUNC(skg_chgsort),(gpointer)this);

  gtk_signal_connect(GTK_OBJECT(clist),"unselect_row",
		     GTK_SIGNAL_FUNC(skg_unselect),(gpointer)this);
  gtk_signal_connect(GTK_OBJECT(pb),"clicked",
		     GTK_SIGNAL_FUNC(skg_play),(gpointer)this);
  gtk_signal_connect(GTK_OBJECT(rb),"clicked",
		     GTK_SIGNAL_FUNC(skg_refresh),0);
  Selected=-1;
  playbutton=pb;
}

void SeekGraph::remove(int id) {
  int i;
  char *z;
  
  gtk_clist_freeze(GTK_CLIST(clist));
  for(i=0;i<Count;i++) {
    gtk_clist_get_text(GTK_CLIST(clist),i,0,&z);
    if (!z)
      continue;
    if (atoi(z)==id) {
      gtk_clist_remove(GTK_CLIST(clist),i);
      --Count;
      break;
    }
  }
  gtk_clist_thaw(GTK_CLIST(clist));
  contentUpdated();
}

void SeekGraph::add(SeekAd *ad) {
  global.debug("SeekGraph","add");
  gtk_clist_freeze(GTK_CLIST(clist));
  gtk_clist_append(GTK_CLIST(clist),(gchar **)(ad->getListLine()));
  Count++;
  gtk_clist_columns_autosize(GTK_CLIST(clist));  
  gtk_clist_thaw(GTK_CLIST(clist));
  contentUpdated();
  delete ad;
}

void SeekGraph::clear() {
  if (!Count)
    return;

  Count=0;
  gtk_clist_freeze(GTK_CLIST(clist));
  gtk_clist_clear(GTK_CLIST(clist));
  gtk_clist_thaw(GTK_CLIST(clist));
  contentUpdated();
}

void SeekGraph::updateFont() {
  GdkFont *fxd;
  GtkStyle *oStyle, *nStyle;
  fxd=gdk_font_load(global.SeekFont);
  if (!fxd) {
    cerr << _("<SeekGraph::updatefont> failed to load ") << global.SeekFont << endl;
    return;
  }		
  oStyle = gtk_widget_get_style(GTK_WIDGET(clist));
  nStyle = gtk_style_copy(oStyle);
  nStyle->font = fxd;
  gtk_widget_set_style(GTK_WIDGET(clist), nStyle);
  gtk_style_unref(oStyle);
}

// --- callbacks

void
skg_chgsort(GtkCList *cl, gint column, gpointer data)
{
  SeekGraph *me;
  me=(SeekGraph *)data;

  if (column != me->SortCol) {
    me->SortCol = column;
  } else {
    me->SortDirection = ! me->SortDirection;
  }

  switch(column) {
  case 0: // id: numeric
  case 2: // rating: numeric
    gtk_clist_set_compare_func(cl, (GtkCListCompareFunc) skg_sort_num);
    break;
  case 4: // time control
    gtk_clist_set_compare_func(cl, (GtkCListCompareFunc) skg_sort_time);
    break;
  default:
    gtk_clist_set_compare_func(cl, 0);
  }

  gtk_clist_set_sort_column(cl,me->SortCol);
  gtk_clist_set_sort_type(cl,me->SortDirection ? GTK_SORT_ASCENDING : GTK_SORT_DESCENDING);
  gtk_clist_freeze(cl);
  gtk_clist_sort(cl);
  gtk_clist_thaw(cl);
}

void
skg_select(GtkCList *cl, gint row, gint column, GdkEventButton *eb, gpointer data)
{
  SeekGraph *me;
  char *z;
  me=(SeekGraph *)data;  
  gtk_clist_get_text(GTK_CLIST(cl),row,0,&z);
  me->Selected=atoi(z);
  gtk_widget_set_sensitive(me->playbutton,TRUE);


  if (eb!=NULL)
    if (eb->type==GDK_2BUTTON_PRESS)
      skg_play(0,data);
}

void
skg_unselect(GtkCList *cl, gint row, gint column, GdkEventButton *eb, gpointer data)
{
  SeekGraph *me;
  me=(SeekGraph *)data;
  me->Selected=-1;
  gtk_widget_set_sensitive(me->playbutton,FALSE);

}

void
skg_play(GtkWidget *w, gpointer data)
{
  SeekGraph *me;
  char z[64];
  me=(SeekGraph *)data;
  if (me->Selected >= 0 && global.protocol) {
    sprintf(z,"play %d",me->Selected);
    global.protocol->sendUserInput(z);
    sprintf(z,_("Replied to seek #%d"),me->Selected);
    global.status->setText(z,10);
  }
}
