/* -*- c -*- */
PROGRAM(text);
// The Text widget allows multiple lines of text to be displayed and
// edited. It supports both multi-colored and multi-font text,
// allowing them to be mixed in any way we wish. It also has a wide
// set of key based text editing commands, which are compatible with
// Emacs.
// <p>
// The text widget supports full cut-and-paste facilities, including
// the use of double- and triple-click to select a word and a whole
// line, respectively.
// <p>
// Bugs:<ul>
//      <li> You cannot add text to the widget before it is realized.
//     </ul>
// IMG: GTK.Text(GTK.Adjustment(),GTK.Adjustment())
// IMG: function_object(call_out(GTK.Text(GTK.Adjustment(),GTK.Adjustment())->set_text, 0, "Some text")[0])
// IMG: function_object(call_out(GTK.Text(GTK.Adjustment(),GTK.Adjustment())->insert, 0, "Some text", 0, GDK.Color(255,255,0), GDK.Color(0,0,0))[0])

INHERIT(editable);
COMPLEX_FUNCTION(create, adjustment, adjustment);
NAME_ARGS(xadjustment,yadjustment);
// Create a new textwidget. The arguments are xadjustment and yadjustment.
COMPLEX_FUNCTION(set_editable, int);
NAME_ARGS(editablep);
// If true, the user can change the text in the widget.
COMPLEX_FUNCTION(set_word_wrap, int);
NAME_ARGS(wordwrapp);
// If true, the widget will automatically wrap the contents.
COMPLEX_FUNCTION(set_line_wrap, int);
NAME_ARGS(linewrapp);
// If true, the widget will automatically wrap the contents.
COMPLEX_FUNCTION(set_adjustments, adjustment, adjustment);
NAME_ARGS(xadjustment,yadjustment);
// Change the adjustments (as supplied to the constructor) to other
// adjustments.
COMPLEX_FUNCTION(set_point, int);
NAME_ARGS(point);
// Set the insertion point.
int COMPLEX_FUNCTION(get_point);
int COMPLEX_FUNCTION(get_length);
SIMPLE_FUNCTION(freeze);
// Stop all updates of the widget. This is very useful if you plan to
// do a lot of modifications all at once.
SIMPLE_FUNCTION(thaw);
// unfreeze the widget.
FUNCTION(insert, "function(string,void|object,void|object,void|object:object)");
ARGS(string,GDK.Font,GDK.Color,GDK.Color);
RETURNS(GTK.Text);
NAME_ARGS(string,font,bg,fg);
// syntax:<p>
// object insert(string what); OR<br>
// object insert(string what, GDK.Font font, GDK.Color fg, GDK.Color bg); OR<br>
// object insert(string what, 0, GDK.Color fg, GDK.Color bg); OR<br>
// object insert(string what, 0, GDK.Color fg); OR<br>
// object insert(string what, 0, 0, GDK.Color bg);<br>
// <p>
//
// Insert new text, optionally with colors. BEWARE: in GTK 1.0.4, if
// you insert a text that ends with a newline with colors on it, the
// text widget will crash the next time you insert any text. This is
// easily bypassed, simply add the newline to the beginning of the
// next text inserted instead.
{
  struct svalue *a, *b, *c;
  struct pike_string *s;
  GdkFont *font = 0;
  GdkColor *fg=0, *bg=0;
  if(args == 4)
  {
    get_all_args("insert", args, "%S%*%*%*", &s,&a,&b,&c);

    if(a->type == T_OBJECT)
      font = get_gdkobject( a->u.object,Font );
    
    if(b->type == T_OBJECT)
      fg = get_gdkobject( b->u.object,Color );

    if(c->type == T_OBJECT)
      bg = get_gdkobject( c->u.object,Color );
  } else
    get_all_args("insert", args, "%S", &s);
    
  gtk_text_insert( GTK_TEXT( THIS->obj ), font, fg, bg, s->str, s->len );

  RETURN_THIS();
}

COMPLEX_FUNCTION(backward_delete, int);
NAME_ARGS(nchars);
// Delete n characters backwards from the cursor position
COMPLEX_FUNCTION(forward_delete, int);
NAME_ARGS(nchars);
// Delete n characters forward from the cursor position

FUNCTION(set_text, "function(string:object)")
NAME_ARGS(to);
// Set the text to the specified string.
{
  gtk_text_freeze( GTK_TEXT( THIS->obj ) );
  gtk_text_set_point( GTK_TEXT( THIS->obj ), 0 );
  gtk_text_forward_delete( GTK_TEXT( THIS->obj ), 
			   gtk_text_get_length( GTK_TEXT( THIS->obj ) ) );
  pgtk_text_insert( 1 );
  gtk_text_thaw( GTK_TEXT( THIS->obj ) );
  RETURN_THIS();
}

FUNCTION(get_text, "function(void:string)")
// Get the current contents of the text object.
{
  struct pike_string *res;
  unsigned int i;
  pop_n_elems(args);
  res = begin_shared_string( gtk_text_get_length( GTK_TEXT( THIS->obj ) ) );
  for(i=0; i<(unsigned int)res->len; i++)
    res->str[i] = GTK_TEXT_INDEX( GTK_TEXT( THIS->obj ), i );
  push_string( end_shared_string( res ) );
}

/* FIXME: Wide string support! */
