#include "edge.h"

#include <math.h>
#include <memory.h>

unsigned char* sobelFilter(int width, int height, int nband, int luminance, int threshold, unsigned char* imgSrc, unsigned char* imgDest)
{
  if ((width <= 0) || (height <= 0))
    return NULL;

  unsigned char* result;
  if (!imgDest)
  {
    result = new unsigned char[3*width*height];
    if (!result)
      return NULL;
  }
  else
    result = imgDest;

  // Avaliando Interior
  // Multiplicando Colunas
  if (!luminance)
  {
	for (int j = 1; j < height-1; j++)
	{
		int idx_j = j*width;
		int idx_j_minus_one = (j-1)*width;
		int idx_j_plus_one = (j+1)*width;
		for (int i = 1; i < width-1; i++)
		{
			for (int band = 0; band < nband; band++)
   			{
				int dx = imgSrc[3*(idx_j_minus_one + (i-1)) + band];      //1  -->  3*(j*width + (i-1))
				dx +=    imgSrc[3*((idx_j) + (i-1)) + band] << 1;     //2  -->  3*(j*width + i)
				dx +=    imgSrc[3*(idx_j_plus_one + (i-1)) + band];      //1  -->  3*(j*width + (i+1))

				dx -=  imgSrc[3*(idx_j_minus_one + (i+1)) + band];      //1  -->  3*(j*width + (i-1))
				dx -= imgSrc[3*((idx_j) + (i+1)) + band] << 1;     //2  -->  3*(j*width + i)
				dx -= imgSrc[3*(idx_j_plus_one + (i+1)) + band];      //1  -->  3*(j*width + (i+1))

				int dy = imgSrc[3*(idx_j_minus_one + (i-1)) + band];      //1  -->  3*(j*width + (i-1))
				dy +=    imgSrc[3*(idx_j_minus_one + i) + band] << 1;     //2  -->  3*(j*width + i)
				dy +=    imgSrc[3*(idx_j_minus_one + (i+1)) + band];      //1  -->  3*(j*width + (i+1))

				dy -=  imgSrc[3*(idx_j_plus_one + (i-1)) + band];      //1  -->  3*(j*width + (i-1))
				dy -= imgSrc[3*(idx_j_plus_one + i) + band] << 1;     //2  -->  3*(j*width + i)
				dy -= imgSrc[3*(idx_j_plus_one + (i+1)) + band];      //1  -->  3*(j*width + (i+1))

				int sobel = sqrt(dx*dx + dy*dy);
				if (sobel > threshold) sobel = 255;
				else sobel = 0;
				result[3*(idx_j + i)+ band] = (unsigned char) sobel;
			}
		}
	}
  }
  else 
  {
	for (int j = 1; j < height-1; j++)
	{
		int idx_j = j*width;
		int idx_j_minus_one = (j-1)*width;
		int idx_j_plus_one = (j+1)*width;
		for (int i = 1; i < width-1; i++)
		{
  		  int dx = imgSrc[3*(idx_j_minus_one + (i-1))];      //1  -->  3*(j*width + (i-1))
		  dx +=    imgSrc[3*((idx_j) + (i-1))] << 1;     //2  -->  3*(j*width + i)
		  dx +=    imgSrc[3*(idx_j_plus_one + (i-1))];      //1  -->  3*(j*width + (i+1))

		  dx -=  imgSrc[3*(idx_j_minus_one + (i+1))];      //1  -->  3*(j*width + (i-1))
		  dx -= imgSrc[3*((idx_j) + (i+1))] << 1;     //2  -->  3*(j*width + i)
		  dx -= imgSrc[3*(idx_j_plus_one + (i+1))];      //1  -->  3*(j*width + (i+1))

		  int dy = imgSrc[3*(idx_j_minus_one + (i-1))];      //1  -->  3*(j*width + (i-1))
		  dy +=    imgSrc[3*(idx_j_minus_one + i)] << 1;     //2  -->  3*(j*width + i)
  		  dy +=    imgSrc[3*(idx_j_minus_one + (i+1))];      //1  -->  3*(j*width + (i+1))

		  dy -=  imgSrc[3*(idx_j_plus_one + (i-1))];      //1  -->  3*(j*width + (i-1))
		  dy -= imgSrc[3*(idx_j_plus_one + i)] << 1;     //2  -->  3*(j*width + i)
		  dy -= imgSrc[3*(idx_j_plus_one + (i+1))];      //1  -->  3*(j*width + (i+1))

		  int sobel = sqrt(dx*dx + dy*dy);
		  if (sobel > threshold) sobel = 255;
		  else sobel = 0;
		  for (int band = 0; band < nband; band++)
		  {
		    result[3*(idx_j + i) + band] = (unsigned char) sobel;
		  }
		}
	}
  }


  // Avaliando Bordas
  // Borda Superior
  
  return result;
}

unsigned char* logFilter(int width, int height, int nband, int luminance, int threshold, unsigned char* imgSrc, unsigned char* imgDest)
{
  if ((width <= 0) || (height <= 0))
    return NULL;

  unsigned char* result;
  if (!imgDest)
  {
    result = new unsigned char[3*width*height];
    if (!result)
      return NULL;
  }
  else
    result = imgDest;

  int kernel[9] = { 0,  1, 0,
	                1, -4, 1,
					0,  1, 0};

    // Avaliando Interior
    for (int j = 1; j < height-1; j++)
    {
      for (int i = 1; i < width-1; i++)
	  {
	    for (int band = 0; band < nband; band++)
		{
		  int log=0;
//          log = kernel[0]*imgSrc[3*((j-1)*width + (i-1)) + band];  // 3*((j-1)*width + (i-1))
          log += kernel[1]*imgSrc[nband*((j-1)*width + i) + band];     // 3*((j-1)*width + i)
//          log += kernel[2]*imgSrc[3*((j-1)*width + (i+1)) + band]; // 3*((j-1)*width + (i+1))

		  log += kernel[3]*imgSrc[nband*(j*width + (i-1)) + band]; // 3*(j*width + (i-1))
          log += kernel[4]*imgSrc[nband*(j*width + i) + band];     // 3*(j*width + i)
          log += kernel[5]*imgSrc[nband*(j*width + (i+1)) + band]; // 3*(j*width + (i+1))

//		  log += kernel[6]*imgSrc[3*((j+1)*width + (i-1)) + band]; // 3*((j+1)*width + (i-1))
          log += kernel[7]*imgSrc[nband*((j+1)*width + i) + band];     // 3*((j+1)*width + i)
//          log += kernel[8]*imgSrc[3*((j+1)*width + (i+1)) + band]; // 3*((j+1)*width + (i+1))

          if(log > threshold)
            result[nband*(j*width+i)+band] = 255;
          else
            result[nband*(j*width+i)+band] = 0;
		}
	  }

	// Avaliando Bordas
	// Borda Superior
  }
  return result;
}