 /*
  * Khoros: $Id: select.c,v 1.2 1992/03/20 22:49:28 dkhoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: select.c,v 1.2 1992/03/20 22:49:28 dkhoros Exp $";
#endif

 /*
  * $Log: select.c,v $
 * Revision 1.2  1992/03/20  22:49:28  dkhoros
 * VirtualPatch5
 *
  */ 

/*
 *----------------------------------------------------------------------
 *
 * Copyright 1990, University of New Mexico.  All rights reserved.
 * 
 * Permission to copy and modify this software and its documen-
 * tation only for internal use in your organization is hereby
 * granted, provided that this notice is retained thereon and
 * on all copies.  UNM makes no representations as too the sui-
 * tability and operability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 * 
 * UNM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
 * NESS.  IN NO EVENT SHALL UNM BE LIABLE FOR ANY SPECIAL,
 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY OTHER DAMAGES WHAT-
 * SOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PER-
 * FORMANCE OF THIS SOFTWARE.
 * 
 * No other rights, including for example, the right to redis-
 * tribute this software and its documentation or the right to
 * prepare derivative works, are granted unless specifically
 * provided in a separate license agreement.
 *----------------------------------------------------------------------
 */

#include "unmcopyright.h"	 /* Copyright 1990 by UNM */
#include "xvutils.h"	


/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>	    	    file name: select.c	                      <<<<
   >>>>                                                       <<<<
   >>>>		  Create a Select Widget		      <<<<
   >>>>                                                       <<<<
   >>>>                xvf_select_wait()		      <<<<              
   >>>>                xvf_create_select()		      <<<<              
   >>>>                xvf_select_no()		      	      <<<<              
   >>>>                xvf_select_canc()		      <<<<              
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */


/************************************************************
*
*  Routine Name:  xvf_select_wait(stmt, label, button_labels, button_num)
*
*      Purpose:   creates a "select" form which has N choices, each returning
*		  (N-1) as a status.  For example, you might need a select
*		  widget that offers the user 5 choices: "Add", "Subtract",
*		  "Multiply", "Divide", or "Cancel".  If these were provided
*		  as button labels in the order given, the calling program
*		  would be returned 1 if the user clicks on "Add", 2 if the
*		  user clicks on "Subtract", and so on to a status of 5 when
*		  the user clicks on "Cancel".  A status of 0 is returned
*		  if the selection widget could not be created.
*
*                 NOTE: this routine will grab all events 
*                 while running.  
*
*        Input:   stmt     - string containing information
*			     for the user (may contain \n for
*                            returns, widget will put in
*                            returns as it needs).
*                 label    - short label for top of form.
*                            NULL will indicate use of default "EXITING".
*
*		  button_labels - array of strings to serve as button labels.
*		  button_num    - number of buttons to create, also size of
*				  the button_labels array.
*
*       Output:   SELECT_SIG (global variable) returned to caller will be:
*		       1 if user selected button1 
*		       2 if user selected button2 
*		       3 if user selected button3 
*		       N if user selected buttonN.
*		       0 if there was an error creating selection widget,
*			 or the user clicked on CANCEL.
*
*		  This routine will NOT return to the calling program until 
*		  one of the buttons is chosen.
*
*    Called By:   the application program
*
*   Written By:   Danielle Argiro
*
*************************************************************/

int xvf_select_wait(stmt, label, button_labels, button_num)
char *stmt;
char *label;
char **button_labels;
int   button_num;
{
   int xvf_create_select();

   SELECT_DONE = false;

   if (xvf_display == NULL)
   {
	fprintf(stderr, "%s\n", stmt);
	return(true);
   }
   if (!(xvf_create_select(stmt, label, button_labels, button_num))) 
	return(false);

   while(!SELECT_DONE)
      xvf_process_event();      /* this does XtNextEvent/DispatchEvent*/

   return(SELECT_SIG);
}

/************************************************************
*
*  Routine Name:  xvf_create_select(select_prompt, select_label,
*				    button_labels, button_num)
*
*      Purpose:   Does the  actual creation of a selection widget. 
*		  The selection widget consists of a form widget with a 
*		  label, text, and and N acknowledgement buttons.
*
*        Input:   select_prompt - the message to appear on selection widget
*                 select_label  - short label for top of widget
*                                 NULL will casue default of "SELECT ONE"
*		  button_labels - array of strings for labelling buttons
*		  button_num    - number of buttons to create
*
*       Output:   False only if selection widget could not be created.
*
*    Called By:   xvf_select_wait() or the application program
*
*   Written By:   Danielle Argiro 
*
*************************************************************/

#define TEXT_WIDTH  35
#define TEXT_HEIGHT 7

typedef struct _Button_Info {
    Widget toplevel;
    int    status;
} Button_Info;

int xvf_create_select(select_prompt, select_label, button_labels, button_num)
char *select_prompt;
char *select_label;
char **button_labels;
int   button_num;
{
   Widget toplevel, back, label, offset, button, cancel;	
   Arg    arg[MaxArgs];
   int    i, j, width, height, total_width = 0;
   char   name[MaxLength];
   void   xvf_exit_select();
   Button_Info *button_info;

   /*
    *  error checks
    */
   if (button_num < 1)
   {
	fprintf(stderr, "xvf_create_select:\n");
	fprintf(stderr, "ERROR - button_num must be > 0\n");
	return(false);
   }
   else if (button_labels == NULL)
   {
	fprintf(stderr, "xvf_create_select:\n");
	fprintf(stderr, "ERROR - You MUST provide a valid button label\n");
	fprintf(stderr, "        for each of the %d buttons requested.\n", 
				 button_num);
	return(false);
   }
   else
   {
	for (i = 0; i < button_num; i++)
	{
	    if (button_labels[i] == NULL)
	    {
	        fprintf(stderr, "xvf_create_select:\n");
	        fprintf(stderr, "ERROR - ");
		fprintf(stderr, "You MUST provide a valid button label\n");
	        fprintf(stderr, "   for each of the %d buttons requested\n", 
				     button_num);
	        return(false);
	    }
	}
   }


   /*
    * create identifying widget name
    */
   sprintf(name,"%d_exit", Select_cnt);
   Select_cnt++;

   /*
    * create the selection box's toplevel widget, and add it
    * to the list of toplevels that is used with journal playback.
    */
   i = 0;
   XtSetArg(arg[i], XtNscreen, xvf_screen); 		  i++;
   XtSetArg(arg[i], XtNargc, xvf_ac); 	                  i++;
   XtSetArg(arg[i], XtNargv, xvf_av);	          	  i++; 
   XtSetArg(arg[i], XtNwinGravity, StaticGravity);	  i++; 
   toplevel = XtAppCreateShell(name, "khoros", transientShellWidgetClass, 
			       xvf_display, arg, i);
   xvf_add_toplevel(toplevel);

   /*
    * create the backplane widget
    */
   i = 0;
   XtSetArg(arg[i],XtNmappedWhenManaged,True);        	i++; 
   XtSetArg(arg[i],XtNborderWidth,1);			i++;
   XtSetArg(arg[i],XtNdefaultDistance,4);		i++;
   back = XtCreateManagedWidget("form_back", formWidgetClass, toplevel,arg,i);

   /* 
    * create the label widget 
    */
   i = 0;
   if(select_label != NULL)
   {
      XtSetArg(arg[i], XtNlabel, xvf_strcpy(select_label)); i++;
      width = (xvf_strlen(select_label)+1) + LEFT_MARGIN;
      total_width += width;
   }
   else
   {
      XtSetArg(arg[i], XtNlabel, xvf_strcpy("SELECT ONE:"));	i++;
      width = 11 + LEFT_MARGIN;
      total_width += width;
   }
   if (xvf_font != NULL)
   {
        XtSetArg(arg[i],XtNfont,xvf_font);              i++;
   }
   XtSetArg(arg[i], XtNmappedWhenManaged, True);	i++;
   XtSetArg(arg[i], XtNwidth,width*xvf_font_width);     i++;
   XtSetArg(arg[i], XtNborderWidth, 0);			i++;
   label = XtCreateManagedWidget("select_label", labelWidgetClass, 
				  back, arg, i);

   /* 
    * create desired number of buttons
    */

   offset = NULL;
   for (j = 0; j < button_num; j++)
   {
   	i = 0;
   	XtSetArg(arg[i], XtNfromVert, label);			   i++;
   	XtSetArg(arg[i], XtNfromHoriz, offset);			   i++;
        XtSetArg(arg[i], XtNlabel, xvf_strcpy(button_labels[j]));  i++;
        width = (xvf_strlen(button_labels[j])+1);
        total_width += width;
        if (xvf_font != NULL)
        {
            XtSetArg(arg[i],XtNfont,xvf_font);              	   i++;
        }
        XtSetArg(arg[i], XtNwidth, width*xvf_font_width);          i++;
	sprintf(name, "selbutton%d", j);
        button = XtCreateManagedWidget(name,  commandWidgetClass, 
				       back, arg, i);

	button_info = (Button_Info *) malloc (sizeof (Button_Info));
	button_info->toplevel = toplevel;
	button_info->status = j + 1;
        XtAddCallback(button, XtNcallback, xvf_select_cb, button_info);
	offset = button;
   }

   i = 0;
   XtSetArg(arg[i], XtNfromVert, label);			i++;
   XtSetArg(arg[i], XtNfromHoriz, offset);			i++;
   XtSetArg(arg[i], XtNlabel, xvf_strcpy("CANCEL"));  		i++;
   width = (6+1);
   total_width += width;
   if (xvf_font != NULL)
   {
       XtSetArg(arg[i],XtNfont,xvf_font);              	   i++;
   }
   XtSetArg(arg[i], XtNwidth, width*xvf_font_width);          i++;
   sprintf(name, "cancel");
   button = XtCreateManagedWidget(name, commandWidgetClass, back, arg, i);
   XtAddCallback(button, XtNcallback, xvf_select_cancel_cb, toplevel);

   /*
    * create the text widget 
    */
   total_width += 2;
   height = MAX(TEXT_HEIGHT, xvf_figure_height(select_prompt, total_width));

   i = 0;
   XtSetArg(arg[i], XtNeditType, XawtextRead);		i++;
   XtSetArg(arg[i], XtNstring, select_prompt);		i++;
   XtSetArg(arg[i], XtNresize, XawtextResizeHeight);	i++;
   XtSetArg(arg[i], XtNwrap,   XawtextWrapWord);	i++;
   XtSetArg(arg[i], XtNtype,   XawAsciiString);		i++;
   XtSetArg(arg[i], XtNheight,(Dimension) height*xvf_font_height);	i++;
   XtSetArg(arg[i], XtNwidth, (Dimension) total_width*xvf_font_width);	i++;
   XtSetArg(arg[i], XtNinsertPosition, 0);		i++;
   XtSetArg(arg[i], XtNfromVert, button);		i++;
   XtSetArg(arg[i], XtNleftMargin, LEFT_MARGIN);	i++;
   if (xvf_font != NULL)
   {
        XtSetArg(arg[i],XtNfont,xvf_font);              i++;
   }
   (void) XtCreateManagedWidget("text", asciiTextWidgetClass, back, arg, i);

   xvf_add_protocol_handler(toplevel, "WM_DELETE_WINDOW", 
			    xvf_select_cancel_cb, toplevel);
   xvf_place_widget(toplevel, NULL);
   return(true);
}

/*			*/
/* callback routines 	*/
/*			*/

void xvf_select_cb(widget, clientData, callData)
Widget widget;
caddr_t clientData, callData;
{
   Widget toplevel;
   Button_Info *button_info;

   button_info = (Button_Info *) clientData;

   /*
    * delete the error box's toplevel from the list 
    * used by journal playback before destroying it
    */
   xvf_delete_toplevel(button_info->toplevel);
   XtUnmapWidget(button_info->toplevel);
   XtDestroyWidget(button_info->toplevel);
   SELECT_DONE = true;
   SELECT_SIG = button_info->status;
}

void xvf_select_cancel_cb(widget, clientData, callData)
Widget widget;
caddr_t clientData, callData;
{
   Widget toplevel;

   toplevel = (Widget) clientData;
   xvf_remove_protocol_handler(toplevel, "WM_DELETE_WINDOW", 
			       xvf_exit_canc, toplevel);
   xvf_delete_toplevel(toplevel);
   XtUnmapWidget(toplevel);
   XtDestroyWidget(toplevel);
   SELECT_DONE = true;
   SELECT_SIG = 0;
}


