PROGRAM(clist);

// The GtkCList widget is a multi-column list widget that is capable
// of handling literally thousands of rows of information. Each column
// can optionally have a title, which itself is optionally active,
// allowing us to bind a function to it's selection.

// IMG: GTK.Clist(2)->set_column_title(0,"Col 1")->set_column_title(1,"Col 2")->column_titles_show()->set_column_width(0,50)->set_usize(150,70)

SIGNAL("select_row", "Called when a row is selected");
SIGNAL("unselect_row", "Called when a row is deselected");
SIGNAL("click_column", "Called when a column is clicked");
INHERIT(container);
/* FIXME: add with titles later on.. */
COMPLEX_FUNCTION(create, int);
NAME_ARGS(columns);

COMPLEX_FUNCTION(set_hadjustment, adjustment);
COMPLEX_FUNCTION(set_vadjustment, adjustment);

adjustment COMPLEX_FUNCTION(get_hadjustment);
adjustment COMPLEX_FUNCTION(get_vadjustment);


SIMPLE_INT_FUNCTION(set_shadow_type);
NAME_ARGS(shadowtype);
// One of CONST(GTK_SHADOW)

SIMPLE_INT_FUNCTION(set_selection_mode);
NAME_ARGS(mode);
// One of CONST(GTK_SELECTION);


COMPLEX_FUNCTION(set_reorderable, int);
COMPLEX_FUNCTION(set_use_drag_icons, int);
COMPLEX_FUNCTION(set_button_actions, int, int);
NAME_ARGS(button,action);
CONSTANT(GTK_BUTTON_IGNORED);
CONSTANT(GTK_BUTTON_SELECTS);
CONSTANT(GTK_BUTTON_DRAGS);
CONSTANT(GTK_BUTTON_EXPANDS);
// Action is a bitwise or of CONST(GTK_BUTTON)



SIMPLE_FUNCTION(freeze);
// freeze all visual updates of the list, and then thaw the list after
// you have made a number of changes and the updates wil occure in a
// more efficent mannor than if you made them on a unfrozen list
SIMPLE_FUNCTION(thaw);
// freeze all visual updates of the list, and then thaw the list after
// you have made a number of changes and the updates wil occure in a
// more efficent mannor than if you made them on a unfrozen list

SIMPLE_FUNCTION(column_titles_show);
SIMPLE_FUNCTION(column_titles_hide);
SIMPLE_FUNCTION(column_titles_active);
SIMPLE_FUNCTION(column_titles_passive);

SIMPLE_INT_FUNCTION(column_title_active);
NAME_ARGS(column);

SIMPLE_INT_FUNCTION(column_title_passive);
NAME_ARGS(column);

COMPLEX_FUNCTION(set_column_title, int, string);
NAME_ARGS(column,title);
string COMPLEX_FUNCTION(get_column_title, int );

COMPLEX_FUNCTION(set_column_widget, int, widget);
NAME_ARGS(column,widget);
widget COMPLEX_FUNCTION(get_column_widget, int );

COMPLEX_FUNCTION(set_column_visibility, int, int);
NAME_ARGS(column,visiblep);

COMPLEX_FUNCTION(set_column_resizeable, int, int);
NAME_ARGS(column,resizeablep);

COMPLEX_FUNCTION(set_column_auto_resize, int, int);
NAME_ARGS(column,autoresizep);

int COMPLEX_FUNCTION(columns_autosize);

int COMPLEX_FUNCTION(optimal_column_width, int);

COMPLEX_FUNCTION(set_column_justification, int, int);
NAME_ARGS(column,justification);
// justification is one of CONST(GTK_JUSTIFY)

COMPLEX_FUNCTION(set_column_width, int, int);
NAME_ARGS(column,width);

COMPLEX_FUNCTION(set_column_min_width, int, int);
NAME_ARGS(column,width);

COMPLEX_FUNCTION(set_column_max_width, int, int);
NAME_ARGS(column,width);
// if width < 0 , there is no restriction


SIMPLE_INT_FUNCTION(set_row_height);
NAME_ARGS(pixels);


// The width is in pixels
COMPLEX_FUNCTION(moveto, int, int,float,float);
NAME_ARGS(row,column,xpos,ypos);
// xpos and ypos are relative, 0.0 == top, 1.0 == bottom)

int COMPLEX_FUNCTION(get_cell_type, int, int);
NAME_ARGS(row, column);


COMPLEX_FUNCTION(set_text, int, int, string);
NAME_ARGS(row,column,text);
// row, col, text

FUNCTION(get_text, "function(int,int:string)");
NAME_ARGS( row, column );
{
  int x, y;  
  gchar *p = NULL;
  get_all_args( "get_*", args, "%d%d", &x, &y );

  pop_n_elems( args );
  gtk_clist_get_text( GTK_CLIST( THIS->obj ), x, y, &p );
  if(p)
    push_text(p);
  else
    push_int(0);
}



FUNCTION(set_pixmap, "function(int,int,object,object|void:object)");
ARGS(int,int,GDK.Pixmap,void|object(GDK.Bitmap));
RETURNS(GTK.Clist);
NAME_ARGS(row,column,image,mask);
{
  int x, y;
  struct object *a, *b=0;
  GdkPixmap *img;
  GdkBitmap *mask = NULL;
  if(args == 3)
    get_all_args("set_pixmap", args, "%d%d%o", &y,&x,&a );
  else
    get_all_args("set_pixmap", args, "%d%d%o%o", &y,&x,&a,&b );

  img = get_gdkobject( a, Pixmap );
  if(b) mask = get_gdkobject( b, Bitmap );
  
  gtk_clist_set_pixmap( GTK_CLIST( THIS->obj ), y, x, img, mask );

  RETURN_THIS();
}

FUNCTION(get_pixmap, "function(int,int:mapping)");
NAME_ARGS( row, column );
{
  int x, y;  
  GdkPixmap *p = NULL;
  GdkBitmap *b = NULL;
  get_all_args( "get_*", args, "%d%d", &x, &y );

  pop_n_elems( args );
  gtk_clist_get_pixmap( GTK_CLIST( THIS->obj ), x, y, &p, &b );
  push_text( "pixmap" );
  if(p)
    push_gdkobject(p, Pixmap);
  else
    push_int( 0 );
  push_text( "mask" );
  if(b)
    push_gdkobject(b, Bitmap);
  else
    push_int( 0 );
  f_aggregate_mapping( 2 );
}




FUNCTION(set_pixtext, "function(int,int,string,int,object,object|void:object)")
ARGS(int,int,string,int,GDK.Pixmap,void|object(GDK.Bitmap));
RETURNS(GTK.Clist);
NAME_ARGS(row,column,text,spacing,image,mask);
{
  int x, y;
  struct object *a, *b=0;
  char *t;
  int s;
  GdkPixmap *img;
  GdkBitmap *mask = NULL;
  if(args == 5)
    get_all_args("set_pixmap", args, "%d%d%s%d%o", &y,&x, &t, &s, &a );
  else
    get_all_args("set_pixmap", args, "%d%d%s%d%o%o", &y,&x, &t, &s,&a,&b );

  img = get_gdkobject( a, Pixmap );
  if(b) mask = get_gdkobject( b, Bitmap );
  
  gtk_clist_set_pixtext( GTK_CLIST( THIS->obj ), y, x, t,s, img, mask );

  RETURN_THIS();
}

FUNCTION(get_pixtext, "function(int,int:mapping)");
NAME_ARGS( row, column );
{
  int x, y;  
  gchar *t = NULL;
  GdkPixmap *p = NULL;
  GdkBitmap *b = NULL;
  guint8 s = 0;
  get_all_args( "get_*", args, "%d%d", &x, &y );

  gtk_clist_get_pixtext( GTK_CLIST( THIS->obj ), x, y, &t, &s, &p, &b );
  pop_n_elems( args );

  push_text( "spacing" );
  push_int( s );

  push_text( "text" );
  if(t)
    push_text( t );
  else
    push_int( 0 );
  push_text( "pixmap" );
  if(p)
    push_gdkobject(p, Pixmap);
  else
    push_int( 0 );
  push_text( "mask" );
  if(b)
    push_gdkobject(b, Bitmap);
  else
    push_int( 0 );

  f_aggregate_mapping( 8 );
}


FUNCTION(set_foreground, "function(int,object:object)")
ARGS(int,GDK.Color);
RETURNS(GTK.Clist);
NAME_ARGS(row,color);
{
  struct object *a;
  int row;
  GdkColor *c;
  get_all_args( "set_foreground", args, "%d%o", &row, &a );
  c = get_gdkobject( a, Color );
  gtk_clist_set_foreground( GTK_CLIST( THIS->obj ), row, c );

  RETURN_THIS();
}

FUNCTION(set_background, "function(int,object:object)")
ARGS(int,GDK.Color);
RETURNS(GTK.Clist);
NAME_ARGS(row,color);
{
  struct object *a;
  int row;
  GdkColor *c;
  get_all_args( "set_background", args, "%d%o", &row, &a );
  c = get_gdkobject( a, Color );
  gtk_clist_set_background( GTK_CLIST( THIS->obj ), row, c );

  RETURN_THIS();
}

COMPLEX_FUNCTION(set_cell_style, int, int, style );
style COMPLEX_FUNCTION(get_cell_style, int, int );
COMPLEX_FUNCTION(set_row_style, int, style );
style COMPLEX_FUNCTION(get_row_style, int );


COMPLEX_FUNCTION(set_shift, int, int, int, int);
NAME_ARGS(row,column,yshift,xshift);


COMPLEX_FUNCTION(set_selectable, int, int);
NAME_ARGS(row, selectablep);

int COMPLEX_FUNCTION(get_selectable, int);
NAME_ARGS(row);

int COMPLEX_FUNCTION(append, stringarray);
NAME_ARGS(columns);

int COMPLEX_FUNCTION(prepend, stringarray);
NAME_ARGS(columns);

int COMPLEX_FUNCTION(insert, int, stringarray);
NAME_ARGS(row,columns);
// Insert a row after a specified row.
COMPLEX_FUNCTION(remove, int);
NAME_ARGS(row);
// delete a row


static void freeit(struct object *o)
{
  free_object( o );
}

FUNCTION(set_row_data, "function(int, object:void)")
{
  int row;
  struct object *obj;
  get_all_args( "set_row_data", args, "%d%o", &row, &obj );
  obj->refs++;
  gtk_clist_set_row_data_full( GTK_CLIST( THIS->obj ), row, obj, 
                               (void *)freeit );
  RETURN_THIS();
}

FUNCTION(get_row_data, "function(int:object)");
{
  int row;
  struct object *o;
  get_all_args( "get_row_data", args, "%d", &row );

  o = gtk_clist_get_row_data( GTK_CLIST( THIS->obj ), row );
  pop_n_elems( args );
  if(o)
    ref_push_object( o );
  else
    push_int( 0 );
}

FUNCTION(find_row_from_data, "function(object:int)");
{
  int row;
  struct object *o;
  get_all_args( "find_row_from_data", args, "%o", &o );
  row = gtk_clist_find_row_from_data( GTK_CLIST( THIS->obj ), o );
  pop_n_elems(args);
  push_int( row );
}

COMPLEX_FUNCTION(select_row, int, int);
NAME_ARGS(row,column);

COMPLEX_FUNCTION(unselect_row, int, int);
NAME_ARGS(row,column);

SIMPLE_FUNCTION(undo_selection);

SIMPLE_FUNCTION(clear);
// remove all rows

FUNCTION(get_selection_info, "function(int,int:mapping)");
NAME_ARGS(x,y);
RETURNS(mapping(string:int));
// return the row column corresponding to the x and y coordinates,
// the returned values are only valid if the x and y coordinates
// are relative to the clist window coordinates
{
  int r=-1, c=-1, x, y;
  get_all_args( "get_selection_info", args, "%d%d", &x, &y );
  gtk_clist_get_selection_info( GTK_CLIST( THIS->obj ), x, y, &r, &c );

  pop_n_elems( args );
  push_text( "row" );
  push_int( r );
  push_text( "column" );
  push_int( c );
  f_aggregate_mapping( 4 );
}

SIMPLE_FUNCTION(select_all);
SIMPLE_FUNCTION(unselect_all);

COMPLEX_FUNCTION(row_move, int, int);

/* set_compare_func */

COMPLEX_FUNCTION(set_sort_type, int);
NAME_ARGS( direction );
// Ascending or descending (One of CONST(GTK_SORT))
COMPLEX_FUNCTION(sort);

COMPLEX_FUNCTION(set_auto_sort, int);
NAME_ARGS( sortp );


