/*
** enum.c
*/

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

#define DOTS(x) for (i=1;i<=x;++i) fprintf(enum_file,(i%3 ==1?".":" "))

/*
** enumerate
** writes out an outline of the definition of given part
** Initial call to this is to give outline of a given surface
*/
int 
enumerate(Piece *piece, Part *part, int indent, FILE *enum_file) {
  int i, j, k, done;
  Image *image;
  
  k = piece->space_d;
  DOTS(indent);
  fflush(enum_file);
  if (part->ID < 0 || part->ID > piece->ID_count ) {
    sprintf(err, "crazy part ID of %d\n", part->ID);
    return(-1);
  }
  fprintf(enum_file, "%s%s #%d/%d\n", describe(part->d),
	  (0 == indent ? "/surface": ""), 
	  (piece->offset ? part->ID - (piece->offset)[part->d] : -1),
	  part->ID);
  fflush(enum_file);
  if (!part->done) {
    part->done = 1;
    if (0 == part->d) {
      DOTS(indent+3);
      fprintf(enum_file, "coords: ");
      fflush(enum_file);
      if (part->coord) {
	for (j=0; j<=k-1; ++j) {
	  fprintf(enum_file, "%s%g%s%s", (0==j ? "(" : ""),
		  part->coord[j],(k-1 > j ? ", " : ""),
		  (k-1 == j ? ")\n" : "") );
	}
      } 
      else {
        fprintf(enum_file, "---\n");
      }
      if (indent >= 3) 
	DOTS(indent+3);
      fprintf(enum_file, "colors: ");
      for (j=0; j<COLORS; ++j) {
	fprintf(enum_file, "%s%g%s%s", (0==j ? "(" : ""),
		part->color[j],(j<COLORS-1 ? ", " : ""),
		(COLORS-1 == j ? ")\n" : "") );
      }
    } /* if 0 == d */
    else {  
      if (indent >= 3) {
	DOTS(indent+3);
	fprintf(enum_file, "colors: ");
	for (j=0; j<COLORS; ++j) {
	  fprintf(enum_file, "%s%g%s%s", (0==j ? "(" : ""),
		  part->color[j], (j<COLORS-1 ? ", " : ""),
		  (COLORS-1 == j ? ")\n" : "") );
	}
	if (2 == part->d) {
	  DOTS(indent+3);
	  fprintf(enum_file, "norm: ");
	  for (j=0; j<=2; ++j) {
	    fprintf(enum_file, "%s%g%s%s", (0==j ? "(" : ""),
		    part->norm[j], (j<2 ? ", " : ""),
		    (2 == j ? ")\n" : "") );
	  }
	}
      } /* if indent >= 3 */
      fflush(enum_file);
      image = NULL;
      do {
	image = (image == NULL ? part->thought : image->next);
	enumerate(piece, image->sense, indent + 3, enum_file);
      } while (image->next != NULL);
    } /* else 0 != d */
  } /* if !done */
  return(0);
}

/*
** enum_object()
** writes outline of object to enum_file.
** wanders through piece image and piece layers to get to surface images,
** from where it calls enumerate() on the underlying surface 
*/
int
enum_object(FILE *enum_file, Piece *piece) {
  Image *image;
  int p=0, j;
  char err2[ERRSTRLEN];

  if (!piece) {
    fprintf(enum_file, "(NULL object)\n");
    fflush(enum_file);
  }
  else {
    fprintf(enum_file, "Object outline: \n\n");
    fprintf(enum_file, "(format: <part type> #<relative #>/<absolute #> )\n");
    fflush(enum_file);
    do {
      fprintf(enum_file, "\n--- Piece %d of object ---\n\n", p);
      fprintf(enum_file, "colors: ");
      for (j=0; j<COLORS; ++j) {
	fprintf(enum_file, "%s%g%s%s", (0==j ? "(" : ""),
		piece->color[j],(j<COLORS-1 ? ", " : ""),
		(COLORS-1 == j ? ")\n" : "") );
      }
      fflush(enum_file);
      image = NULL; 
      j = 1;
      do {
	image = (!image ? piece->thought : image->next);
	if (enumerate(piece, image->sense, 0, enum_file)) {
	  sprintf(err2, "enum_object:\n");
	  strcat(err, err2); return(-1);
	}
	++j;
      } while (image->next);
      ++p;
      piece = piece->next;
    } while (NULL != piece);
  }
  reset_object(piece);
  return(0);
}

