#include "gradImage.h"


int compare( const void *elem1, const void *elem2 )
{
	return (*(int *)elem1>*(int *)elem2);
}

void	imageNormalize(double ** u, double **out, int width, int height, int maxminflag, double maxMin[2])
{
	int i,j;

	double max = 0.0, min = 1.0;

	if (maxminflag == NORMALIZE) 
	{
		max = 0.0; min = 1.0;
		for (i=1; i <= width; i++) {
			for (j=1; j <= height; j++) {
				if (u[i][j] > max) max = u[i][j];
				if (u[i][j] < min) min = u[i][j];
			}
		}
		for (i=1; i <= width; i++) {
			for (j=1; j <= height; j++) {
				out[i][j] = (u[i][j] - min) / (max - min);
			}
		}
	}
	else if (maxminflag == USEMAXMIN) 
	{
		max = maxMin[0]; min = maxMin[1];
		for (i=1; i <= width; i++) {
			for (j=1; j <= height; j++) {
				out[i][j] = (u[i][j] - min) / (max - min);
			}
		}
	}

	printf("umax %f umin %f\n", max, min);
	maxMin[0] = max ; maxMin[1] = min;

}


//void setGradient(Image *image, Image *mask, double ** u, int flag, Image * edgeimage, Image * maskimage,
//				 Image * hor_red, Image * hor_redblur, Image * hor_blue, Image * hor_blueblur,
//				 Image * ver_red, Image * ver_redblur, Image * ver_blue, Image * ver_blueblur)
				 //Image * horimage, Image * verimage)
void setGradient(Image *image, Image *mask, double ** u, int flag, Image * edgeimage, Image * maskimage)
{
	int i,j;
	int n = image->width-1;
	Image *divG = ImageCreate(n+1,n+1);
	Image *gradHy1 = ImageCreate(n+1,n+1);
	Image *gradHx1 = ImageCreate(n+1,n+1);

	imageGradient(image, gradHx1, gradHy1, edgeimage, maskimage);
	//GradientFromImage(horimage, verimage, gradHx1, gradHy1);
	//GradientFromImageNew(hor_red, hor_redblur, hor_blue, hor_blueblur, 
	//	ver_red, ver_redblur, ver_blue, ver_blueblur, gradHx1, gradHy1);

	//if (flag == MASK_ON) maskGradient(mask, gradHx1, gradHy1);
	imageGradientTodivG(gradHx1, gradHy1, divG);

	ImageDestroy(gradHx1);
	ImageDestroy(gradHy1);

	for (i=1; i <= n; i++) {
		for (j=1; j <= n; j++) {
			u[i][j] = (double) (ImageGetPixelf(divG, i, j, 0, GRAY)/255.0);
			//u[i][j] = (double) (ImageGetPixelf(divG, i, j, 0, GRAY));
		}
	}
	ImageDestroy(divG);
}


void setMask(Image *mask, double ** u)
{
	int i,j;
	int n = mask->width-1;

	for (i=1; i <= n; i++) {
		for (j=1; j <= n; j++) {
			//if (ImageGetPixel(mask, i, j, 0, GRAY) == 0)
			//	u[i][j] = 0.0;
			//if ((ImageGetPixel(mask, i, j, 0, GRAY) == 0) && (fabs(u[i][j]) > 0.03))
			if (ImageGetPixel(mask, i, j, 0, GRAY) == 0)
				u[i][j] = u[i][j]/2.0;
		}
	}
}

void saveArrayAsImage(double ** u, double ** uOut, u_char * resultpixel, int arrayWidth, int arrayHeight, char *fileName, int maxminflag, double maxMin[2])
{
	int i,j;
	int n = arrayWidth;
	unsigned char val;
	int valBig;

	// Important !!!
	imageNormalize((double **) u, (double **) uOut, n, n, maxminflag, maxMin); // uOut now in [0,1]

	Image *image2 = ImageCreate(n+1,n+1);
	ImageClear(image2, 1,1,1); 
	for (i=1; i <= n; i++) {
		for (j=1; j <= n; j++) {
			valBig =  (int) (255.0 * uOut[i][j]);
			//valBig =  (int) (uOut[i][j]);
			val = valBig > 255 ? 255 : (unsigned char) valBig;
			val = valBig < 0   ? 0   : (unsigned char) valBig;
			ImageSetPixel(image2, i, j, 0, val, GRAY) ; // red channel
			
			//new code
			int pos = j * (n + 1) + i;
			resultpixel[pos] = val;
		}
	}
	ImageWriteP6grey2color(image2, fileName);	printf("created %s\n", fileName);
	//ImageWriteP5(image2, fileName);	printf("created %s\n", fileName);
	if (DEBUG) {
		char fName[100];
		strcpy(fName,"");
		strcat(fName, fileName);strcat(fName, "Float.pfm");
		ImageWriteP7greyfloat2color(u, arrayWidth, arrayHeight, fName); // using u instead of uOut, u is NOT between [0,1]
		strcpy(fName,"");
		strcat(fName, fileName);strcat(fName, "FloatScaled.pfm");
		ImageWriteP7greyfloat2color(uOut, arrayWidth, arrayHeight, fName); // using uOut, between [0,1]
	}
}

