 /*
  * Khoros: $Id: createform.c,v 1.5 1992/03/20 22:47:29 dkhoros Exp $
  */

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

 /*
  * $Log: createform.c,v $
 * Revision 1.5  1992/03/20  22:47:29  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 "forms.h"

/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>             file name: createform.c                   <<<<
   >>>>                                                       <<<<
   >>>>             User Interface Creation Routines          <<<<
   >>>>                                                       <<<<
   >>>>       These routines create and map the widgets       <<<<
   >>>>       that make up the xvforms graphical user 	      <<<<
   >>>>       interface.        			      <<<<
   >>>>                                                       <<<<
   >>>>			xvf_create_subform()		      <<<<
   >>>>			xvf_create_guidepane()		      <<<<
   >>>>			xvf_create_pane()		      <<<<
   >>>>			xvf_create_toggle()		      <<<<
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  */


/************************************************************
*
* Routine Name:  xvf_create_subform
*
*      Purpose:  Performs the creation of a subform of 
*		 a graphical user interface;  assumes that the rest of
*		 the form tree and has already been created, and 
*		 the only thing left to do is create and
*		 record the appropriate widgets on this subform.
*
*        Input:  database - pointer to the internal database struct
*		 form     - pointer to the form tree
*		 subform  - pointer to this subform branch of the form tree
*		 guide    - pointer to the matching guide button for this pane
*		 pane     - pointer to this pane struct
*	         
*       Output:  creates the widgets associated with this subform.
*		 returns TRUE on success, FALSE on failure
*
*   Written By:  Danielle Argiro
*
*************************************************************/
extern int last_guide_index;

int xvf_create_subform(database, form, subform, mapped)
char             *database[];
xvf_form         *form;
xvf_sub_form     *subform;
int		  mapped;
{
	int              i, xvf_index;
        Line_Info        line_info;
	xvf_guide_button *guide;
	Arg		 args[MaxArgs];
        char		 geometry[MaxLength], name[MaxLength];
static  int count = 0;

        xvf_clear_line_info(&line_info);
	xvf_index = subform->index;
	last_guide_index = xvf_index;

        if (!(xvf_parse_startsubform_line(database[xvf_index], &line_info)))
              return(false);

	/* create the subform's toplevel name */
	if (client_cantata)
	    sprintf(name, "%s_%s_subform_%d", form->toplevel_name, 
                    line_info.variable, count++);
	else
	    sprintf(name,"%s_%s_subform", form->toplevel_name, 
		    line_info.variable);
	subform->toplevel_name = xvf_strcpy(name);

        i = 0;
        XtSetArg(args[i], XtNscreen, xvf_screen); 			i++;
        XtSetArg(args[i], XtNargc, xvf_ac);            			i++;
        XtSetArg(args[i], XtNargv, xvf_av);            			i++;
        XtSetArg(args[i], XtNinput, true);             			i++;
        XtSetArg(args[i], XtNtitle, line_info.variable); 		i++;
        XtSetArg(args[i], XtNcursor, xvf_cursor);      			i++;
        XtSetArg(args[i], XtNallowShellResize, True);  			i++;
        XtSetArg(args[i], XtNwidth, line_info.width*xvf_font_width);    i++;
        XtSetArg(args[i], XtNheight, line_info.height*xvf_font_height); i++;
	XtSetArg(args[i], XtNwinGravity, StaticGravity);		i++; 
        if (form->toplevel == NULL && (xvf_x != -1 && xvf_y != -1))
        {
            (void) sprintf(geometry,"+%d+%d", xvf_x, xvf_y);
            XtSetArg(args[i], XtNgeometry, geometry);   		i++;
        }
        if (xvf_visual != NULL)
        {
            XtSetArg(args[i], XtNvisual, xvf_visual);         		i++;
        }
        if (xvf_colormap != NULL)
        {
            XtSetArg(args[i], XtNcolormap, xvf_colormap);     		i++;
        }
        subform->toplevel = XtAppCreateShell(name, xvf_cap_first_letter(name),
                             applicationShellWidgetClass, xvf_display, args, i);
        xvf_realize_widget(subform->toplevel);

        subform->back = xvf_create_backplane(&(subform->label),
                                      &line_info, subform->toplevel,
                                      &(subform->back_name),
                                      &(subform->label_name), mapped);
        if (subform->back == NULL)
        {
            fprintf(stderr, "xvf_create_subform:\n");
            fprintf(stderr, "    ERROR: Could not create form backplane\n");
            fprintf(stderr, "           Aborting form creation\n");
            return(false);
        }

	if ((subform->guide_button != NULL) && 
            (subform->guide_button->index != -1))  /* there is a guide pane */
        {
	      if (!(xvf_create_guidepane(database, form, subform)))
                return(false);
	}

	/* 
	 * search for any workspaces on pane that would mean that
         * pane needs to be created
         */
	guide = subform->guide_button;
	while (guide != NULL)
	{
	    if (guide->pane != NULL)
            {
		if (detect_workspace_on_pane(database, guide->pane))
		{
		    if (!(xvf_create_pane(database, form, subform,
                                       guide, guide->pane, guide->selected)))
                        return(false);
		}
	    }
	    guide = guide->next_button;
	}


	/* 
	 * search for a "true" guide button that is selected -
	 * map it's pane, and highlight the button.
         */
	guide = subform->guide_button;

	if (guide != NULL)
	{
	    while (((guide->type != GuideButton) || (guide->index == -1)
	          || (guide->selected != true)) && (guide->next_button != NULL))
	       guide = guide->next_button;
        }

	if (guide != NULL)
	{
	    if ((guide->selected) && (guide->pane->back == NULL)) 
            {
		if (!(xvf_create_pane(database, form, subform,
                                       guide, guide->pane, true)))
                        return(false);
                guide->pane->count++;
            }
	}

	if (subform->glyph_type != NONE)
	   subform->glyph_wid = xvf_subform_create_glyph_sel(form, subform);

	return(true);
}

/************************************************************
*
* Routine Name:  xvf_create_guidepane
*
*      Purpose:  Performs the creation of a guide pane on a subform of 
*		 a graphical user interface;  assumes that the rest of
*		 the form tree and has already been created, and 
*		 the only thing left to do is create and
*		 record the appropriate widgets on the guide pane.
*
*        Input:  database - pointer to the internal database struct
*		 form     - pointer to the form tree
*		 subform  - pointer to this subform branch of the form tree
*	         
*       Output:  creates the widgets associated with this guide pane.
*		 returns TRUE on success, FALSE on failure
*
*   Written By:  Danielle Argiro
*
*************************************************************/

xvf_create_guidepane(database, form, subform)
char             *database[];
xvf_form         *form;
xvf_sub_form     *subform;
{
	int done, flag, xvf_index;
        Line_Info line_info;
        xvf_guide_button *current;
	int  help_num=0, quit_num=0, blank_num=0;

        done = false;
        xvf_clear_line_info(&line_info);
	xvf_index = subform->guide_index; 

	if (!(xvf_parse_startguide_line(database[xvf_index], &line_info)))
                    return(false);

	subform->guide_back = xvf_create_backplane(&(subform->guide_label),
                              &line_info, subform->back,
                              &(subform->guide_back_name),
			      &(subform->guide_label_name), true);
        if (subform->guide_back == NULL)
        {
            fprintf(stderr, "xvf_create_guidepane:\n");
            fprintf(stderr, "   ERROR: Could not create guide backplane\n");
            fprintf(stderr, "          Aborting form creation\n");
            return(false);
        }
        xvf_index++;
	
        /*
         * current is our most current guide button structure.
         */
	current = subform->guide_button;

        while (!done)
        {
            /*
             *  see what type of line we have
             */
             flag = xvf_get_line_type(database[xvf_index]);

             switch (flag) {

                case GuideButton:
                     current->button = xvf_create_guide_sel(form, subform, 
				       current, database, &xvf_index, 
				       subform->guide_back,
                                       &(current->button_name));
                     if (current->button == NULL) 
		     {
                     	 fprintf(stderr, "xvf_create_guidepane:\n");
                         fprintf(stderr, "   ERROR: Couldn't create");
                         fprintf(stderr, " create guidebutton widget\n");
                         fprintf(stderr, "          Aborting form creation\n");
                         return(false);
                     }
		     if (current->selected == true)
			xvf_reverse_colors(current->button);
		     break;

                case QuitForm:

                     current->button = xvf_create_quit_subform_sel(form, 
				       subform, current, database, 
				       &xvf_index, subform->guide_back, quit_num,
                                       &(current->button_name));
                     if (current->button == NULL) 
		     {
                         fprintf(stderr,"xvf_create_guidepane:\n");
                         fprintf(stderr,"    ERROR: Couldn't create ");
                         fprintf(stderr,"quit button widget\n");
                         fprintf(stderr, "         Aborting form creation\n");
                         return(false);
                     }
                     quit_num++;
		     break;

                case SubformAction:
		     current->button = xvf_create_subform_action_sel(form, 
				       subform, current, database, 
				       &xvf_index, subform->guide_back,
                                       &(current->button_name));
                     if (current->button == NULL) 
		     {
                         fprintf(stderr,"xvf_create_guidepane:\n");
                         fprintf(stderr,"    ERROR: Couldn't create subform");
                         fprintf(stderr," action button widget\n");
                         fprintf(stderr,"           Aborting form creation\n");
                         return(false);
                     }
		     break;

                case HelpSel:
                     current->button = xvf_create_help_sel(form, subform, 
				       current, NULL, database, &xvf_index, 
				       subform->guide_back, help_num,
                                       &(current->button_name), 2, False);
                     if (current->button == NULL) 
		     {
                         fprintf(stderr,"xvf_create_guidepane:\n");
                         fprintf(stderr,"    ERROR: Couldn't create help");
                         fprintf(stderr," button widget\n");
                         fprintf(stderr,"           Aborting form creation\n");
                         return(false);
                     }
		     help_num++;
		     break;

		case WorkWidget:
		     current->button = xvf_create_workspace_sel(database, 
				       &xvf_index, NULL, current, NULL, 
				       subform->guide_back);

                     /* error check */
                     if (current->button == NULL) 
		     {
                         fprintf(stderr,"xvf_create_guidepane:\n");
                         fprintf(stderr,"   ERROR: Couldn't create workspace");
                         fprintf(stderr," widget\n");
                         fprintf(stderr,"          Aborting form creation\n");
                         return(false);
                     }
		     break;

                case Blank:
                     current->button = xvf_create_blank_sel(database,&xvf_index,
                                                 subform->guide_back,
						 blank_num, NULL, 2);
                     blank_num++;
		     break;

		case LibCall:
		     break;

                case End:
                     done = true;
                     break;

		default:
                     fprintf(stderr,"xvf_create_guidepane:\n");
		     fprintf(stderr,"   ERROR: UIS line in wrong place:\n");
                     fprintf(stderr,"   %s\n",database[xvf_index]);
		     return(false);
                     break;
		}
		xvf_index++;
		if (!done) current = current->next_button;
	}
	return(true);
}

/************************************************************
*
* Routine Name:  xvf_create_pane
*
*      Purpose:  Performs the creation of a "pane" on a subform of 
*		 a graphical user interface;  assumes that the rest of
*		 the pane structure of the form tree and its
*		 selection list has already been created, and 
*		 the only thing left to do is create and
*		 record the appropriate widgets.
*
*        Input:  database - pointer to the internal database struct
*		 form     - pointer to the form tree
*		 subform  - pointer to this subform branch of the form tree
*		 guide    - pointer to the matching guide button for this pane
*		 pane     - pointer to this pane struct
*	         
*       Output:  creates the widgets associated with this pane.
*		 returns TRUE on success, FALSE on failure
*
*   Written By:  Danielle Argiro
*
*************************************************************/


int xvf_create_pane(database, form, subform, guide, pane, mapped)
char             *database[];
xvf_form         *form;
xvf_sub_form     *subform;
xvf_guide_button *guide;
xvf_pane         *pane;
int		  mapped;
{
	int  flag, done, xvf_index, mutual_exclusion;
	int  help_num=0, quit_num=0, blank_num=0;
	int  doing_toggle = false;
	Line_Info line_info;
	xvf_selection *current, *toggle;

	mutual_exclusion = false;
	xvf_clear_line_info(&line_info);
	xvf_index = pane->index;

	/* parse the StartPane line */
        if (!(xvf_parse_startpane_line(database[xvf_index],&line_info)))
                         return(false);
	xvf_index++;

	pane->back = xvf_create_backplane(&(pane->label_widget),
                          &line_info, subform->back,
                          &(pane->back_name), &(pane->label_name), mapped);

	/* error check: if pane back successfully created */
        if (pane->back == NULL)
        {
            fprintf(stderr, "xvf_create_pane:\n");
            fprintf(stderr, "   ERROR: Could not create pane backplane\n");
            fprintf(stderr, "          Aborting form creation\n");
            return(false);
        }
	
	done = false;
	current = pane->sel_list;
	XawFormDoLayout(pane->back, (Boolean) false);

	while (!done)
        {
            /*
             *  see what type of line we have
             */
            flag = xvf_get_line_type(database[xvf_index]);

	    switch(flag)
	    {
	    case InputFile:
		 current->back  = xvf_create_input_sel(form, subform, guide,
                                     current, database, &xvf_index,
                                     pane->back, doing_toggle,NULL);
		 if (current->back  == NULL) return (false);
		 break;

	    case OutputFile:
		 current->back  = xvf_create_output_sel(form, subform,
                                     guide, current, database,&xvf_index,
                                     pane->back, doing_toggle,NULL);
                 if (current->back  == NULL) return (false);
		 break;

	    case IntegerOpt:
                 current->back  = xvf_create_int_sel(form, subform, guide,
                                     current, database,&xvf_index, pane->back,
                                     doing_toggle,NULL);
                 if (current->back == NULL) return (false);
		 break;

	    case FloatOpt:
		 current->back = xvf_create_float_sel(form, subform,
                                     guide, current, database,&xvf_index,
                                     pane->back, doing_toggle,NULL);
                 if (current->back == NULL) return (false);
		 break;

	    case StringOpt:
                 current->back = xvf_create_string_sel(form,subform,guide,
                                     current, database, &xvf_index, pane->back,
                                     doing_toggle,NULL);
                 if (current->back == NULL) return (false);
		 break;

            case LogicOpt:
		 current->back = xvf_create_logic_sel(form, subform,
                                     guide, current, database, &xvf_index,
                                     pane->back, doing_toggle,NULL);
                 if (current->back == NULL) return (false);
		 break;

	    case Routine:
                 current->value_widget = xvf_create_routine_sel(form,
                                       subform, guide, current,
                                       database, &xvf_index,pane->back,
                                       &(current->back_name));
                 if (current->value_widget == NULL) return (false);
		 break;

	    case Cycle:
		 current->back = xvf_create_cycle_sel(form,
                                     subform, guide, current,
                                     database, &xvf_index,pane->back,
                                     &(current->back_name));
                 if (current->value_widget == NULL) return (false);
		 break;

	    case List:
		 current->back = xvf_create_list_sel(form,
                                     subform, guide, current,
                                     database, &xvf_index,pane->back,
                                     &(current->back_name));
		 if (current->value_widget == NULL) return (false);
		 break;

	    case Toggle:
                 current->back = xvf_create_toggle_sel(form,subform,guide,
                                     current, database,&xvf_index, pane->back);
                 if (current->back == NULL) return (false);

		 xvf_index++;
		 if (!(xvf_create_toggle(form, subform, guide, current, 
					 database, &xvf_index)))
			return(false);
		 xvf_index--;
		 break;

	    case MutExcl:
                 mutual_exclusion = true;
                 break;


	    case HelpSel:
                 current->value_widget = xvf_create_help_sel(form,
                                       subform, guide, current,
                                       database, &xvf_index,
                                       pane->back, help_num,
                                       &(current->back_name), 3, False);
                 if (current->value_widget == NULL) return (false);
                 help_num++;
	         break;

            case WorkWidget:
                 current->value_widget = xvf_create_workspace_sel(database, 
				       &xvf_index, NULL, NULL, current, 
				       pane->back);
                 if (current->value_widget == NULL) return(false);
		 break;

	    case PaneAction:
                 current->value_widget = xvf_create_pane_action_sel(
                                       form, subform, guide,
                                       current, database, &xvf_index,
                                       pane->back, &(current->back_name));
                 if (current->value_widget == NULL) return(false);
		 break;



            case Blank:
                 current->value_widget = xvf_create_blank_sel(database,
                                       &xvf_index,pane->back, blank_num,
                                       &(current->back_name), 0);
                 if (current->value_widget == NULL) return(false);
		 blank_num++;
		 break;

	     case QuitForm:
                  current->value_widget = xvf_create_quit_pane_sel(form,
                                        subform, guide, current,
                                        database, &xvf_index, pane->back,
                                        quit_num, &(current->back_name));
                  if (current->value_widget == NULL) return(false);
                  quit_num++;
		  break;

	    case AnswerInfile:
		 current->back  = xvf_create_ansinfile_sel(form, subform, 
				  guide, current, database, &xvf_index,
                                  pane->back);
		 if (current->back  == NULL) return (false);
		 break;

	    case AnswerOutfile:
		 current->back  = xvf_create_ansoutfile_sel(form, subform, 
				  guide, current, database, &xvf_index,
                                  pane->back);
		 if (current->back  == NULL) return (false);
		 break;

	    
	     case End:
                  if (mutual_exclusion)
		      mutual_exclusion = false;
		  else done = true;
		  break;

	     default:
                     fprintf(stderr,"xvf_create_pane:\n");
                     fprintf(stderr,"   ERROR: UIS line in wrong place.\n");
                     fprintf(stderr,"   %s\n",database[xvf_index]);
		     return(false);
                     break;

	     }

	    if ((flag != MutExcl) && (flag != End))
            {
	       if (!done) current = current->next;
	    }
            (xvf_index)++;

        }
	
        current = pane->sel_list;
        while (current != NULL)
        {
            if((current->opt_selected==true)& (current->opt_widget!=NULL))
                xvf_reverse_colors(current->opt_widget);
            if (current->toggle_next != NULL)
            {
                toggle = current->toggle_next;
                while (toggle != NULL)
                {
                    if ((toggle->opt_selected==true) &&
                          (toggle->opt_widget!=NULL))
                          xvf_reverse_colors(toggle->opt_widget);
                    toggle = toggle->next;
                }
            }
            current = current->next;
        }
	XawFormDoLayout(pane->back, (Boolean) true);
        return(true);
}


/************************************************************
*
* Routine Name:  xvf_create_toggle
*
*      Purpose:  Performs the creation of a toggle on a pane of 
*		 a graphical user interface;  assumes that the 
*		 toggle list has already been created, and 
*		 the only thing left to do is create and
*		 record the appropriate widgets.
*
*        Input:  
*		 form     - pointer to the form tree
*		 subform  - pointer to this subform branch of the form tree
*		 guide    - pointer to the matching guide button for this pane
*		 toggle_start - pointer to head of the toggle list
*		 database - pointer to the internal database struct
*		 xvf_index - pointer to the current index into the database
*	         
*       Output:  creates the widgets associated with this pane.
*		 returns TRUE on success, FALSE on failure
*
*   Written By:  Danielle Argiro
*
*************************************************************/

int xvf_create_toggle(form, subform, guide, toggle_start, database, xvf_index)

xvf_form        *form;
xvf_sub_form    *subform;
xvf_guide_button *guide;
xvf_selection   *toggle_start;
char            *database[];
int             *xvf_index;
{
	int done=false, flag, doing_toggle = true, blank_num=0;
        xvf_selection *current;
	Widget parent;
	
	parent = XtParent(toggle_start->label_widget);
	current = toggle_start->toggle_next;

	while (!done)
        {
	    flag = xvf_get_line_type(database[*xvf_index]);

	    switch (flag) {

                case InputFile:
                     current->back = xvf_create_input_sel(form, subform, 
					 guide, current, database, xvf_index, 
					 parent, doing_toggle, toggle_start);
                     if (current->back == NULL) return(false);
		     break;

		case OutputFile:
                     current->back = xvf_create_output_sel(form, subform,
                                         guide, current, database, xvf_index,
                                         parent, doing_toggle,toggle_start);
                     if (current->back == NULL) return(false);
		     break;

		case IntegerOpt:
                     current->back = xvf_create_int_sel(form, subform, 
					 guide, current, database, xvf_index, 
				 	 parent, doing_toggle,toggle_start);
                     if (current->back == NULL) return(false);
		     break;

                case FloatOpt:
                     current->back = xvf_create_float_sel(form, subform, 
					 guide, current, database, xvf_index, 
					 parent, doing_toggle,toggle_start);
                     if (current->back == NULL) return(false);
		     break;

		case StringOpt:
                     current->back = xvf_create_string_sel(form, subform, 
					 guide, current, database, xvf_index, 
					 parent, doing_toggle, toggle_start);
                     if (current->back == NULL) return(false);
		     break;

		case LogicOpt:
                     current->back = xvf_create_logic_sel(form, subform, 
					 guide, current, database, xvf_index, 
				         parent, doing_toggle, toggle_start);
                     if (current->back == NULL) return(false);
		     break;

		case Blank:
                     current->back = xvf_create_blank_sel(database, xvf_index,
                                          parent, blank_num, NULL, 0);
                     blank_num++;
		     break;
	
		case End:
                     done = true;
                     break;

                default:
		     fprintf(stderr, "xvf_create_toggle:\n");
                     fprintf(stderr, "   ERROR: UIS line in wrong place.\n");
                     fprintf(stderr, "   %s\n",database[*xvf_index]);
		     return(false);
                     break;
		}
		*xvf_index = *xvf_index+1;
	        if (!done) current = current->next;
	}

	return(true);
}

detect_workspace_on_pane(database, pane)
char **database;
xvf_pane *pane;
{
	int index, flag;
	Line_Info line_info;
	xvf_selection *current;

	xvf_clear_line_info(&line_info);

	current = pane->sel_list;
	while (current != NULL)
	{
	   flag = xvf_get_line_type(database[current->index]);
	   if (flag == WorkWidget)
		return(true);
	   current = current->next;
	}
        return(false);
}
