 /*
  * Khoros: $Id: routines.c,v 1.1 1991/05/10 15:57:48 khoros Exp $
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id: routines.c,v 1.1 1991/05/10 15:57:48 khoros Exp $";
#endif

 /*
  * $Log: routines.c,v $
 * Revision 1.1  1991/05/10  15:57:48  khoros
 * Initial revision
 *
  */ 


/*
 *----------------------------------------------------------------------
 *
 * 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 "cantata.h"


/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>	    file name:  routines.c                            <<<<
   >>>>                                                       <<<<
   >>>>   description:                                        <<<<
   >>>>                                                       <<<<
   >>>>      routines:  xvl_create_routine()                  <<<<
   >>>>                 xvl_routine()                         <<<<
   >>>>                                                       <<<<
   >>>> modifications:					      <<<<
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */


#define RoutinesList "KHOROS_HOME/repos/cantata/routines"

static char    *routine_name[512]; /* names of all executable routines (-P) */
static char    *subform_name[512]; /* form associated with each routine	    */
static int	pane_num[512];     /* location of pane within form	    */
static int	routine_cnt;	   /* number of routines available	    */


/************************************************************
*
* Routine Name:  xvl_create_routine
*
*      Purpose:  This routine is used to create the accelerated
*		 IPL routine glyph.  xvl_create_routine reads
*		 through the entire form gathering four pieces
*		 of information.
*
*	 1. routine_name:  The routine name which resides on the pane.
*	 2. pane_num:      The pane number on the particular subform.
*	 3. subform_name:  The subform that the pane is located on.
*	 4. routine_cnt:   The routines found.
*
*		 After gathering the routine names to be displayed
*		 by xvl_routine() we then take the routine names
*		 and sort them, discarding any duplicate entries.
*
*        Input:  form -	 form to be get routine names from.
*
*
*   Written By: Stephanie Hallett and Mark Young
*
*************************************************************/


int xvl_create_routine(form)

xvf_form *form;
{
	Line_Info lineinfo;
	int	  i, j, done, tmp_pane, flag;
	int	  max_index, num_entries, index = 0;
	char	  *tmp_subform, *tmp_routine, **list, **vlistfile();


	max_index   = form->line_num;
	routine_cnt = 0;
	tmp_subform = NULL;

	xvf_clear_line_info(&lineinfo);

	/* read in all the names and fill out strucutures */
	list = vlistfile(RoutinesList, NULL, True, &num_entries);
	while (index < max_index)
	{
	   flag = xvf_get_line_type(form->db[index]);

	   switch (flag)
	   {
	      case StartSubForm:
		   xvf_parse_startsubform_line(form->db[index],&lineinfo);

		   if (tmp_subform != NULL)
		      free(tmp_subform);

		   tmp_subform = xvf_strcpy(lineinfo.variable);
		   tmp_pane = 0;
		   break;

	      case StartPane:
		   tmp_pane++;
		   xvf_parse_startpane_line(form->db[index],&lineinfo);

	 	   if (lineinfo.variable == NULL)
		      break;

		   for (i = 0; i < num_entries; i++)
		   {
		      if (strcmp(list[i], lineinfo.variable) == 0)
			 break;
		   }

		   if (i == num_entries)
		   {
                      pane_num[routine_cnt]     = tmp_pane;
		      subform_name[routine_cnt] = xvf_strcpy(tmp_subform);
		      routine_name[routine_cnt] = xvf_strcpy(lineinfo.variable);
		      routine_cnt++;
		   }
		   break;

              default:
		   break;
	   }
	   index++;
	}

	/*
	 *  Sort routines to be in alphabetic in order
	 */
	done = false;
	while (!done)
	{
	   done = true; i = 1;
	   while (i < routine_cnt)
	   {
	      if (strcmp(routine_name[i-1],routine_name[i]) > 0)
	      {
	         tmp_routine = routine_name[i-1];
		 routine_name[i-1] = routine_name[i];
		 routine_name[i] = tmp_routine;

		 tmp_subform = subform_name[i-1];
		 subform_name[i-1] = subform_name[i];
		 subform_name[i] = tmp_subform;

		 tmp_pane = pane_num[i-1];
		 pane_num[i-1] = pane_num[i];
		 pane_num[i] = tmp_pane;
          
		 done = false;
		 i++;
	      }
	      else if (strcmp(routine_name[i-1],routine_name[i]) == 0)
	      {
		 free(routine_name[i]);
		 free(subform_name[i]);

		 routine_cnt--;
		 for (j = i; j < routine_cnt; j++)
		 {
		    pane_num[j]     = pane_num[j+1];
		    routine_name[j] = routine_name[j+1];
		    subform_name[j] = subform_name[j+1];
		 }
	      }
	      else
	      {
	         i++;
	      }
	   }
        }
}



/************************************************************
*
* Routine Name:  xvl_routine
*
*      Purpose:  This routine is used to set a desired guide
*		 button for a given subform.  The user supplies
*		 the subform and the guide button they wish to
*		 make active.  xvf_change_input then races thru
*		 the old guide list clearing the current selected
*		 guide pane and selecting the desired one.
*
*        Input:  workspace - the desired guide button to be selected
*
*
*   Written By: Stephanie Hallett and Mark Young
*
*************************************************************/


xvl_routine(workspace, form)

Workspace	*workspace;
xvf_form	*form;
{
	int  num = 0;
	XawListReturnStruct **glyph_use;
	char *prompt1  = "Choose glyph/routine:";
	char *label1   = "Create Glyph";

	char		error[512];
	xvf_sub_form    *subform, *new_subform;
	int		cnt, i, index, done;
	xvf_guide_button *guide;

	/*
	 *  use the routine_list widget to get what glyph to create
	 */
	glyph_use = xvf_run_list_multsel_wait(routine_name, routine_cnt, 5,
			prompt1, label1, false, true, &num);

	if (glyph_use == NULL)
	{
	   return;
	}

	for (i = 0; i < num; i++)
	{
	    index = glyph_use[i]->list_index;

	    /* search for subform which matches the Subform_Name */
	    subform = form->subform;
	    done = false;
	    while ((subform != NULL) && (!done))
	    {
	       if ((subform->type == PsuedoSubForm) && (subform->subform_name !=
		    NULL))
	       {
	          if (strcmp(subform->subform_name,subform_name[index])==0)
		     done = true;
	       	  else
		     subform = subform->next_subform;
               }
	       else
		  subform = subform->next_subform;
	    }

	    if (!done)
	    {
	       sprintf(error,"Couldn't find form %s", subform_name[index]);
	       xvf_error_wait(error, "xvl_routine", NULL);
	    }
	    else if ((new_subform = xvl_copy_subform(workspace->glyphform, subform)) != NULL)
	    {
	       /*
	        *  select the guide button and pane the user has
		*  specified
		*/
	       guide = new_subform->guide_button;
	       cnt = pane_num[index];
	       while ((guide != NULL) && (cnt != 0))
	       {
		  if (guide->type == GuideButton)
		     cnt--;
		  if (cnt != 0)
		     guide = guide->next_button;
	       }

	       /*
	        *  Set the guide selection if the guide button is
	        *  not NULL
	        */
	       if (guide != NULL)
	       {
	          /*
		   *  create new subform (GLYPH).  First, since this
		   *  is the accelerated guide routine we need to set
		   *  the subform guide to the right pane.  We then
		   *  create the subform glyph.
		   */
		  if (guide->index != -1)
		  {
		     xvf_change_input(workspace->glyphform, guide->index,
				   xvf_guide_chng, "1", 0);
		  }

		  if (xvl_build_glyph(workspace, GLYPH, (caddr_t) new_subform,
			True, -1, -1) == NULL)
		  {
	             sprintf(error,"couldn't create %s routine glyph",
			     subform_name[index]);
	             xvf_error_wait(error, "xvl_routine", NULL);
		  }
	       }
	    }
	    else
	    {
   	       xvf_error_wait("Unable to create form","xvl_routine", NULL);
	    }

	    /*
	     *  Free up the glyph routine selection.
	     */
	    if (glyph_use[i] == NULL)
	    {
	       free(glyph_use[i]);
	    }
	}
	if (!(xvf_adjust_form_indices(workspace->glyphform))) return;
}
