 /*
  * Khoros: $Id$
  */

#if !defined(lint) && !defined(SABER)
static char rcsid[] = "Khoros: $Id$";
#endif

 /*
  * $Log$
  */ 

/*
 *----------------------------------------------------------------------
 *
 * Copyright 1991, 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 to 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 1991 by UNM */

/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
 >>>>
 >>>>  	        String Manipulation / Utility Routines
 >>>>
 >>>>			create_mapcol_list()
 >>>>			variable_scan()
 >>>>			create_function_def()
 >>>>			create_function_call()
 >>>>
 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>   <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/

#include "spectrum.h"

/****************************************************************
*
* Routine Name: create_mapcol_list()
*      Purpose: creates the list of map columns to be 
*		passed to xvf_run_list_wait() by run_files()
*        Input: none
*       Output: returns the list of map columns
*   Written By: Danielle Argiro
*
****************************************************************/

char **create_mapcol_list()
{
     int  i;
     char **list;
     char temp[MaxLength];
    
     list = (caddr_t *) calloc(1, spc_map_colnum * sizeof(char *));
     for (i = 0; i < spc_map_colnum; i++)
     {
        sprintf(temp, "Map Column %d (desc)", i);
        list[i] = xvf_strcpy(temp);
     }
     return(list);
}


/****************************************************************
*
* Routine Name: create_category_list()
*      Purpose: creates the list of categories to be 
*		passed to xvf_run_list_wait() by other routines
*        Input: prepend  - supply 1st element of list if desired
*		listflag - indicates type of list
*		size     - size of desired list
*		excludelist - list of names to exclude
*       Output: returns the list of class categories
*   Written By: Danielle Argiro
*
****************************************************************/

char **create_category_list(prepend, listflag, size, excludelist, excludesize)
char *prepend;
int   listflag;
int   *size;
char **excludelist;
int   excludesize;
{
     int  i;
     char **list;
     legend_list *legend_ptr;
    
     list = (char **) calloc(1, sizeof(char *));
     i = 0;

     /* prepend an item if desired */
     if ((prepend != NULL) && (i == 0))
     {
	 list[i++] = xvf_strcpy(prepend);
         list = (caddr_t *) realloc(list, (i+1)*sizeof(char *));
     }

     legend_ptr = spc_legend_list;
     while (legend_ptr != NULL)
     {
	 /* create list of hidden class categories */
	 if ((legend_ptr->hidden) && (listflag == SpcHidden) &&
	     (!(string_member(legend_ptr->text, excludelist, excludesize))))
             list[i++] = xvf_strcpy(legend_ptr->text);

	 /* create list of displayed class categories */
         else if ((!legend_ptr->hidden) && (listflag == SpcDisplayed) &&
	     (!(string_member(legend_ptr->text, excludelist, excludesize))))
             list[i++] = xvf_strcpy(legend_ptr->text);

	 /* create list of non-empty class categories */
         else if ((legend_ptr->clusternum > 0) && (listflag == SpcNotEmpty) &&
	     (!(string_member(legend_ptr->text, excludelist, excludesize))))
             list[i++] = xvf_strcpy(legend_ptr->text);

	 /* create list of all class categories */
         else if ((listflag == SpcAll) && 
		 (!(string_member(legend_ptr->text, excludelist, excludesize))))
             list[i++] = xvf_strcpy(legend_ptr->text);

         legend_ptr = legend_ptr->next;
         list = (caddr_t *) realloc(list, (i+1)*sizeof(char *));
     }
     *size = i;


     return(list);
}


/****************************************************************
*
* Routine Name: string_member()
*      Purpose: sees if string passed in is a member of the list
*		of strings passed in. 
*        Input: string - the string to look for
*		list   - list of strings to look in.
*       Output: returns TRUE if string is in list, FALSE otherwise.
*   Written By: Danielle Argiro
*
****************************************************************/
string_member(string, list, size) 
char *string;
char **list;
{
	int i;

	if ((list == NULL) || (size == 0)) return(false);

	for (i = 0; i < size; i++)
	{
	    if ((strcmp(string, list[i])) == 0)
		return(true);
	}
	return(false);
}
/****************************************************************
*
* Routine Name: variable_scan()
*      Purpose: scans a function string (to be passed to vexpr parser)
*		for variables, where all variables MUST be of the
*		form "MX" where X is from 0 to M, M being the number
*		of rows in the map data.  For example, if you passed 
*		in "M1 + M2 / M5", variable_scan() would return a list
*		of strings consisting of "M1", "M2", and "M5".
*
*        Input: string - the function string, eg, "M1 + M2 / M5"
*       Output: variable_num - the number of variables found 
*			       in the function string.
*		returns the list of variables
*
*   Written By: Danielle Argiro
*
****************************************************************/

char **variable_scan(string, variable_num)
char *string;
int  *variable_num;
{
     int i, j, k, l, length, colcheck, repeat;
     char temp[MaxLength];
     char **list;

     *variable_num = 0;
     list = (caddr_t *) calloc(1, spc_map_colnum * sizeof(char *));

     length = xvf_strlen(string);
     if (length < 2) return(NULL);
     
     k = 0;
     i = 0;
     while (i < length)
     {
          while ((string[i] != 'M') && (i<length)) i++;
	  if (i == length) break;
	  if (i < length)
          {
	     /* get a variable specified by MX */
             j = 0;
	     temp[j++] = string[i++];
	     while (isdigit(string[i]))
	     	temp[j++] = string[i++];
             temp[j] = '\0';
          }

	  /* make sure MX does not specify an invalid map column */
	  colcheck = atoi(&temp[1]);
	  if (colcheck > spc_map_colnum-1)
	  {
	      sprintf(temp, "Legal variables include M0 to M%d only.", 
		      spc_map_colnum-1);
              xvf_error_wait(temp, "variable scan", NULL);
	      return(NULL);
	  }
	  
	  /* look for repeat of a certain MX */
          repeat = false;
	  for (l = 0; l < k; l++)
             if (strcmp(list[l], temp) == 0) repeat = true;
	  
	  /* add variable to list if it is not a repeat */
	  if (!repeat) list[k++] = xvf_strcpy(temp);

     }
     *variable_num = k;
     return(list);
}


/****************************************************************
*
* Routine Name: create_function_def()
*      Purpose: creates a function definition to be passed to the vexpr
*		library, based on the string that the user types in as 
*		the function defining the red band, green band, or blue band.
*		For example,  "M1 + M2 / M5".
*
*        Input: string - the function string, eg, "M1 + M2 / M5".
*		colorband - SpcRed, SpcGreen, or SpcBlue
*       Output: returns the function definition in correct format 
*   Written By: Danielle Argiro
*
****************************************************************/

char *create_function_def(string, init_string, var_list, var_num)
char *string;
char *init_string;
char **var_list;
int   var_num;
{
     int  i;
     char temp[MaxLength], temp2[MaxLength];

     sprintf(temp, init_string);
     for (i = 0; i < var_num; i++)
     {
         strcat(temp, var_list[i]);
         if (i < var_num-1)  strcat(temp, ",");
     }
     strcat(temp, ")");
     sprintf(temp2, "= %s", string);
     strcat(temp, temp2);

     return(xvf_strcpy(temp));
}


/****************************************************************
*
* Routine Name: create_function_call()
*      Purpose: creates a function call to be passed to the vexpr
*		library, based on the number of variables (MX's) that
*		are used in the current function, the pointers to the
*		appropriate columns, and the current row.
*		For example,  "Red(25,0,200)".
*
*        Input: cluster - the current cluster (row) across all columns
*		columns - array of columns that will have values in function
*		var_num - number of variables (columns) in the function
*		colorband - SpcRed, SpcGreen, or SpcBlue
*
*       Output: returns the function call in correct format 
*
*   Written By: Danielle Argiro
*
****************************************************************/
char *create_function_call(cluster, columns, var_num, init_string)
int  cluster; 
int *columns;
int  var_num; 
char *init_string;
{
	char func[MaxLength], temp[MaxLength];
	int  i, column;

	sprintf(func, init_string);

        for (i = 0; i < var_num; i++)
	{
	     column = columns[i];
 	     sprintf(temp, "%g", spc_map[column][cluster]);
	     strcat(func,  temp);
	     if (i < var_num-1)  strcat(func, ",");
        }
        strcat(func, ")");

	return(xvf_strcpy(func));
}
