// file: $USFS/class/image_analysis/v6.1/imaga_seg_01.cc
//

// isip include files
//
#include "image_analysis.h"
#include "image_analysis_constants.h"

#ifndef __ISIP_POLYGON
#include <polygon.h>
#endif

// method: load_polygons_cc
//
// arguments:
//  char_1* seg_fname: (input) the segmentation data file name
//
// return:
//  a logical_1 value indicating status
//
// this method builds a linked list of polygons read from the segmentation
// data file. if a transcription has been prescribed in the parameter file,
// only polygons of that transcription will be read. if the transcription
// has been set to be "none" in the parameter file, no polygons will be read.
// if no such information available, then all kinds of polygons will be read,
// which is the case in evaluation of the automatic segmentation.
//
logical_1 Image_analysis::load_polygons_cc(char_1* seg_fname_a) {

  // open the segmentation data file
  //
  FILE* fp = fopen((char*)seg_fname_a, "r");
  if (fp == (FILE*)NULL) {
    error_handler_cc((char_1*)"load_polygons_cc", (char_1*)"error opening
                     the data file");
    return ISIP_FALSE;
  }

  // variables for cleaning the polygon list
  //
  Link_node* curr_node = (Link_node*)NULL;
  Link_node* next_node = (Link_node*)NULL;
  Polygon* node_item = (Polygon*)NULL;

  if (polygon_list_d != (Link_list*)NULL) {

    // make sure the polygon list is empty
    //
    if ((curr_node = polygon_list_d->get_head_cc()) != (Link_node*)NULL) {
      while (curr_node != (Link_node*)NULL) {
        next_node = curr_node->get_next_cc();
        node_item = (Polygon*)(curr_node->get_item_cc());
        polygon_list_d->remove_cc(curr_node);
        if (node_item != (Polygon*)NULL) {
	  delete node_item;
        }
        curr_node = next_node;
      }
    }
  }

  // declare local variables
  //
  char_1* buf = new char_1[ISIP_MAX_STRING_LENGTH];
  logical_1 end_of_loop = ISIP_FALSE;
  int_4 count = 0;
  int_4 count_load_data = 0;
  int_4 n = 0;
  Polygon* polygon = (Polygon*)NULL;
  char_1* transcription = (char_1*)NULL;
    
  // loop over the data file and build the linked list of polygons
  //
  while (end_of_loop == ISIP_FALSE) {
    if ((n = fscanf(fp, "%s", (char*)buf)) == 0) {
      error_handler_cc((char_1*)"load_polygons_cc", (char_1*)"error reading
                       the data file");
      return ISIP_FALSE;
    }
    else if (n == EOF) {
      end_of_loop = ISIP_TRUE;
    }

    if (count == 0) {
      
      // check the tag for transcription
      //
      if (strcmp((char*)buf, (char*)IMAGA_TRANSCRIPTION_TAG) == 0) {
	count++;
      }
    }
    else if (count == 1) {

      // check if there is any prescription for the transcription
      //
      if (transcription_d != (char_1*)NULL) {
	  
        // check for the prescribed transcription
        //
        if (strcmp((char*)buf, (char*)transcription_d) == 0) {
	  count++;
          polygon = new Polygon();
	  count_load_data = 0;
        }
        else {
	  count = 0;
        }
      }

      // if no prescription for transcription, load all polygons
      //
      else {
	transcription = new char_1[ISIP_MAX_STRING_LENGTH];
	strcpy((char*)transcription, (char*)buf);
	count++;
        polygon = new Polygon();
	count_load_data = 0;		
      }
    }
    else if (count == 2) {

      // check for the end of polygon data
      //
      if (strcmp((char*)buf, (char*)IMAGA_TRANSCRIPTION_TAG) == 0 ||
	  end_of_loop == ISIP_TRUE) {

	// end of this polygon
	//
	count = 1;

	if (count_load_data == 0) {

	  // actually no data for this polygon
	  //
	  if (transcription != (char_1*)NULL) {
	    delete [] transcription;
	    transcription = (char_1*)NULL;
	  }
	  delete polygon;
	  polygon = (Polygon*)NULL;
	}
	else {

	  // pass the end information to the polygon
	  //
	  if (polygon->load_cc(IMAGA_END_POLYGON) == ISIP_FALSE) {
	    error_handler_cc((char_1*)"load_polygons_cc", (char_1*)"error
                             building the polygon");
	    return ISIP_FALSE;
	  }
	
	  // set the transcription of the polygon
	  //
	  if (transcription_d != (char_1*)NULL) {
	    if (polygon->set_trans_cc(transcription_d) == ISIP_FALSE) {
	      error_handler_cc((char_1*)"load_polygons_cc", (char_1*)"error
                               setting the transcription of the polygon");
	      return ISIP_FALSE;
	    }
	  }
	  else {
	    if (polygon->set_trans_cc(transcription) == ISIP_FALSE) {
	      error_handler_cc((char_1*)"load_polygons_cc", (char_1*)"error
                               setting the transcription of the polygon");
	      return ISIP_FALSE;
	    }	    
	  }

	  // release memory
	  //
	  if (transcription != (char_1*)NULL) {
	    delete [] transcription;
	    transcription = (char_1*)NULL;
	  }
	    	      
	  // allocate a polygon list if one doesn't exist yet
	  //
	  if (polygon_list_d == (Link_list*)NULL) {
	    polygon_list_d = new Link_list();
	  }

	  // add the polygon to the linked list
	  //
	  if (polygon_list_d->insert_cc(polygon) == ISIP_FALSE) {
	    error_handler_cc((char_1*)"load_polygons_cc", (char_1*)"error
                            inserting the polygon into the list");
	    return ISIP_FALSE;
	  }
	}
      }
      else {

	// polygon data continues
	//
	int_4 coordinate = (int_4)atoi((char*)buf);

	count_load_data++;
	
	// load in the segmentation data as a polygon
	//
	if (polygon->load_cc(coordinate) == ISIP_FALSE) {
	  error_handler_cc((char_1*)"load_polygons_cc",
			   (char_1*)"error reading the data file");
	  return ISIP_FALSE;
	}
      }
    }
  }    

  // close the segmentation data file
  //
  fclose(fp);

  // delete memory
  //
  delete [] buf;
  
  // give some debug information
  //
  if (debug_level_d != ISIP_DEBUG_NONE) {

    if (polygon_list_d != (Link_list*)NULL) {
      
      Link_node* curr_node = (Link_node*)NULL;
      Link_node* next_node = (Link_node*)NULL;
      Polygon* polygon = (Polygon*)NULL;

      for (curr_node = polygon_list_d->get_head_cc();
	   curr_node != (Link_node*)NULL; curr_node = next_node) {
        next_node = curr_node->get_next_cc();
        polygon = (Polygon*)(curr_node->get_item_cc());
        if (polygon->debug_cc(stdout, (char_1*)"load_polygons_cc")
	    == ISIP_FALSE) {
	  error_handler_cc((char_1*)"load_polygons_cc",
			   (char_1*)"error displaying debugging information");
	  return ISIP_FALSE;
        }
      }
    }
  }
    
  // exit gracefully
  //
  return ISIP_TRUE;
}
