/*
** util.c
*/

#include <stdio.h>
#include <malloc.h>
#include "peek.h"

/* 
** dispose_piece()
** disposes of given piece and everything below it.
*/
void
dispose_piece(Piece *piece) {
  Image *image,*next;
  Part *part;
  int i;

  if (piece->thought) {
    for (i=0; i<=piece->ID_count-1; i++) {
      part = (piece->catalog)[i];
      image = part->thought;
      free(part);
      if (image) do {
	next = image->next;
	free(image);
	image = next;
      } while (next);
    }
  }
  free(piece->xform);
  free(piece->color);
  free(piece->catalog);  /* does this really work, given the gimmicks
			    that are done in tag() ? */
  free(piece);
}

/*
** dispose_object()
** disposes of given object
*/
void
dispose_object(Piece *object) {
  Piece 
    *piece,
    *next;
  
  if (object) {
    piece = object;
    do {
      next = piece->next;
      dispose_piece(piece);
      piece = next;
    } while (next);
  }
}

/*
** fix_cat()
** given piece with jumbled part catalog, organized part catalog by
** part's dimension and creates the corresponding offset array
*/
int
fix_cat(Piece *piece) {
  return(0);
}

/*
** reset()
** sets done to 0 and result to NULL everywhere in surface (or other part)
** This recursive function assumes that done has been set to 1 everywhere
** in parts below.  It should only be used when part of an object
** has been processed.  If an entire object has been processed, the
** non-recursive reset_object should be used.
*/
void
reset(Part *part) {
  Image *image;
 
  if (part) {
    part->done = 0;
    part->result = NULL;
    if (part->d > 0) {
      image = NULL;
      do {
        image = (image == NULL ? part->thought : image->next);
	if (image->sense->done)
	  reset(image->sense);
      } while (image->next != NULL);
    }
  }
}

/* 
** reset_object()
** given an object, result to NULL in all pieces and calls reset() on all
** constituent parts
*/
void
reset_object(Piece *piece) {
  Image *image;
  int i;
  
  if (piece) {
    do {
      image = NULL;
      for (i=0; i<=piece->ID_count-1; i++) {
	(piece->catalog)[i]->done = 0;
	(piece->catalog)[i]->result = NULL;
      }
      piece = piece->next;
    } while (piece);
  }
}

/*
** describe
** returns a one word string describing something based on the dimension
*/
char *
describe(int d) {
  static char *descript[9] = {"undefined", "vertex", "edge", "face", 
			 "cell", "4-cell", "5-cell", "6-cell"};

  if (0 <= d && d <= 7)
    return(descript[d+1]);
  else
    return(descript[0]);
}

