// file: $USFS/class/image_analysis/v6.2/imaga_edge_24.cc
//

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

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

// method: edge_lines_cc
//
// arguments:
//  float_4*& edge_data: (input) edge detected data
//  int_4 width: width of the image
//  int_4 height: height of the image
//  FILE* fp_out: pointer to the output data file
//
// this method counts the number and the length of the vertical lines
// and write the data into an output file
//
logical_1 Image_analysis::edge_lines_cc(float_4*& edge_data_a,
					int_4 width_a, int_4 height_a,
					FILE* fp_out_a) {

  // a temporary buffer
  //
  float_4* tmp_buf = new float_4[width_a * height_a];
  memset(tmp_buf, 0, width_a*height_a*sizeof(float_4));
  
  // variables used for storing coordinates data
  //
  int_4* coord = new int_4[2 * height_a];
  memset(coord, 0, 2*height_a*sizeof(int_4));
    
  for (int_4 i=0; i<height_a; i++) {
    for (int_4 j=0; j<width_a; j++) {
      
      // initializing the number of pixels and the deviations in the horizontal
      // and vertical direction
      //
      int_4 pixel_num = 0;
      int_4 h_dev = 0;
      int_4 v_dev = 0;
      
      // storing the row and the column numbers
      //
      int_4 row_num = i;
      int_4 col_num = j;
      
      // checking for the edge
      //
      while (((uint_2)edge_data_a[i * width_a + j]) == IMAGA_EDGE_COLMAX) {

	coord[2 * pixel_num] = j;
	coord[2 * pixel_num + 1] = i;
	edge_data_a[i * width_a + j] = 0;
	pixel_num++;
	
	h_dev = col_num - j;
	v_dev = 0;
	
	// if the pixel is an edge, increment the row to check for the
	// next vertical pixel
	//
	if ((i + 1) < height_a) {
	  if (((uint_2)edge_data_a[(i + 1) * width_a + j])
	      == IMAGA_EDGE_COLMAX) {
	    i++;
	  }
	}
	
	// if the immediate veritcal pixel does not correspond to the line,
	// increment the row number until the vertical deviation limit
	//
	else {
	  
	  while ((v_dev < IMAGA_EDGE_VDEV) && ((i + v_dev) < height_a)
		 && ((uint_2)edge_data_a[(i + v_dev) * width_a + j])
		 != IMAGA_EDGE_COLMAX) {
	    v_dev++;
	  }
	  
	  // if the vertical deviation is within the limit
	  //
	  if ((v_dev < IMAGA_EDGE_VDEV) && ((i + v_dev) < height_a)) {
	    for (int_4 k=0; k<v_dev; k++) {
	      i++;
	      pixel_num++;
	      coord[2 * pixel_num] = j;
	      coord[2 * pixel_num + 1] = i;
	    }
	  }
	  
	  // if there is no line in the vertical direction check to see
	  // if there is any by assuming a limit in the horizontal direction
	  //
	  else if (((i + 1) < height_a) && ((j + 1) < width_a) &&
		   (((uint_2)edge_data_a[(i + 1) * width_a + j + 1])
		    == IMAGA_EDGE_COLMAX) && (abs(h_dev) < IMAGA_EDGE_HDEV)) {
	    j++;
	    i++;
	    h_dev++;
	  }
	  
	  // checking the limit in the deviation in the horizontal direction
	  //
	  else if (((i + 1) < height_a) && (j > 0) &&
		   (((uint_2)edge_data_a[(i + 1) * width_a + j - 1])
		    == IMAGA_EDGE_COLMAX) && (abs(h_dev) < IMAGA_EDGE_HDEV)) {
	    j--;
	    i++;
	    h_dev++;
	  }
	}
      }
      
      // checking if the pixel count is large enough to treat it as a line
      //
      if (pixel_num >= IMAGA_EDGE_PIXEL) {

	fprintf(fp_out_a, "Class\nlongline\n");
	
	// output the coordinates data
	//
	for (int_4 k=0; k<pixel_num; k++) {
	  fprintf(fp_out_a, "%ld  %ld\n", coord[2 * k],
		  coord[2 * k + 1]);
	  tmp_buf[coord[2 * k + 1] * width_a + coord[2 * k]] =
	    (float_4)IMAGA_EDGE_COLMAX;
	}
      }
      i = row_num;
      j = col_num;
      memset(coord, 0, 2*height_a*sizeof(int_4));
    }
  }

  // release memory
  //
  delete [] coord;
  delete [] edge_data_a;
  edge_data_a = tmp_buf;
  
  // exit gracefully
  //
  return ISIP_TRUE;
}
