// file: $USFS/util/analyze_image/v1.0/analyze_image.cc
//

// isip include files
//
#include "analyze_image.h"
#include "analyze_image_constants.h"

// main program
//
int main(int_4 argc, char_1** argv) {
  
  // declare a flag to make sure initialization be done only once
  //
  static logical_1 ia_init = ISIP_TRUE;

  // declare command line arguments
  //
  char_1* param_file = (char_1*)NULL;
  char_1* output_file = (char_1*)NULL;
  
  // declare a debug parameter
  //
  int_4 debug_level = ISIP_DEBUG_NONE;
  
  // declare the position of the first file in the command line list
  //
  int_4 pos = 0;
  
  // parse the command line
  //
  if (get_parameters_cc(param_file, output_file, debug_level, pos,
			argc, argv) == ISIP_FALSE) {
    fprintf(stdout, "%s: error in command line arguments\n", argv[0]);
    return ISIP_ERROR;
  }
  
  // check the arguments
  //
  FILE* fp_o = (FILE*)NULL;
  
  if (param_file == (char_1*)NULL) {
    fprintf(stdout, "%s: no parameter file\n", argv[0]);
    return ISIP_ERROR;
  }
  else {
    
    // prepare an output file if necessary
    //
    if (output_file != (char_1*)NULL) {
      fp_o = fopen((char*)output_file, "w");
      if (fp_o == (FILE*)NULL) {
	fprintf(stdout, "%s: error opening output file\n", argv[0]);
	return ISIP_ERROR;
      }
    }
    
    // print the information of the arguments in the output file, if any
    //
    if (fp_o != (FILE*)NULL) {
      fprintf(fp_o, AI_PRINT_FORMAT_B, param_file);
      fprintf(fp_o, AI_PRINT_FORMAT_C, output_file);
    }
    else {
      fprintf(stdout, AI_PRINT_FORMAT_B, param_file);      
    }
  }     
  
  // declare objects and the necessary variables
  // 
  Image_analysis* ia = (Image_analysis*)NULL;
  ia = new Image_analysis[AI_MAX_NUMBER_MODELS];
  
  if (ia == (Image_analysis*)NULL) {
    fprintf(stdout, "unable to allocate image analysis\n");
    fprintf(fp_o, "unable to allocate image analysis\n");
  }
  
  Ppm ppm;
  char_1** model_files = (char_1**)NULL;
  int_4 num_models = 0;
  
  // fetch the model filenames as a list
  //
  if (ia[(int)0].get_nmods_cc(num_models, model_files, param_file)
      == ISIP_FALSE) {
    fprintf(stdout, "error in reading the parameter files\n");
    fprintf(fp_o, "error in reading the parameter files\n");
  }
  
  // load the model files
  //
  for (int_4 i=0; i<num_models; i++) {
    ia[i].load_cc(model_files[i]);
  }
  
  // define counter to keep up with the number of files processed successfully
  //
  int_4 counter_before = (int_4)0;
  int_4 counter_after = (int_4)0;
  
  // declare the memory for the image_file
  //
  char_1* image_file = new char_1[ISIP_MAX_STRING_LENGTH];
  
  // printing the results
  //
  if (fp_o != (FILE*)NULL) {
    fprintf(fp_o, "\t\t\t%s\t\t\t\t\t\t", "filename");
    fprintf(fp_o, "%s", "sbe_value");
  }
  else {
    fprintf(stdout, "\t\t\t%s\t\t\t\t\t\t", "filename");
    fprintf(stdout, "%s", "sbe_value");
  }
  
  // fetching the imagefile name and looping through all the images
  //
  while (get_next_filename_cc(image_file, argc, argv, pos)
	 == ISIP_TRUE) {
    
    // initializing the sbe
    //
    float_8 sbe = (float_8)0.0;
    
    // process the file
    //
    // loop over the models
    //
    counter_before++;
    
    for (int_4 m=0; m<num_models; m++) {
      
      if (m == (int)0) {
	
	// initialize only if the mode is train
	//
	if (ia_init == ISIP_TRUE) {
	  if (ia[(int)0].init_cc() == ISIP_FALSE) {
	    fprintf(stdout, "error in initializing the data\n");
	    return ISIP_ERROR;
	  }
	  ia_init = ISIP_FALSE;
	}
	
	if (ia[m].set_debug_cc(debug_level) == ISIP_FALSE) {
	  fprintf(stdout, "%s:invalid debug level\n", argv[0]);
	}

	if (fp_o != (FILE*)NULL) {
	  fprintf(fp_o, "\n%s\t", image_file);
	}
	else {
	  fprintf(stdout, "\n%s\t", image_file);
	}
      }
      
      if (ia[m].process_cc(sbe, image_file) == ISIP_TRUE) {
	
	if (m == (int)0) {
	  counter_after++;
	}

	if (fp_o != (FILE*)NULL) {
	  fprintf(fp_o, "%6.2f", sbe);
	}
	else {
	  fprintf(stdout, "%6.2f", sbe);
	}
      }
    }
  }
  
  // update the mean and the covariance matrix for factor analysis
  //
  if (ia[(int)0].sbe_components_cc() == ISIP_FALSE) {
    fprintf(stdout, "error computing the components of the feature vector");
  }

  // write to the model file if the mode is train
  //
  if (ia[(int)0].write_cc() == ISIP_FALSE) {
    fprintf(stdout, "error writing the model file");
  }
  
  // close files
  //
  if (fp_o != (FILE*)NULL) {
    fclose(fp_o);
  }
  
  // print how many successful files were processed
  //
  if (fp_o != (FILE*)NULL) {
    fprintf(fp_o, "\n<%s: %ld of %ld files processed successfully>\n",
	    argv[0], counter_after, counter_before);
  }
  else {
    fprintf(stdout, "\n<%s: %ld of %ld files processed successfully>\n",
	    argv[0], counter_after, counter_before);
  }
  
  // delete allocated memory
  //
  for (int_4 i=0; i<num_models; i++) {
    if (model_files[i] != (char_1*)NULL) {
      delete [] model_files[i];
    }
  }
  delete [] model_files;

  // delete the paramater and output file
  //
  if (param_file != (char_1*)NULL) {
    delete [] param_file;
  }
  if (output_file != (char_1*)NULL) {
    delete [] output_file;
  }
  if (image_file != (char_1*)NULL) {
    delete [] image_file;
  }
  
  // exit gracefully
  //
  return ISIP_NO_ERROR;
}
