#pragma ident "@(#)utils.c 1.1 97/10/31 SMI"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "utils.h"
#include "zdebug.h"


/*
 * randNum
 *
 *      Randomly picks a value from low to high (used to get color values)
 *
 */
float randNum (float low, float high)
{
  float coef;
  coef = (float )(rand() % 100)/100.0; 
  return( coef * low + (1 - coef) * high);
}  /* End of randNum */




/*
 * genString
 *
 *      Returns a copy of old string. 
 */

char *
genString(char *name)
{
    char *temp;

    temp = (char *) malloc(sizeof(char) * (strlen(name) + 1));
    strcpy(temp, name);
    return temp;
}  /* End of genString */




/*
 * strAdd 
 *
 *      Merge two strings into one and return the resulting new string.
 */

char *
strAdd (char *str1, char *str2)
{
  char *temp;

  temp = (char *) malloc(sizeof(char) * (strlen(str1) + strlen(str2) + 1));
  strcpy(temp, str1);
  strcat(temp, str2);
  return temp;
}  /* End of strAdd*/





/*
 * strCut
 *
 *      Returns a portion of string from start to end-1.
 * So strCut("Good Day", 0, 4) would return "Good". 
 */

char *
strCut(char *word, int start, int end)
{
  char *newWord;
  int j;

  /* Allocate end-start + 1 to account for the NULL character */
  newWord = (char *) malloc(sizeof(char) * (end - start + 1));
  for(j = start; j < end; j++)
    newWord[j-start] = word[j];
  /* Null terminated it */
  newWord[end-start] = '\0';
  return newWord;
}  /* End of strCut*/





/*
 * spaces
 *
 *      Prints into file stream n spaces.
 */

void 
spaces(FILE *fp, int n)
{
  int i;

  for (i = 0; i < n; i++)
    fprintf(fp, " ");
}  /* End of spaces*/



/* linkedList routines */
 

/*
 * linkedListNewLink
 *
 *      Adds a new link to link list.
 */

LinkedList *
linkedListNewNode ()
{
    LinkedList *linkedList;
    
    linkedList = (LinkedList *) malloc(sizeof(LinkedList));
    linkedList->current = NULL;
    linkedList->next = NULL;
    return linkedList;
}  /* End of linkedListNewNode*/




/*
 * linkedListAddNode
 *
 *      Add a new node to a linkedList.
 */

void
linkedListAddNode (LinkedList **list, void *nptr)
{
    
    LinkedList *newNode, *nlptr;   /* New nodeList node */

    /* Check if it's already there . */
    if (linkedListFindNode(*list, nptr)){
      zdo6 printf("in linked list, abort\n");
      return;
    }

    nlptr = *list;
    /* Empty list, make nptr the first. */
    if (nlptr->current == NULL)
	{
	    nlptr->current = nptr;
	    return;
	}
    /* Normal case, add Node as head */
    
    newNode = linkedListNewNode();
    newNode->current = nptr;
    newNode->next = nlptr;
    *list = newNode;
}  /* End of linkedListAddNode*/



/*
 * linkedListAddNodeFast
 *
 *      Add a new node to a linkedList. Does not check existence.
 */

void
linkedListAddNodeFast (LinkedList **list, void *nptr)
{
    
    LinkedList *newNode, *nlptr;   /* New nodeList node */

    nlptr = *list;
    /* Empty list, make nptr the first. */
    if (nlptr->current == NULL)
	{
	    nlptr->current = nptr;
	    return;
	}
    /* Normal case, add Node as head */
    
    newNode = linkedListNewNode();
    newNode->current = nptr;
    newNode->next = nlptr;
    *list = newNode;
}  /* End of linkedListAddNodeFast*/




/*
 * linkedListRemoveNode
 *
 *      Removes a new node from a linkedList.
 */

void
linkedListRemoveNode (LinkedList **list, void *nptr)
{
    
    LinkedList *newNode, *nlptr;   /* New nodeList node */
    LinkedList *prev;

    if (list == NULL)
      return;
    nlptr = *list;
    while (nlptr && (nlptr->current != nptr)){
      prev = nlptr;
      nlptr = nlptr->next;
    }

    if (nlptr != 0) {
      if (nlptr == *list)  /* If nlptr is head, */
	if (nlptr->next == NULL)    /* If next is null, 
				       make a new list */
	  *list = linkedListNewNode();
	else *list = nlptr->next;
      else
	prev->next = nlptr->next;   /* Leap-frog current */

      /* Destroy it */
      nlptr->current = 0;
      nlptr->next = 0;
      free(nlptr);
    }
}  /* End of linkedListRemoveNode*/

/*
 * nodeForEachChild
 *
 *     This calls function, f, on each of the children nodes. 
 */

void
linkedListForEachNode (LinkedList *list,  
		       int (*f)(void *, void *), void *data)
{
  LinkedList *nlptr, *next;

  for (nlptr = list; nlptr != NULL; nlptr = next){
    next = nlptr->next;
    if (nlptr->current)
      f(nlptr->current, data);
  }
}  /* End of linkedListForEachNode*/



/*
 * linkedListFindNode
 *
 *     This checks for existence of a node in list.
 */

int
linkedListFindNode (LinkedList *list,  
		       void *node)
{
  LinkedList *nlptr, *next;

  for (nlptr = list; nlptr != NULL; nlptr = next){
    next = nlptr->next;
    if (nlptr->current == node)
      return 1;
  }
  return 0;
}  /* End of linkedListForEachNode*/



/*
 * linkedListDestroy
 *
 *     Free up memory for all the nodes of a linked list.
 */

void 
linkedListDestroy (LinkedList *list)
{
  LinkedList *nlptr, *next;

  for (nlptr = list; nlptr != NULL; nlptr = next){
    next = nlptr->next;
    free(nlptr);
  }
}  /* End of linkedListDestroy */


 /* End of utils.c */
