 /*
  * Khoros: $Id: cnd_drv.c,v 1.4 1992/03/20 22:45:19 dkhoros Exp $
  */

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

 /*
  * $Log: cnd_drv.c,v $
 * Revision 1.4  1992/03/20  22:45:19  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 "conductor.h"  

/************************************************************
*
*  Routine Name: cnd_gen_driver
*
*      Purpose:  This routine creates a file called "form_drv.c" 
*
*        Input:  database : internal database struct
*
*       Called by: lconductor()
*
*       COMMENTS:  Note that this routine will *only* be called by libconductor
*                  if cnd_gen_forminfo (which creates the FormInfo structure)
*                  returns successfully.  This implies that all the detailed
*                  error checking of the database that is done in
*                  cnd_gen_forminfo is not necessary here, and need not be
*                  repeated.  Any errors in the database will be caught by
*                  cnd_gen_forminfo, and conductor will not get to this routine.
*
*   Written By:  Danielle Argiro 
*
*************************************************************/

Display *display;

int cnd_gen_driver(database, extract_flag, uis_file)

char **database;
int  extract_flag;
char *uis_file;
{
	int index, flag=0, first;
	int master_quit_button = false;
	char *form_var, *subform_var, *pane_var, *buffer, *fullpath; 
	char temp[512], resp;
 	FILE *fid, *tmpfile;
	int  master_form=false, sub_form=false, sub_form_num=0; 
	int  submenu = 0,non_excl = 0;
	int  subform_quit_button = false, pane_quit_button = false;
	Line_Info line_info;

        /*
	 *  first of all, if 'form_drv.c' exists, see if they want to over-
	 *  write it.  If not, return immediately.
	 */
        fullpath = vfullpath("form_drv.c", NULL, NULL);
	if (!conductor->f)
        {
           if (tmpfile = fopen(fullpath, "r"))
           {
              fprintf(stderr, "\nOverwrite file '%s'?  [y/n]: ", fullpath);
              fgets(temp, MaxLength, stdin);
              sscanf(temp, "%c", &resp);
              if ((resp != 'y') && (resp != 'Y')) 
	          return(true);
           }
        }

	/*
	 * create & open the temporary file which will have the 
	 * first part of the main driver
	 */
	if ((fid = fopen("drv_master", "w"))== NULL)
	{
		fprintf(stderr, "\ncnd_gen_getforminfo:\n");
		fprintf(stderr, "  Could not create tmp file 'drv_master'\n");
		return(false);
	}

	/* begin file with RCS header */
	fprintf(fid, " /*\n  * Khoros: %cId%c\n  */\n\n", '$', '$');
        fprintf(fid, "#if !defined(lint) && !defined(SABER)\n");
        fprintf(fid, "static char rcsid[] = \"Khoros: %cId%c\";\n", '$','$');
        fprintf(fid, "#endif\n\n");
        fprintf(fid, " /*\n  * %cLog%c\n  */\n\n", '$', '$');

	/* follow RCS header with UNM copyright */
        fprintf(fid, "%s", cp_top); 
        fprintf(fid, "%s", cp_line); 
        fprintf(fid, "%s", cp_right); 
        fprintf(fid, "%s", cp_line); 
        fprintf(fid, "%s", cp_bottom); 
		
	/* write to file the necessary #includes */
	fprintf(fid,"%s", include1);
	fprintf(fid,"%s", include5);
	fprintf(fid,"%s", include2);
	fprintf(fid,"%s", include4);

	index = 0;
	master_form = false;

	/* read the StartForm definition & get FormInfo variable name */
	xvf_clear_line_info(&line_info);
       	xvf_parse_startform_line(database[index], &line_info);
        if (line_info.variable == NULL)
        {
	    fprintf(stderr, "\ncnd_gen_getforminfo:\n");
	    fprintf(stderr, "Form does not have a variable name \n");
	    fprintf(stderr, "associated with it. Cannot generate \n");
	    fprintf(stderr, "correct code without this string.\n");
            unlink("./drv_master");
	    return(false);
        }
       	form_var = xvf_strcpy(line_info.variable);
	index++;
        
        
       
	/* Opening advice & comments to the user */
	fprintf(fid, "%s", cp_top);
	fprintf(fid, " * Advice for the user of this code:\n *\n");
	fprintf(fid, " * Note global declaration of 'display'! You may want to\n");
	fprintf(fid, " * to move this elsewhere... perhaps into a .h file...\n");
	fprintf(fid, " *\n");
	fprintf(fid, " * Also Note:  this driver for the forms is for use \n"); 
	fprintf(fid, " * with the code generated by 'ghostwriter'. The main\n"); 
	fprintf(fid, " * program generated by 'ghostwriter' has global declarations\n"); 
	fprintf(fid, " * for 'av', 'ac', and 'program', which will be necessary\n"); 
	fprintf(fid, " * in order to compile your program.\n"); 
	fprintf(fid, " *\n");
	fprintf(fid, " * If you are not using a main() generated by 'ghostwriter',\n"); 
	fprintf(fid, " * you will have to make these changes for this code to work:\n"); 
	fprintf(fid, " *\n");
	fprintf(fid, " *   1)  Change the name of the following routine to 'main(argc, argv)'.\n");
	fprintf(fid, " *   2)  Globally declare the following:\n");
	fprintf(fid, " *       char  **av,\n");
	fprintf(fid, " *             *program,\n");
	fprintf(fid, " *             *calloc(); \n");
	fprintf(fid, " *       int   ac; \n");
	fprintf(fid, " *\n");
	fprintf(fid, " *   3) At the beginning of the main, set:\n");
	fprintf(fid, " *       program = VStrcpy(argv[0]);\n");
	fprintf(fid, " *       ac = argc;  av = argv; \n");
	fprintf(fid, " *\n");
	fprintf(fid, " * If you are using a main() generated by 'ghostwriter',\n"); 
	fprintf(fid, " * you should include a call to 'run_%s' there.\n", form_var);
        fprintf(fid, " * Don't forget to delete 'program' out of the parameter list!\n");
	fprintf(fid, " * \n");
	fprintf(fid, " * Finally, you should IMMEDIATELY re-name this file\n");
	fprintf(fid, " * so that you will not accidentally over-write it\n");
	fprintf(fid, " * after you have modified it to your satisfaction!\n");
	fprintf(fid, " * \n");
	fprintf(fid, " * p.s. You should probably delete this long comment \n");
	fprintf(fid, " *      after reading/understanding it, too!\n");
	fprintf(fid, " *\n");
	fprintf(fid, "%s\n\n", cp_bottom);
	fprintf(fid, "Display *display;\n\n");

       	/* start out generated main with a header */
       	fprintf(fid, "%s%s", top_bdr, single_star); 
       	fprintf(fid, "%s run_%s\n", dr_name, form_var);
	fprintf(fid, "%s drives the master form\n", dr_purpose);
	fprintf(fid, "%s argc - number of arguments on command line\n", 
			dr_input);
	fprintf(fid, "*\t\t  argv  - arguments from command line\n");
	fprintf(fid, "%s action of the application program\n", dr_output);
	fprintf(fid, "%s the main application program\n", dr_call_by);
	fprintf(fid, "%s -i %s -l %d -b\n", author, uis_file, extract_flag);
       	fprintf(fid, "%s%s\n\n", single_star, bottom_bdr); 


       	/* write out program name & argument list */
       	fprintf(fid, "run_%s(argc, argv, program)\n", form_var);
       	fprintf(fid, "int 	argc;\n");
       	fprintf(fid, "char	*argv[];\n");
       	fprintf(fid, "char	*program;\n");
       
       	/* write out beginning bracket & declarations */
       	fprintf(fid, "{\n"); 
       	fprintf(fid, "\txvf_form  *form;\n");
       	fprintf(fid, "\t%s %s_info;\n", form_var, form_var);
       	fprintf(fid, "\tchar *form_filestring;\n");
       	fprintf(fid, "\tchar *form_pathname;\n\n");
       
	/* initialize display & forms */
	fprintf(fid, "\t%s", cp_top);
	fprintf(fid, "\t * initialize the display & the forms - \n");
	fprintf(fid, "\t * NOTE: assuming a global 'Display *display'\n");
	fprintf(fid, "\t%s", cp_bottom);
	fprintf(fid, "\tdisplay = xvf_initialize(ac, av, program);\n");
	fprintf(fid, "\tif (display == NULL)\n");
       	fprintf(fid, "\t{\n"); 
	fprintf(fid, "\t     fprintf(stderr, \"Could not open connection to server\");\n");
	fprintf(fid, "\t     exit(0);\n");
	fprintf(fid, "\t}\n\n");

	/* set the form filestring */
	fprintf(fid, "\t%s", cp_top);
	fprintf(fid, "\t * Substitute below the correct filename and directory path\n");
	fprintf(fid, "\t * of the User Interface Description file to be used\n");
	fprintf(fid, "\t%s", cp_bottom);
	fprintf(fid, "\tform_filestring = xvf_strcpy(\"your_filename.form\");\n");
	fprintf(fid, "\tform_pathname   = xvf_strcpy(\"your_filename_directory\");\n");
	fprintf(fid, "\tform_filestring = vfullpath(form_filestring, form_pathname, NULL);\n\n");

	/* create the forms */
	fprintf(fid, "\t%s", cp_top);
	fprintf(fid, "\t * Create the forms \n");
	fprintf(fid, "\t%s", cp_bottom);
	fprintf(fid, "\tif (!(form = xvf_create_form(form_filestring, av, ac, SIMPLE, NULL,\n");
	fprintf(fid,"\t\t\t\t     -1, -1)))\n");
	fprintf(fid, "\t   exit(0);\n\n");

	/* initialize the information structure */
	fprintf(fid, "\t%s", cp_top);
	fprintf(fid, "\t * Initialize the auto-generated information structure\n");
	fprintf(fid, "\t%s", cp_bottom);
	fprintf(fid, "\t_xvf_init_%s(form,  &%s_info);\n\n", form_var, form_var);

	/* start up forms */
	fprintf(fid, "\t%s", cp_top);
	fprintf(fid, "\t * Map the forms\n");
	fprintf(fid, "\t%s", cp_bottom);
	fprintf(fid, "\txvf_change_active(form, true);\n\n");

	/* beginning of user interface loop */
	fprintf(fid, "\tdo\n");
	fprintf(fid, "\t{\n");
	fprintf(fid, "\t     %s", cp_top);
	fprintf(fid, "\t      * run the forms\n");
	fprintf(fid, "\t     %s", cp_bottom);
	fprintf(fid, "\t     form = xvf_run_form();\n");
	fprintf(fid, "\t     if (form == NULL) break;\n\n");
	fprintf(fid, "\t     %s", cp_top);
	fprintf(fid, "\t      * get information from the master\n");
	fprintf(fid, "\t     %s", cp_bottom);
	fprintf(fid, "\t     _xvf_get_%s(form, &%s_info);\n\n", form_var, form_var);
	
	first = true;
	xvf_clear_line_info(&line_info);
	do
       	{

	    flag = xvf_get_line_type(database[index]);

	    
            switch(flag)
            {
		case StartMaster:
		     xvf_parse_startmaster_line(database[index], &line_info);
		     if (line_info.logical_val == false)
		         non_excl = true;
                     index++;
                     master_form = true;
                     break;
	
		case SubFormButton:
		case PsuedoSubForm:
		case WorkWidget:
                case HelpSel:
                case Blank:
                     index++;
                     break;

		case StartSubMenu:
		     index++;
		     submenu = true;
		     break;

	        case MasterAction:
		     xvf_parse_master_action_line(database[index], &line_info);

		     fprintf(fid, "\t     %s", cp_top);
		     fprintf(fid, "\t      * user clicked on master ");
		     fprintf(fid, " action button '%s'\n", line_info.variable);
		     fprintf(fid, "\t     %s", cp_bottom);

		     if (first || non_excl)
		         fprintf(fid, "\t     if (%s_info.%s)\n",
			         form_var, line_info.variable);
		     else
		         fprintf(fid, "\t     else if (%s_info.%s)\n",
			         form_var, line_info.variable);
	             first = false;
		     fprintf(fid, "\t     {\n");
		     fprintf(fid, gen_comm);
		     fprintf(fid, "\t     }\n\n");
       		     index++;
		     break;
			
		case QuitForm:
		     index++;
		     master_quit_button = true;
		     break;

		case End:
		     if (master_form == TRUE) 
                     {
                        index++;
                        flag = xvf_get_line_type(database[index]);
			if ((!submenu) && (!master_quit_button))
			{
			    fprintf(stderr, "\ncnd_gen_driver:\n");
			    fprintf(stderr, "Cannot generate driver properly ");
			    fprintf(stderr, "for a master form without \n");
			    fprintf(stderr, "a quit button.\n");
                            unlink("./drv_master");
                            unlink("./drv_subform");
			    return(false);
			}
                     }
                     break;

		case StartSubForm:

		     xvf_parse_startsubform_line(database[index], &line_info);
		     sub_form = true;
		     sub_form_num++;
		     if ((sub_form_num > 1) && (master_form != true))
		     {
			    fprintf(stderr, "\ncnd_gen_driver:\n");
			    fprintf(stderr, "Cannot generate driver properly ");
			    fprintf(stderr, "for >1  subforms without \n");
			    fprintf(stderr, "a master form.\n");
                            unlink("./drv_master");
                            unlink("./drv_subform");
			    return(false);
		     }
                     subform_var = xvf_strcpy(line_info.variable);

		     fprintf(fid, "\t     %s", cp_top);
		     fprintf(fid, "\t      * action came from the ");
		     fprintf(fid, "'%s' subform\n", subform_var);
		     fprintf(fid, "\t     %s", cp_bottom);

		     if (first || non_excl)
		         fprintf(fid, "\t     if (%s_info.%s_selected)\n",
			         form_var, subform_var);
		     else 
		         fprintf(fid, "\t     else if (%s_info.%s_selected)\n",
			         form_var, subform_var);
	             first = false;
		     fprintf(fid, "\t     {\n");
		     fprintf(fid, "\t\t  run_%s(form, %s_info.%s);\n", 
				subform_var, form_var, subform_var);
		     fprintf(fid, "\t     }\n\n");
                     index++;
                     if (!(cnd_gen_subform_driver(database,&index,
                	   form_var, subform_var, &pane_var, extract_flag, 
			   master_quit_button, &subform_quit_button,
		 	   &pane_quit_button, uis_file)))
		     {
                          unlink("./drv_master");
                          unlink("./drv_subform");
                          return(false); 
		     }

                     flag = xvf_get_line_type(database[index]);
                     break;

	    } 

	
	} while (flag != End); 

	fprintf(fid,"\n\txvf_clear_selections(form->db, form->line_num);\n"); 

	if (master_form == true)
	   fprintf(fid, "\t} while (!%s_info.quit);", form_var);   

	else if ((sub_form == true) && (subform_quit_button == true))
	{
	   if (extract_flag == 1) 
	      fprintf(fid, "\t} while (!%s_info.%s->quit);", 
		      form_var, subform_var);   
	   else 
	   {
	      fprintf(stderr, "\ncnd_gen_driver:\n");
	      fprintf(stderr, "When you use a quit button on a subform\n");
	      fprintf(stderr, "to exit the program, you must use a \n");
	      fprintf(stderr, "level 1 extraction [-l 1].\n");
 	      fprintf(stderr, "Cannot generate driver properly ");
	      fprintf(stderr, "- aborting creation of form_drv.c\n\n");
              unlink("./drv_master");
              unlink("./drv_subform");
	      return(false);
	   }

	}
	else 
	{
	    if (extract_flag == 1)
	       fprintf(fid, "\t} while (!%s_info.%s->%s->quit);",
                    form_var, subform_var, pane_var);
	    else
	    {
	       fprintf(stderr, "\ncnd_gen_driver:\n");
	       fprintf(stderr, "When you use a quit button on a pane\n");
	       fprintf(stderr, "to exit the program, you must use a \n");
	       fprintf(stderr, "level 1 extraction [-l 1].\n");
 	       fprintf(stderr, "Cannot generate driver properly ");
	       fprintf(stderr, "- aborting creation of form_drv.c\n\n");
               unlink("./drv_master");
               unlink("./drv_subform");
	       return(false);
	    }
	}


	fprintf(fid, "    /* end user interface loop */\n");
       	fprintf(fid, "\n}    /* end run_%s */\n\n", form_var);

        fclose(fid);


	buffer = xvf_strcpy("cat drv_master drv_subform > form_drv.c");
	system(buffer);
        unlink("./drv_master");
        unlink("./drv_subform");

       	fprintf(stderr, "\ncnd_gen_drivers:\n");
        fprintf(stderr, "Done with generating driver code, now in\n");
	fprintf(stderr, "'form_drv.c'\n");
       
        return(true);

}  /* end  cnd_gen_driver */
        


/************************************************************
*
*  Routine Name: cnd_gen_subform_driver
*
*      Purpose:  generates the code to get the values from each pane 
*		 from the database & put them into the appropriate 
*		 Form Info structure
*
*        Input:  database    - the internal database struct
*                index       - current index into the database
*                form_var    - name of the form variable
*                subform_var - name of the subform variable
*
*       Output:  appropriate subform initialization code
*                in the "form_init.c" file
*
*   Written By:  Danielle Argiro
*
*
*************************************************************/


int cnd_gen_subform_driver(database, index, form_var, 
			   subform_var, pane_variable, extract_flag, 
			   master_quit_button, subform_quit_button, 
			   pane_quit_button, uis_file)

char **database;
int  *index;
char *form_var;
char *subform_var;
char **pane_variable;
int  extract_flag;
int  master_quit_button;
int  *subform_quit_button;
int  *pane_quit_button;
char *uis_file;
{
	FILE *fid;
        Line_Info line_info;
	int       flag, first;
        int  guide_pane = 0, pane_num=0;
        char *buffer, *pane_var;

	/* 
	 * create & open the "subform_info" file which will have the 
	 * "form_info" structure definition 
	 */
	if ((fid = fopen("drv_subform", "a"))== NULL)
	{
		fprintf(stderr, "\ncnd_gen_get_subform_info:\n");
		fprintf(stderr, "  Could not create tmp file 'subform_info'\n");
		return(false);
	}

       	/* start out generated subform driver with a header */
       	fprintf(fid, "\n\n%s%s", top_bdr, single_star); 
       	fprintf(fid, "%s run_%s\n*\n", dr_name, subform_var);
	fprintf(fid, "%s drives the subform '%s'\n*\n", dr_purpose, subform_var);
	fprintf(fid, "%s form - pointer to the form tree \n", dr_input);
	fprintf(fid, "*\t\t  %s_info  - information structure for subform '%s'\n", subform_var, subform_var);
	fprintf(fid, "%s action of the application program\n*\n", dr_output);
	fprintf(fid, "%s run_%s()\n*\n", dr_call_by, form_var);
	fprintf(fid, "%s -i %s -l %d -b\n", author, uis_file, extract_flag);
	fprintf(fid, "%s%s\n\n", single_star, bottom_bdr); 
        
       	/* write out program name & argument list */

       	fprintf(fid, "run_%s(form, %s_info)\n\n", subform_var, subform_var);
       	fprintf(fid, "xvf_form *form;\n");
       	fprintf(fid, "%s_%s *%s_info;", form_var, subform_var, subform_var); 
	fprintf(fid, "\n");
       
       	/* write out beginning bracket & declarations */
       	fprintf(fid, "{\n\n"); 

	xvf_clear_line_info(&line_info);
	first = true;

	if (extract_flag != XVF_GET_ALL_LEVELS)  
	    fprintf(fid, "\t_xvf_get_%s(form, %s_info);\n\n", 
			 subform_var, subform_var);

        do
	{
	    flag = xvf_get_line_type(database[*index]);

            switch(flag)
            {
		case StartGuide:
                     (*index)++;
                     guide_pane = true;
                     break;

		case GuideButton:
		case Blank:
		case WorkWidget:
                case HelpSel:
                     (*index)++;
                     break;

		case SubformAction:
                     xvf_parse_subform_action_line(database[*index], &line_info);
		     fprintf(fid, "\t%s", cp_top);
		     fprintf(fid, "\t * user clicked on subform");
		     fprintf(fid, " action button '%s'\n", line_info.variable);
		     fprintf(fid, "\t%s", cp_bottom);

		     if (first == true)
		         fprintf(fid, "\tif (%s_info->%s)\n",
			         subform_var, line_info.variable);
		     else
		         fprintf(fid, "\telse if (%s_info->%s)\n",
			         subform_var, line_info.variable);
		     first = false;
		     fprintf(fid, "\t{\n");
		     fprintf(fid, gen_comm);
		     fprintf(fid, "\t}\n\n");
        	     (*index)++;
		     break;

		case QuitForm:
		     *subform_quit_button = true;
        	     (*index)++;
		     break;

		case End:
                     if (guide_pane == TRUE) /* skip over it */
                     {
                         (*index)++;
                         flag = xvf_get_line_type(database[*index]);
			 if (*subform_quit_button != true)
			 {
			    fprintf(stderr, "cnd_gen_driver:\n");
			    fprintf(stderr, "Cannot generate driver properly ");
			    fprintf(stderr, "for a guide pane without \n");
			    fprintf(stderr, "a quit button.\n");
			    return(false);
			 }
                     }
                     break;

		case StartPane:
        	     xvf_parse_startpane_line(database[*index], &line_info);
        	     pane_var = xvf_strcpy(line_info.variable);
		     *pane_variable = pane_var;
		     pane_num++;
		     if ((pane_num > 1) && (guide_pane != true))
		     {
			    fprintf(stderr, "cnd_gen_driver:\n");
			    fprintf(stderr, "Cannot generate driver properly ");
			    fprintf(stderr, "for > 1  panes on a subform \n");
			    fprintf(stderr, "without a guide pane.\n");
			    return(false);
		     }
		     fprintf(fid, "\t%s", cp_top);
		     fprintf(fid, "\t * action came from the ");
		     fprintf(fid, "'%s' pane\n", pane_var);
		     fprintf(fid, "\t%s", cp_bottom);

		     if (first == true)
		         fprintf(fid, "\tif (%s_info->%s_selected)\n",
			            subform_var, pane_var);
		     else
		         fprintf(fid, "\telse if (%s_info->%s_selected)\n",
			            subform_var, pane_var);

		     first = false;
		     fprintf(fid, "\t    run_%s(form, %s_info->%s);\n\n",
				pane_var, subform_var, pane_var, extract_flag);
         	     (*index)++;
		     if (!(cnd_gen_pane_driver(database, index,
                                               form_var, subform_var,
                                               pane_var, extract_flag, 
					       pane_quit_button, uis_file)))
                          return(false);

        	     flag = xvf_get_line_type(database[*index]);
		     break;

		} /* end switch */


	} while (flag != End);

        if ((pane_num == 1) && (*pane_quit_button != true)
	    && (master_quit_button != true))
        {
 	    fprintf(stderr, "cnd_gen_driver:\n");
	    fprintf(stderr, "Cannot generate driver properly ");
	    fprintf(stderr, "for a single pane on a subform \n");
	    fprintf(stderr, "without a quit button.\n");
	    return(false);
        }
	(*index)++;
        fprintf(fid, "\n}   /* end run_%s */\n\n\n\n", subform_var);
	fclose(fid);

	buffer = xvf_strcpy("cat drv_pane >> drv_subform");
	system(buffer);
        unlink("./drv_pane");
	return(true);


} /* end cnd_gen_subform_driver */
        		
/************************************************************
*
*  Routine Name: cnd_gen_pane_driver
*
*      Purpose:  generates the code to get the values from each pane 
*		 from the database & put them into the appropriate 
*		 Form Info structure
*
*        Input:  database    - the internal database struct
*                index       - current index into the database
*                form_var    - name of the form variable
*                subform_var - name of the subform variable
*                pane_var    - name of the pane variable
*
*
*       Output:  appropriate code to get values of pane parameters
*                in the "form_info.c" file
*
*   Written By:  Danielle Argiro
*
*
*************************************************************/

int cnd_gen_pane_driver(database, index, form_var, 
			subform_var, pane_var, extract_flag,
			pane_quit_button, uis_file)
char **database;
int  *index;
char *form_var;
char *subform_var;
char *pane_var;
int  extract_flag;
int  *pane_quit_button;
char *uis_file;
{
	FILE	  *fid;
        Line_Info line_info;
	int 	  save_index;


	/* 
	 * create & open the "pane_info" file which will have the 
	 * routines which get "pane_info" information 
	 */
	if ((fid = fopen("drv_pane", "a"))== NULL)
	{
		fprintf(stderr, "\ncnd_gen_get_pane_info:\n");
		fprintf(stderr, "  Could not create tmp file 'pane_info'\n");
		return(false);
	}

       	/* start out generated pane driver with a header */
       	fprintf(fid, "\n\n%s%s", top_bdr, single_star); 
       	fprintf(fid, "%s run_%s\n*\n", dr_name, pane_var);
	fprintf(fid, "%s drives the pane '%s'\n*\n", dr_purpose, pane_var);
	fprintf(fid, "%s form - pointer to the form tree \n", dr_input);
	fprintf(fid, "*\t\t  %s_info  - information structure for pane '%s'\n", pane_var, pane_var);
	fprintf(fid, "%s action of the application program\n*\n", dr_output);
	fprintf(fid, "%s run_%s()\n*\n", dr_call_by, subform_var);
	fprintf(fid, "%s -i %s -l %d -b\n", author, uis_file, extract_flag);
        fprintf(fid, "%s%s\n\n", single_star, bottom_bdr); 
        
       	/* write out program name & argument list */

       	fprintf(fid, "run_%s(form, %s_info)\n\n", pane_var, pane_var);
       	fprintf(fid, "xvf_form *form;\n");
       	fprintf(fid, "%s_%s *%s_info;", subform_var, pane_var, pane_var); 
	fprintf(fid, "\n");
       
       	/* write out beginning bracket & declarations */
       	fprintf(fid, "{\n\n"); 

	xvf_clear_line_info(&line_info);

	if (extract_flag == XVF_GET_PANES)
	    fprintf(fid, "\t_xvf_get_%s(form, %s_info);\n\n", pane_var, pane_var);
	
        save_index = *index;
        if (!(cnd_gen_pane_sels(fid, database, index, pane_var, 
				true, pane_quit_button)))
		return(false);

        if (!(cnd_gen_pane_sels(fid, database, &save_index, pane_var, 
				false, pane_quit_button)))
		return(false);
       	(*index)++;
	fprintf(fid, "\n\n}\n\n\n");
	fclose(fid);
	return(true);
	
}  /* cnd_gen_pane_driver */
        
        	
        
/************************************************************
*
*  Routine Name: cnd_gen_pane_driver
*
*      Purpose:  generates the code to get the values from each pane 
*		 from the database & put them into the appropriate 
*		 Form Info structure
*
*        Input:  database    - the internal database struct
*                index       - current index into the database
*                form_var    - name of the form variable
*                subform_var - name of the subform variable
*                pane_var    - name of the pane variable
*
*
*       Output:  appropriate code to get values of pane parameters
*                in the "form_info.c" file
*
*   Written By:  Danielle Argiro
*
*
*************************************************************/
        
int cnd_gen_pane_sels(fid, database, index, pane_var, 
			opt_flag, pane_quit_button)
FILE *fid;
char **database;
int  *index;
char *pane_var;
int   opt_flag;
int   *pane_quit_button;
{
        Line_Info line_info;
	int first = true, flag;
	int mutual_exclusion = false;

	xvf_clear_line_info(&line_info);
	do
       	{
	      flag = xvf_get_line_type(database[*index]);
       	      switch(flag) {
        
	      case InputFile:
       		   xvf_parse_input_line(database[*index], &line_info);
	           if ((line_info.optional == opt_flag) &&
		       ((line_info.live == true)||(line_info.optional == true)))
	 	   {
		       if (line_info.live == true)
		       {
		           fprintf(fid, "\t%s", cp_top);
		           fprintf(fid, "\t * user clicked on 'live' input file");
		           fprintf(fid, " selection '%s'\n", line_info.variable);
		           fprintf(fid, "\t%s", cp_bottom);
		       }
		       else 
		       {
		           fprintf(fid, "\t%s", cp_top);
		           fprintf(fid, "\t * user clicked on optional input file");
		           fprintf(fid, " selection '%s'\n", line_info.variable);
		           fprintf(fid, "\t%s", cp_bottom);
		       }

		       if ((first == true) || 
			   ((line_info.optional == true) && (opt_flag == true)))
		           fprintf(fid, "\tif (%s_info->%s_selected)\n",
		                    pane_var, line_info.variable);
		       else 
		           fprintf(fid, "\telse if (%s_info->%s_selected)\n",
		                   pane_var, line_info.variable);
		       first = false;
		       fprintf(fid, "\t{\n");
		       fprintf(fid, gen_comm);
		       fprintf(fid, "\t}\n\n");

		   }
       	           (*index)++;
       	           flag = xvf_get_line_type(database[*index]);
       		   break;

       	      case OutputFile:
       		   xvf_parse_output_line(database[*index], &line_info);
	           if ((line_info.optional == opt_flag) &&
		       ((line_info.live == true)||(line_info.optional == true)))
	 	   {
		       if (line_info.live == true)
		       {
		           fprintf(fid, "\t%s", cp_top);
		           fprintf(fid, "\t * user clicked on 'live' output file");
		           fprintf(fid, " selection '%s'\n", line_info.variable);
		           fprintf(fid, "\t%s", cp_bottom);
		       }
		       else 
		       {
		           fprintf(fid, "\t%s", cp_top);
		           fprintf(fid, "\t * user clicked on optional output file");
		           fprintf(fid, " selection '%s'\n", line_info.variable);
		           fprintf(fid, "\t%s", cp_bottom);
		       }

		       if ((first == true)  || 
			   ((line_info.optional == true) && (opt_flag == true)))
		           fprintf(fid, "\tif (%s_info->%s_selected)\n",
		                    pane_var, line_info.variable);
		       else
		           fprintf(fid, "\telse if (%s_info->%s_selected)\n",
		                   pane_var, line_info.variable);
		       first = false;
		       fprintf(fid, "\t{\n");
		       fprintf(fid, gen_comm);
		       fprintf(fid, "\t}\n\n");

		   }
       	           (*index)++;
       	           flag = xvf_get_line_type(database[*index]);
       		   break;

      	      case IntegerOpt:
       		   xvf_parse_int_line(database[*index], &line_info);
	           if ((line_info.optional == opt_flag) &&
		       ((line_info.live == true)||(line_info.optional == true)))
	 	   {
		       if (line_info.live == true)
		       {
		           fprintf(fid, "\t%s", cp_top);
		           fprintf(fid, "\t * user clicked on 'live' integer");
		           fprintf(fid, " selection '%s'\n", line_info.variable);
		           fprintf(fid, "\t%s", cp_bottom);
		       }
		       else 
		       {
		           fprintf(fid, "\t%s", cp_top);
		           fprintf(fid, "\t * user clicked on optional integer");
		           fprintf(fid, " selection '%s'\n", line_info.variable);
		           fprintf(fid, "\t%s", cp_bottom);
		       }

		       if ((first == true)  || 
			   ((line_info.optional == true) && (opt_flag == true))) 
		           fprintf(fid, "\tif (%s_info->%s_selected)\n",
		                    pane_var, line_info.variable);
		       else
		           fprintf(fid, "\telse if (%s_info->%s_selected)\n",
		                   pane_var, line_info.variable);
		       first = false;
		       fprintf(fid, "\t{\n");
		       fprintf(fid, gen_comm);
		       fprintf(fid, "\t}\n\n");

		   }
       	           (*index)++;
       	           flag = xvf_get_line_type(database[*index]);
       		   break;

       	      case FloatOpt:
       		   xvf_parse_float_line(database[*index], &line_info);
	           if ((line_info.optional == opt_flag) &&
		       ((line_info.live == true)||(line_info.optional == true)))
	 	   {
		       if (line_info.live == true)
		       {
		           fprintf(fid, "\t%s", cp_top);
		           fprintf(fid, "\t * user clicked on 'live' float");
		           fprintf(fid, " selection '%s'\n", line_info.variable);
		           fprintf(fid, "\t%s", cp_bottom);
		       }
		       else 
		       {
		           fprintf(fid, "\t%s", cp_top);
		           fprintf(fid, "\t * user clicked on optional float");
		           fprintf(fid, " selection '%s'\n", line_info.variable);
		           fprintf(fid, "\t%s", cp_bottom);
		       }

		       if ((first == true)  || 
			   ((line_info.optional == true) && (opt_flag == true)))
		           fprintf(fid, "\tif (%s_info->%s_selected)\n",
		                    pane_var, line_info.variable);
		       else
		           fprintf(fid, "\telse if (%s_info->%s_selected)\n",
		                   pane_var, line_info.variable);
		       first = false;
		       fprintf(fid, "\t{\n");
		       fprintf(fid, gen_comm);
		       fprintf(fid, "\t}\n\n");

		   }
       	           (*index)++;
       	           flag = xvf_get_line_type(database[*index]);
       		   break;

       	      case StringOpt:
       		   xvf_parse_string_line(database[*index], &line_info);
	           if ((line_info.optional == opt_flag) &&
		       ((line_info.live == true)||(line_info.optional == true)))
	 	   {
		       if (line_info.live == true)
		       {
		           fprintf(fid, "\t%s", cp_top);
		           fprintf(fid, "\t * user clicked on 'live' string");
		           fprintf(fid, " selection '%s'\n", line_info.variable);
		           fprintf(fid, "\t%s", cp_bottom);
		       }
		       else 
		       {
		           fprintf(fid, "\t%s", cp_top);
		           fprintf(fid, "\t * user clicked on optional string");
		           fprintf(fid, " selection '%s'\n", line_info.variable);
		           fprintf(fid, "\t%s", cp_bottom);
		       }

		       if ((first == true)  || 
			   ((line_info.optional == true) && (opt_flag == true)))
		           fprintf(fid, "\tif (%s_info->%s_selected)\n",
		                    pane_var, line_info.variable);
		       else
		           fprintf(fid, "\telse if (%s_info->%s_selected)\n",
		                   pane_var, line_info.variable);
		       first = false;
		       fprintf(fid, "\t{\n");
		       fprintf(fid, gen_comm);
		       fprintf(fid, "\t}\n\n");

		   }
       	           (*index)++;
       	           flag = xvf_get_line_type(database[*index]);
       		   break;

       	      case LogicOpt:
       		   xvf_parse_logic_line(database[*index], &line_info);
		   if ((line_info.optional == opt_flag) &&
                       ((line_info.live == true)||(line_info.optional == true)))
	 	   {
		       fprintf(fid, "\t%s", cp_top);
		       fprintf(fid, "\t * user clicked on 'live' logical");
		       fprintf(fid, " selection '%s'\n", line_info.variable);
		       fprintf(fid, "\t%s", cp_bottom);

		       fprintf(fid, "\tif (%s_info->%s_selected)\n",
		                    pane_var, line_info.variable);
		       first = false;
		       fprintf(fid, "\t{\n");
		       fprintf(fid, gen_comm);
		       fprintf(fid, "\t}\n\n");
                   }
                   (*index)++;
                   flag = xvf_get_line_type(database[*index]);
        	   break;

       	      case Cycle:
       		   xvf_parse_cycle_line(database[*index], &line_info);
		   if ((line_info.optional == opt_flag) &&
                       ((line_info.live == true)||(line_info.optional == true)))
	 	   {
		       fprintf(fid, "\t%s", cp_top);
		       fprintf(fid, "\t * user clicked on 'live' cycle");
		       fprintf(fid, " selection '%s'\n", line_info.variable);
		       fprintf(fid, "\t%s", cp_bottom);

		       fprintf(fid, "\tif (%s_info->%s_selected)\n",
		                    pane_var, line_info.variable);
		       first = false;
		       fprintf(fid, "\t{\n");
		       fprintf(fid, gen_comm);
		       fprintf(fid, "\t}\n\n");
                   }
                   (*index)++;
                   flag = xvf_get_line_type(database[*index]);
        	   break;

       	      case List:
       		   xvf_parse_list_line(database[*index], &line_info);
		   if ((line_info.optional == opt_flag) &&
                       ((line_info.live == true)||(line_info.optional == true)))
	 	   {
		       fprintf(fid, "\t%s", cp_top);
		       fprintf(fid, "\t * user clicked on 'live' list");
		       fprintf(fid, " selection '%s'\n", line_info.variable);
		       fprintf(fid, "\t%s", cp_bottom);

		       fprintf(fid, "\tif (%s_info->%s_selected)\n",
		                    pane_var, line_info.variable);
		       first = false;
		       fprintf(fid, "\t{\n");
		       fprintf(fid, gen_comm);
		       fprintf(fid, "\t}\n\n");
                   }
                   (*index)++;
                   flag = xvf_get_line_type(database[*index]);
        	   break;


       	      case Routine:
       	      case Blank:
       	      case LibCall:
	      case HelpSel:
	      case WorkWidget:
	      case AnswerInfile:
	      case AnswerOutfile:
		   (*index)++;
                   flag = xvf_get_line_type(database[*index]);
                   break;

	      case QuitForm:
                   (*index)++;
                   flag = xvf_get_line_type(database[*index]);
		   *pane_quit_button = true;
        	   break;

	      case MutExcl:
		   mutual_exclusion = true;
		   (*index)++;
		   break;

	      case Toggle:
       		   xvf_parse_toggle_line(database[*index], &line_info);
	           if ((line_info.optional == opt_flag) &&
		       ((line_info.live == true)||(line_info.optional == true)))
	 	   {
		       if (line_info.live == true)
		       {
		           fprintf(fid, "\t%s", cp_top);
		           fprintf(fid, "\t * user clicked on 'live' toggle");
		           fprintf(fid, " selection '%s'\n", line_info.variable);
		           fprintf(fid, "\t%s", cp_bottom);
		       }
		       else 
		       {
		           fprintf(fid, "\t%s", cp_top);
		           fprintf(fid, "\t * user clicked on optional toggle");
		           fprintf(fid, " selection '%s'\n", line_info.variable);
		           fprintf(fid, "\t%s", cp_bottom);
		       }

		       if ((first == true)  || 
			   ((line_info.optional == true) && (opt_flag == true)))
		           fprintf(fid, "\tif (%s_info->%s_selected)\n",
		                    pane_var, line_info.variable);
		       else
		           fprintf(fid, "\telse if (%s_info->%s_selected)\n",
		                   pane_var, line_info.variable);
		       first = false;
		       fprintf(fid, "\t{\n");
		       fprintf(fid, gen_comm);
		       fprintf(fid, "\t}\n\n");
		   }
		   while (flag != End)
                   {
                      (*index)++;
                      flag = xvf_get_line_type(database[*index]);
                   }
                   (*index)++;
                   flag = xvf_get_line_type(database[*index]);
        	   break;
       
       	      case PaneAction:
       		   xvf_parse_pane_action_line(database[*index], &line_info);

		   if (opt_flag == false)
		   {
		      fprintf(fid, "\t%s", cp_top);
		      fprintf(fid, "\t * user clicked on pane");
		      fprintf(fid, " action button '%s'\n", line_info.variable);
		      fprintf(fid, "\t%s", cp_bottom);

		      if (first == true)
		          fprintf(fid, "\tif (%s_info->%s)\n",
		                pane_var, line_info.variable);
		      else
		          fprintf(fid, "\telse if (%s_info->%s)\n",
		               pane_var, line_info.variable);
		      first = false;
		      fprintf(fid, "\t{\n");
		      fprintf(fid, gen_comm);
		      fprintf(fid, "\t}\n\n");
		   }
       	           (*index)++;
       	           flag = xvf_get_line_type(database[*index]);
       		   break;

       	      case End:
		   if (mutual_exclusion == true)
		   { 
		      mutual_exclusion = false;
		      (*index)++;
		      flag = xvf_get_line_type(database[*index]);
		   }
       		   break;
       
      	      default:
       		   (*index)++;
       		   flag = xvf_get_line_type(database[*index]);
       		   break;
       
       	      }  /* end switch */
       
	      if ((flag == End) && (mutual_exclusion == true))
	      {
	          mutual_exclusion = false;
	         (*index)++;
	          flag = xvf_get_line_type(database[*index]);
	      }
       
       
	} while (flag != End);

	return(true);
}
       
