
/*
 * dialog.c --
 *
 * This file implements the gnome dialog and messageBox widget
 *
 * Copyright (c) 2001 - 2002 P.G. Baum
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 */

/*
   History:
   2001-05: Begin of developement
 */

#include "gnocl.h"
#include <string.h>
#include <assert.h>

typedef struct
{
   Gnocl_StringBool child;    /* either child or text */
   Gnocl_ObjBool    text;
   Gnocl_StringBool parent;
   Gnocl_IntBool    defaultBut;
   Gnocl_ObjBool    type;
   Gnocl_BoolBool   modal;
} DialogParams;

static const GnoclWidgetOptions dialogOptions[] =
{
   { "-child", GNOCL_STRING, GNOCL_OFFSET( DialogParams, child ) },
   { "-text", GNOCL_OBJ, GNOCL_OFFSET( DialogParams, text ) },
   { "-parent", GNOCL_STRING, GNOCL_OFFSET( DialogParams, parent ) },
   { "-default", GNOCL_INT, GNOCL_OFFSET( DialogParams, defaultBut ) },
   { "-type", GNOCL_OBJ, GNOCL_OFFSET( DialogParams, type ) },
   { "-modal", GNOCL_BOOL, GNOCL_OFFSET( DialogParams, modal ) },
   { NULL, 0, 0 }
};

int gnoclDialogCmd( ClientData data, Tcl_Interp *interp,
      int objc, Tcl_Obj * const objv[] )
{
   char *types[] = { "none", "info", "warning", "error", "question",
         "generic", NULL };

   DialogParams pp;
   GnomeDialog  *dialog;
   int          n, noButtons;
   GtkWidget    *child = NULL;
   GtkWindow    *parent = NULL;
   int          typeIdx = 0;
   int          ret;

   if( objc < 3 )
   {
      Tcl_WrongNumArgs( interp, 1, objv, "title buttons ?option val ...?" );
      return TCL_ERROR;
   }
   memset( &pp, 0, sizeof( pp ) );
   if( gnoclParseAllWidgetOpts( interp, objc, objv, 2,
         dialogOptions, (char *)&pp ) != TCL_OK )
      return TCL_ERROR;

   if( Tcl_ListObjLength( interp, objv[2], &noButtons ) != TCL_OK 
         || noButtons < 1 )
   {
      Tcl_SetResult( interp, "button-list must be proper list", 
            TCL_STATIC );
      return TCL_ERROR;
   }
   if( pp.text.changed && pp.child.changed )
   {
      Tcl_SetResult( interp, "either \"text\" or \"child\" may be specified", 
            TCL_STATIC );
      return TCL_ERROR;
   }
   
   if( pp.type.changed )
   {
      if( Tcl_GetIndexFromObj( interp, pp.type.val, types, "type",
            TCL_EXACT, &typeIdx ) != TCL_OK )
         return TCL_ERROR;
   }

   if( pp.text.changed )
   {
      child = gtk_label_new( gnoclGetString( pp.text.val ) );
   }
   else if( pp.child.changed )
   {
      child = gnoclGetWidgetFromName( pp.child.val, interp );
      if( child == NULL )
         return TCL_ERROR;
   }

   if( pp.parent.changed )
   {
      GtkWidget *par = gnoclGetWidgetFromName( pp.parent.val, interp );
      if( par == NULL )
         return TCL_ERROR;

      parent = GTK_WINDOW( par );
      /* TODO: test this cast */
   }
   if( typeIdx == 0 )
   {
      dialog = GNOME_DIALOG( gnome_dialog_new( 
         gnoclGetString( objv[1] ), NULL ) );
   }
   else
   {
      dialog = GNOME_DIALOG( gnome_message_box_new( 
         gnoclGetString( objv[1] ), types[typeIdx], NULL ) );
   }

   for( n = 0; n < noButtons; ++n )
   {
      Tcl_Obj *pobj;
      const char *but = NULL;

      if( Tcl_ListObjIndex( interp, objv[2], n, &pobj ) != TCL_OK )
         return TCL_ERROR;
      if( gnoclGetStringType( pobj ) & GNOCL_STR_STOCK )
         but = gnoclGetStockButtonName( NULL, pobj );
      if( but == NULL )
         but = gnoclGetString( pobj );
      gnome_dialog_append_buttons( dialog, but, NULL );
   }

   if( child )
   {
      gtk_box_pack_start( GTK_BOX( dialog->vbox ), child, TRUE, TRUE, 0 );
      gtk_widget_show_all( GTK_WIDGET( dialog->vbox ) );
   }

   if( parent )
      gnome_dialog_set_parent( dialog, parent );

   if( pp.defaultBut.changed )
      gnome_dialog_set_default( dialog,  pp.defaultBut.val );

   if( pp.modal.changed )
      gtk_window_set_modal( GTK_WINDOW( dialog ), pp.modal.val );

   ret = gnome_dialog_run_and_close( dialog );

   Tcl_SetObjResult( interp, Tcl_NewIntObj( ret ) );

   return TCL_OK;
}

