 /*
  * Khoros: $Id: adjust.c,v 1.2 1992/03/20 22:47:00 dkhoros Exp $
  */

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

 /*
  * $Log: adjust.c,v $
 * Revision 1.2  1992/03/20  22:47:00  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"

/* >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
   >>>>                                                       <<<<
   >>>>		       Form  Index Adjustment Routines        <<<<
   >>>>                                                       <<<<
   >>>>       These routines adjust the indices at each node  <<<<
   >>>>       in the form tree, as necessary after adding or  <<<<
   >>>>       deleting a subform. Skeletons modeled after     <<<<
   >>>>       form creation routines (createform.c)	      <<<<
   >>>>                                                       <<<<
   >>>>             xvf_adjust_form_indices()                 <<<<
   >>>>             xvf_adjust_subform_indices()              <<<<
   >>>>             xvf_adjust_master_indices()               <<<<
   >>>>             xvf_adjust_guide_indices()                <<<<
   >>>>             xvf_adjust_pane_indices()                 <<<<
   >>>>             xvf_adjust_toggle_indices()               <<<<
   >>>>                                                       <<<<
   >>>>                                                       <<<<
   >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<  */


/******************************************************************
*
*  Routine Name:  xvf_adjust_form_indices
*
*	Purpose:  takes a form tree that has just had a subform added
*		  or deleted, and re-assignes the indices at each node
*		  to correctly point to their corresponding database line.
*
*	  Input:  form - pointer to the form tree
*
*    Written By: Danielle Argiro
*
*******************************************************************/

int xvf_adjust_form_indices(form)
xvf_form *form;
{
	int curr_index = 0, done = false, flag;
	int subform_num = 0, subform_button_num = 0, master_button_num = 0; 
	xvf_sub_form *subform;
	char **database;

	database = form->db;
	flag = xvf_get_line_type(database[curr_index]);
	if (flag != StartForm)
        {
            fprintf(stderr, "xvf_adjust_form_indices:\n");
            fprintf(stderr, "   ERROR: Database form definition");
	    fprintf(stderr, " must begin with '-F'\n");
            return(false);
        }
	form->index = curr_index;  curr_index++;

	flag = xvf_get_line_type(database[curr_index]);

	/* 
	 * have only a dummy form - nothing to adjust 
	 */ 
	if (flag == End)
	     return(true);

	/* 
	 * have a master def - need to adjust indices on the master 
         */
	else if (flag == StartMaster)
        {
	    curr_index++;
	    done = false;
	    xvf_adjust_master_indices(form, database, &curr_index, 
				      &subform_button_num, &master_button_num);
	}

	/*****  now a series of (-M) subform definitions should follow *****/

	subform = form->subform;
	while ((subform->type != SubFormButton) && 
	       (subform->type != PsuedoSubForm) && 
		(subform->next_subform != NULL))  
		 subform = subform->next_subform;

	while (!done) 
	{
	    flag = xvf_get_line_type(database[curr_index]);
	    if (flag == StartSubForm)
            {
		subform_num++;
		subform->index = curr_index; 
		xvf_adjust_subform_indices(subform, database, &curr_index);
	        subform->db = form->db;
	        subform = subform->next_subform;
		if (subform != NULL)
		{
	            while ((subform->type != SubFormButton)&& 
			   (subform->type != PsuedoSubForm) &&
		            (subform->next_subform != NULL))  
		             subform = subform->next_subform;
		}
	    }
	    else if (flag == End)
	    {
		if ((subform_button_num != 0) &&
                     (subform_num != subform_button_num))
                {
                      fprintf(stderr, "xvf_adjust_form_indices:\n");
                      fprintf(stderr, "   WARNING: UIS file specified\n");
                      fprintf(stderr, "            has %d subform defs,", 
					subform_num);
		      fprintf(stderr, "            but %d subform buttons\n", 
					subform_button_num);
		}
		done = true;
	    }
	    else
	    {
		 fprintf(stderr, "xvf_adjust_form_indices:\n");
                 fprintf(stderr, "   ERROR: UIS line out of place.\n");
                 return(false);
   	    }

	}
	form->subform_num = subform_num;
	return(true);

}



/******************************************************************
*
*  Routine Name:  xvf_adjust_master_indices
*
*	Purpose:  takes a form tree that has just had a subform added
*		  or deleted, and re-assignes the indices at each node
*		  to correctly point to their corresponding database line.
*
*	  Input:  form - pointer to the form tree
*		  caseflay - indicates the current situation
*
*    Written By: Danielle Argiro
*
*******************************************************************/

int xvf_adjust_master_indices(form, database, curr_index, subform_button_num, 
			  master_button_num)
xvf_form     *form;
char	     **database;
int          *curr_index;
int          *subform_button_num;
int          *master_button_num;
{
	int flag, submenu_def;
	xvf_sub_form *current;

	current = form->subform;
	while (current != NULL)
        {
            /*
             *  see what type of line we have
             */
            flag = xvf_get_line_type(database[*curr_index]);

            switch (flag) {

                case SubFormButton:
                case PsuedoSubForm:
                     current->button_index = *curr_index;
		     (*subform_button_num)++;
                     (*master_button_num)++;
                     (*curr_index)++;
	             current = current->next_subform;
		     break;

		case WorkWidget:
                     current->index = -1;
		     (*curr_index)++;
	             current = current->next_subform;
		     break;

		case StartSubMenu:
		     submenu_def = true;
		     (*curr_index)++;
		     break;

		case Blank:
		     (*curr_index)++;
		     break;

		case MasterAction:
		case QuitForm:
		case HelpSel:
		     current->button_index = *curr_index;
                     current->index = -1;
		     (*curr_index)++;
                     (*master_button_num)++;
	             current = current->next_subform;
		     break;
	
		case End:
		     if (submenu_def == true)
		     {
			(*curr_index)++;
			submenu_def = false;
		     }
		     else
		     {
		        fprintf(stderr, "xvf_adjust_master_indices:\n");
		        fprintf(stderr, "   ERROR: reaching end of subform ");
		        fprintf(stderr, " definition before\n");
		        fprintf(stderr, "           end of subform list\n");
		     }
		     break;

	    } /* end switch */

	} /* end while */

       (*curr_index)++;

	return(true);
}

/******************************************************************
*
*  Routine Name:  xvf_adjust_subform_indices
*
*	Purpose:  takes a form tree that has just had a subform added
*		  or deleted, and re-assignes the indices within the subform
*		  to correctly point to their corresponding database line.
*
*	  Input:  form - pointer to the form tree
*
*    Written By: Danielle Argiro
*
*******************************************************************/

int xvf_adjust_subform_indices(subform, database, curr_index)
xvf_sub_form *subform;
char	     **database;
int	     *curr_index;
{
	int flag, done;
	int guide_num = 0, button_num = 0, pane_count = 0;
	xvf_guide_button *guide_ptr;

	done = false;
	flag = xvf_get_line_type(database[*curr_index]);
        if (flag != StartSubForm)
        {
            fprintf(stderr, "xvf_create_subform:\n");
            fprintf(stderr, "   ERROR: UIS subform definition not ");
	    fprintf(stderr, "beginning with (-M)\n");
            return(false);
        }
	
	(*curr_index)++;
	flag = xvf_get_line_type(database[*curr_index]);

        if ((flag != StartGuide) && (flag != StartPane))
        {
             fprintf(stderr, "xvf_adjust_subform_indices:\n");
             fprintf(stderr, "   ERROR: StartSubForm UIS line [-M] \n");
             fprintf(stderr, "          must be followed by either a ");
	     fprintf(stderr, " [-G] UIS line \n");
             fprintf(stderr, "          indicating a guide pane definition\n");
	     fprintf(stderr, "          or a [-P] line indicating a single \n");
             fprintf(stderr, "          pane on the subform\n");
             return(false);
        }

	if (flag == StartGuide)
        {
	    subform->guide_index = *curr_index;
	    (*curr_index)++;
            if (!(xvf_adjust_guide_indices(subform, database, curr_index, 
					   &guide_num, &button_num)))
                return(false);
        }

	guide_ptr = subform->guide_button;
	if (guide_ptr == NULL) return(false);
	while (((guide_ptr->type != GuideButton) || 
	        (guide_ptr->pane == NULL)) && 
		(guide_ptr->next_button != NULL))  
		 guide_ptr = guide_ptr->next_button;
	while (!done) 
        {

           flag = xvf_get_line_type(database[*curr_index]);

           if (flag == StartPane)
           {
		pane_count++;
		if (guide_ptr->pane != NULL)
		{
		   guide_ptr->pane->index = *curr_index; (*curr_index)++; 
		}
		if (!(xvf_adjust_pane_indices(guide_ptr->pane, database, 
					      curr_index)))
                          return(false);

	        guide_ptr = guide_ptr->next_button;
	        if (guide_ptr != NULL)
	        {
	        while (((guide_ptr->type != GuideButton) || 
	                (guide_ptr->pane == NULL)) && 
		       (guide_ptr->next_button != NULL))  
		        guide_ptr = guide_ptr->next_button;
		}

           }  /* end if */
	   else if (flag == End)
           {

                /* error check: if # panes = # "true" guide buttons */
                if ((guide_num != 0) && (pane_count != guide_num))
                {
                    fprintf(stderr, "xvf_adjust_subform_indices:\n");
                    fprintf(stderr, "   WARNING: UIS file specified has\n");
                    fprintf(stderr, "            %d guide buttons, but %d panes.\n",
                                 guide_num, pane_count);
                 }
                 done = true;
                 (*curr_index)++;

           }  /* end else */

           /* database line out of place */
           else
           {
              fprintf(stderr, "xvf_adjust_subform_indices:\n");
              fprintf(stderr, "   ERROR: UIS line out of place.\n");
              return(false);
           }

        } /* end while */

        return(true);

} /* end xvf_adjust_subform_indices() */


/******************************************************************
*
*  Routine Name:  xvf_adjust_guide_indices
*
*	Purpose:  takes a form tree that has just had a subform added
*		  or deleted, and re-assignes the indices within the guide
*		  to correctly point to their corresponding database line.
*
*	  Input:  form - pointer to the form tree
*
*    Written By: Danielle Argiro
*
*******************************************************************/

int xvf_adjust_guide_indices(subform, database, curr_index, 
			     guide_num, button_num)
xvf_sub_form *subform;
char 	    **database;
int	     *curr_index;
int	     *guide_num;
int	     *button_num;
{
	int flag;
	xvf_guide_button *current;

	current = subform->guide_button;
	while (current != NULL)
        {
            flag = xvf_get_line_type(database[*curr_index]);

	    switch (flag) {
		
		case GuideButton:
		     current->index = *curr_index;
		     current->guide_num = *button_num;
		     (*guide_num)++; (*button_num)++; (*curr_index)++;
		     break;

		case QuitForm:
		case SubformAction:
		case HelpSel:
		     current->index = *curr_index;
		     current->guide_num = *button_num;
		     (*button_num)++; (*curr_index)++;
		     break;

		case Blank:
		case WorkWidget:
		     (*curr_index)++;
                     break;

	    } /* end switch */

	    current = current->next_button;

	} /* end while */

	(*curr_index)++;

	return(true);

} /* end xvf_adjust_guide_indices */



/******************************************************************
*
*  Routine Name:  xvf_adjust_pane_indices
*
*	Purpose:  takes a pane from a form tree that has just had a 
*		  subform added or deleted, and re-assignes the indices 
*		  within the pane to correctly point to their corresponding 
*		  database lines.
*
*	  Input:  form - pointer to the form tree
*
*    Written By: Danielle Argiro
*
*******************************************************************/

int xvf_adjust_pane_indices(pane, database, curr_index)
xvf_pane *pane;
char 	 **database;
int	 *curr_index;
{
	int flag;
	xvf_selection *current;
	
	current = pane->sel_list;
	while (current != NULL)
        {
	    flag = xvf_get_line_type(database[*curr_index]);

	    switch (flag) {

		case InputFile:
		case OutputFile:
		case IntegerOpt:
		case FloatOpt:
		case StringOpt:
		case LogicOpt:
		case Routine:
		case HelpSel:
		case PaneAction:
		case Blank:
		case WorkWidget:
		case QuitForm:
		case AnswerInfile:
		case AnswerOutfile:
		case Cycle:
		case List:
		     current->index = *curr_index; (*curr_index)++;
	             current = current->next;
		     break;

		case MutExcl:
		     (*curr_index)++;
		     if (!(xvf_adjust_me_indices(pane, &current,
                           database, curr_index)))
                           return(false);
		     break;

		case Toggle:
		     current->index = *curr_index; (*curr_index)++;
		     if (!(xvf_adjust_toggle_indices(current->toggle_next, 
			   database, curr_index))) 
		 	   return(false);
		     (*curr_index)++;
	             current = current->next;
		     break;
	    }

	} /* end while */

        (*curr_index)++;
	return (true);

} /* end xvf_adjust_pane_indices */




/******************************************************************
*
*  Routine Name:  xvf_adjust_toggle_indices
*
*	Purpose:  takes a toggle list of a form that has just had a 
*		  subform added or deleted, and re-assignes the indices 
*		  within the toggle to correctly point to their 
*		  corresponding database line.
*
*	  Input:  form - pointer to the form tree
*
*    Written By: Danielle Argiro
*
*******************************************************************/

int xvf_adjust_toggle_indices(toggle_start, database, curr_index)

xvf_selection *toggle_start;
char	      **database;
int	      *curr_index;
{
	int flag;
	xvf_selection *current;
	
	current = toggle_start;
	while (current != NULL)
        {
            flag = xvf_get_line_type(database[*curr_index]);

            switch (flag) {

                case InputFile:
		case OutputFile:
		case IntegerOpt:
		case FloatOpt:
		case StringOpt:
		case LogicOpt:
		case Cycle:
		     current->index = *curr_index;
		     break;

		case Blank:
                     break;

	   } /* end switch */
	   (*curr_index)++;
	   current = current->next;
	}
	return(true);

} /* end xvf_adjust_toggle_indices */


/******************************************************************
*
*  Routine Name:  xvf_adjust_me_indices
*
*	Purpose:  takes a selection list of a form that has just had a 
*		  subform added or deleted, and re-assignes the indices 
*		  within the mutually exclusive group
*		  to correctly point to their corresponding database lines.
*
*	  Input:  form - pointer to the form tree
*
*    Written By: Danielle Argiro
*
*******************************************************************/

int xvf_adjust_me_indices(pane, selection, database, curr_index)

xvf_pane       *pane;
xvf_selection **selection;
char	      **database;
int	      *curr_index;
{
	int flag; int done = false;
	xvf_selection *current;
	mut_excl_link *mut_excl_ptr;

	current = *selection;
	mut_excl_ptr = pane->mut_exclusion[current->mut_excl_id];
	while (!done)
        {
            flag = xvf_get_line_type(database[*curr_index]);

            switch (flag) {

                case InputFile:
		case OutputFile:
		case IntegerOpt:
		case FloatOpt:
		case StringOpt:
		case LogicOpt:
		case Cycle:
		     current->index = *curr_index;
		     mut_excl_ptr->index = *curr_index;
	             current = current->next;
		     mut_excl_ptr = mut_excl_ptr->next;
		     break;

		case Blank:
		     current->index = *curr_index;
	             current = current->next;
                     break;

		case End:
		     done = true;

	   } /* end switch */
	   (*curr_index)++;
	}

	*selection = current;
	return(true);

} /* end xvf_adjust_me_indices */

