// file: $USFS/util/error_eval/v6.2/error_proc_01.cc
//

// system include file
//
#include <string.h>

// isip include files
//
#include "error_eval.h"
#include "error_eval_constants.h"

#ifndef __ISIP_PPM
#include <ppm.h>
#endif

// function: eval_line_cc
//
// arguments:
//  char_1* res_filelist: (input) the result file list
//  char_1* ref_filelist: (input) the reference segmentation data file list
//
// return:
//  a logical_1 value indicating status
//
// this function evaluates the performance of the edge and line detectors
//
logical_1 eval_line_cc(char_1* res_filelist_a, char_1* ref_filelist_a) {

  // open the input file lists
  //
  FILE* fp_res_list = fopen((char*)res_filelist_a, "r");

  if (fp_res_list == (FILE*)NULL) {
    fprintf(stdout, "eval_line_cc: error opening file\n");
    return ISIP_FALSE;
  }

  // declare local variables
  //
  char_1* fname_res = new char_1[ISIP_MAX_STRING_LENGTH];
  char_1* fname_ref = new char_1[ISIP_MAX_STRING_LENGTH];
  memset(fname_res, 0, ISIP_MAX_STRING_LENGTH);
  memset(fname_ref, 0, ISIP_MAX_STRING_LENGTH);
  
  int_4 total_res_lines = 0;
  int_4 total_ref_lines = 0;

  int_4 total_correct = 0;
  int_4 total_error = 0;
  
  // loop over the result file list
  //
  while (fgets((char*)fname_res, ISIP_MAX_STRING_LENGTH, fp_res_list)
	 != (char*)NULL) {  

    // cut the newline symbol at the end of the string
    //
    fname_res[strlen((char*)fname_res) - 1] = ISIP_NULL;

    // read the corresponding image file name from the result file
    //
    char_1* fname_img = new char_1[ISIP_MAX_STRING_LENGTH];
    memset(fname_img, 0, ISIP_MAX_STRING_LENGTH);
    
    FILE* fp_res = fopen((char*)fname_res, "r");

    if (fp_res == (FILE*)NULL) {
      fprintf(stdout, "eval_line_cc: error opening file %s\n", fname_res);
      return ISIP_FALSE;
    }

    char_1* temp_buf = new char_1[ISIP_MAX_STRING_LENGTH];
    memset(temp_buf, (int)0, ISIP_MAX_STRING_LENGTH);

    if (fscanf(fp_res, "%s", temp_buf) == 0) {
      fprintf(stdout, "eval_line_cc: error reading file %s\n", fname_res);
      return ISIP_FALSE;
    }
    
    Ppm ppm;

    // expand the file name
    //
    if (ppm.expand_cc(fname_img, temp_buf) == ISIP_FALSE) {
      fprintf(stdout, "%s: error in expanding the filename\n", temp_buf);
    }

    delete [] temp_buf;
    
    // find the corresponding reference file in the list
    //
    if (get_next_segfname_cc(fname_ref, fname_img, ref_filelist_a)
	== ISIP_FALSE) {
      fprintf(stdout, "eval_line_cc: error reading the reference file list\n");
      return ISIP_FALSE;
    }

    // open the reference file
    //
    FILE* fp_ref = fopen((char*)fname_ref, "r");

    if (fp_ref == (FILE*)NULL) {
      fprintf(stdout, "eval_line_cc: error opening file %s\n", fname_ref);
      return ISIP_FALSE;
    }

    // declare a string buffer for reading the reference file line by line
    //
    char_1* str_ref = new char_1[ISIP_MAX_STRING_LENGTH];
    memset(str_ref, 0, ISIP_MAX_STRING_LENGTH);

    int_4 count = 0;
    int_4 count_data = 0;
    logical_1 end_of_loop = ISIP_FALSE;
    int_4 n = 0;

    // a buffer used to hold the reference line coordinates
    //
    int_4* line_ref = new int_4[EE_MAX_NUM_COORDINATES];
    memset(line_ref, 0, sizeof(int_4) * EE_MAX_NUM_COORDINATES);

    // variables for statistics
    //
    int_4 num_ref_lines = 0;
    int_4 num_res_lines = 0;

    int_4 count_correct = 0;
    int_4 count_error = 0;
    
    // loop over the reference lines and find each best match
    //
    while (end_of_loop == ISIP_FALSE) {

      // check for the end of file
      //
      if ((n = fscanf(fp_ref, "%s", (char*)str_ref)) == 0) {
	fprintf(stdout, "eval_line_cc: error reading reference file\n");
	return ISIP_FALSE;
      }
      else if (n == EOF) {
	end_of_loop = ISIP_TRUE;
      }
      
      // check for valid data
      //
      if (count == 0) {

	// check for the "Class" label
	//
	if (strcmp((char*)str_ref, "Class") == 0) {
	  count++;
	}
      }
      else if (count == 1) {

	// check for the "longline" label
	//
	if (strcmp((char*)str_ref, "longline") == 0) {
	  count++;
	  count_data = 0;
	}
	else {
	  count = 0;
	}
      }
      else if (count == 2) {

	// check for the end of line data
	//
	if (strcmp((char*)str_ref, "Class") == 0 || end_of_loop == ISIP_TRUE) {

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

	  if (count_data != 0) {

	    // find and score the match line in the result file
            //
	    if (score_match_cc(line_ref, count_data, fp_res, count_correct,
			       count_error, num_res_lines)
		== ISIP_FALSE) {
	      fprintf(stdout, "eval_line_cc:
	              error finding a match detection\n");
	      return ISIP_FALSE;
	    }

	    // prepare for the next line
	    //
	    memset(line_ref, 0, sizeof(int_4) * EE_MAX_NUM_COORDINATES);
	    num_ref_lines++;
	  }
        }
	else {

	  // line data continues, record it, and adjust the data count
	  //
	  line_ref[count_data] = (int_4)atoi((char*)str_ref);
	  count_data++;
	}	
      }

      // prepare memory for the next fetch
      //
      memset(str_ref, 0, ISIP_MAX_STRING_LENGTH);
    }
    
    // error statistics for one result file
    //
    fprintf(stdout, "#%s\n", fname_res);
    fprintf(stdout, "reference: %ld\n", num_ref_lines);
    fprintf(stdout, "detection: %ld\n", num_res_lines);

    fprintf(stdout, "error: %.1f%% (%ld)\n",
	    count_error / (float_8)num_ref_lines * 100, count_error);
    fprintf(stdout, "correct: %.1f%% (%ld)\n",
	    count_correct / (float_8)num_ref_lines * 100, count_correct);

    total_res_lines += num_res_lines;
    total_ref_lines += num_ref_lines;

    total_error += count_error;
    total_correct += count_correct;
    
    // close files
    //
    fclose(fp_res);
    fclose(fp_ref);

    // release memory
    //
    delete [] fname_img;
    delete [] str_ref;
    delete [] line_ref;
    
    // initialize memory for the next fetch
    //
    memset(fname_res, 0, ISIP_MAX_STRING_LENGTH);
    memset(fname_ref, 0, ISIP_MAX_STRING_LENGTH);
  }

  // error statistics for all files in the list
  //
  fprintf(stdout, "total statistics\n");
  fprintf(stdout, "reference: %ld\n", total_ref_lines);
  fprintf(stdout, "detection: %ld\n", total_res_lines);

  fprintf(stdout, "error: %.1f%% (%ld)\n",
	  total_error / (float_8)total_ref_lines * 100, total_error);
  fprintf(stdout, "correct: %.1f%% (%ld)\n",
	  total_correct / (float_8)total_ref_lines * 100, total_correct);
  
	  
  // close files
  //
  fclose(fp_res_list);

  // release memory
  //
  delete [] fname_res;
  delete [] fname_ref;
  
  // exit gracefully
  //
  return ISIP_TRUE;
}
