#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define MAXSIZE 1000

int sqr(int i)
{
	return i*i;
}

void readPicture(int picture[MAXSIZE][MAXSIZE], int* width, int* height, char* filename)
{
	FILE* pictureFile;
	char tempString[255];
	int i,j;
	
	pictureFile = fopen(filename,"r");
	fgets(tempString, 255, pictureFile);
	fgets(tempString, 255, pictureFile);

	fscanf(pictureFile, "%d %d\n", width, height);
	
	fgets(tempString, 255, pictureFile);
	for (i = 0; i < *height; i++)
	{
		for (j = 0; j < *width; j++)
		{
			fgets(tempString, 255, pictureFile);
			picture[i][j] = atoi(tempString);
		}
	}

	fclose(pictureFile);
}

void printPicture(int picture[MAXSIZE][MAXSIZE], int width, int height)
{
	int i,j;
	for (i = 0; i < height; i++)
	{
		for (j = 0; j < width; j++)
		{
			printf("%d ",picture[i][j]);
		}
	printf("\n");
	}
}

void writePicture(int picture[MAXSIZE][MAXSIZE], int width, int height, char* filename)
{
	FILE* pictureFile;
	int i,j;
	pictureFile = fopen(filename,"w");
	fprintf(pictureFile,"P2\n");
	fprintf(pictureFile,"# CREATOR: Dan Schafer\n");
	fprintf(pictureFile,"%d %d\n",width,height);
	fprintf(pictureFile,"255\n");
	for (i = 0; i < height; i++)
	{
		for (j = 0; j < width; j++)
		{
			fprintf(pictureFile,"%d\n",picture[i][j]);
		}
	}
}

void scalePicture(int picture[MAXSIZE][MAXSIZE], int width, int height, int scale)
{
	int i,j;
	for (i = 0; i < height; i++)
	{
		for (j = 0; j < width; j++)
		{
			picture[i][j] = scale * picture[i][j];
			if (picture[i][j] > 255)
			{
				picture[i][j] = 255;
			}
		}
	}
}

void makeCopyArray(int newA[MAXSIZE][MAXSIZE], int oldA[MAXSIZE][MAXSIZE], int width, int height)
{
	int i,j;
	for (i = 0; i < height; i++)
	{
		for (j = 0; j < width; j++)
		{
			newA[i][j] = oldA[i][j];
		}
	}
	
}

void horizEdges(int picture[MAXSIZE][MAXSIZE], int width, int height, int thres)
{
	int i,j;
	int originalPic[MAXSIZE][MAXSIZE];
	
	makeCopyArray(originalPic,picture, width, height);

	for (j = 0; j < width-1; j++)
	{
		for (i = 0; i < height; i++)
		{
			picture[i][j] = abs(originalPic[i][j] - originalPic[i][j+1]);
		}
	}
	for (i = 0; i < height; i++)
	{
		picture[i][width-1] = 0;
	}
}

void vertEdges(int picture[MAXSIZE][MAXSIZE], int width, int height, int thres)
{
	int i,j;
	int originalPic[MAXSIZE][MAXSIZE];
	
	makeCopyArray(originalPic,picture, width, height);

	for (i = 0; i < height-1; i++)
	{
		for (j = 0; j < width; j++)
		{
			picture[i][j] = abs(originalPic[i][j] - originalPic[i+1][j]);
		}
	}
	for (j = 0; j < width; j++)
	{
		picture[height-1][j] = 0;
	}
}

void crossEdges(int picture[MAXSIZE][MAXSIZE], int width, int height, int thres)
{
	int i,j;
	int originalPic[MAXSIZE][MAXSIZE];
	
	makeCopyArray(originalPic,picture, width, height);

	for (i = 1; i < height-1; i++)
	{
		for (j = 1; j < width-1; j++)
		{
			picture[i][j] = (int)(sqrt(sqr(originalPic[i][j-1] - originalPic[i][j+1]) + sqr(originalPic[i-1][j] - originalPic[i+1][j])));
			//picture[i][j] = abs(originalPic[i][j-1] - originalPic[i][j+1]) + abs(originalPic[i-1][j] - originalPic[i+1][j]);
			if (picture[i][j] > 255)
			{
				picture[i][j] = 255;
			}
		}
	}
	for (j = 0; j < width; j++)
	{
		picture[0][j] = 0;
		picture[height-1][j] = 0;
	}
	for (i = 0; i < height; i++)
	{
		picture[i][0] = 0;
		picture[i][width-1] = 0;
	}

}

void sobelEdges(int picture[MAXSIZE][MAXSIZE], int width, int height, int thres)
{
	int i,j,dx,dy;
	int originalPic[MAXSIZE][MAXSIZE];
	
	makeCopyArray(originalPic,picture, width, height);

	for (i = 1; i < height-1; i++)
	{
		for (j = 1; j < width-1; j++)
		{
			dx = originalPic[i-1][j+1] + 2*originalPic[i][j+1] + originalPic[i+1][j+1] - (originalPic[i-1][j-1] + 2*originalPic[i][j-1] + originalPic[i+1][j-1]);
			dy = originalPic[i-1][j-1] + 2*originalPic[i-1][j] + originalPic[i-1][j+1] - (originalPic[i+1][j-1] + 2*originalPic[i+1][j] + originalPic[i+1][j+1]);
			picture[i][j] = (int)(sqrt(sqr(dx) + sqr(dy)));
			if (picture[i][j] > 255)
			{
				picture[i][j] = 255;
			}
		}
	}
	for (j = 0; j < width; j++)
	{
		picture[0][j] = 0;
		picture[height-1][j] = 0;
	}
	for (i = 0; i < height; i++)
	{
		picture[i][0] = 0;
		picture[i][width-1] = 0;
	}

}

int main()
{
	int picture[MAXSIZE][MAXSIZE];
	int width, height;
	char* filename = "tripod.pgm";
	
	readPicture(picture,&width,&height,filename);
	printf("%s\n","Picture read.");

	horizEdges(picture,width,height,80);	
	printf("%s\n","Horiz Edge data generated read.");
	writePicture(picture, width, height,"horiz.pgm");
	printf("%s\n","Horiz picture written.");

	readPicture(picture,&width,&height,filename);
	printf("%s\n","Picture read.");
	
	vertEdges(picture,width,height,80);	
	printf("%s\n","Vert Edge data generated read.");
	writePicture(picture, width, height,"vert.pgm");
	printf("%s\n","Vert picture written.");
	
	readPicture(picture,&width,&height,filename);
	printf("%s\n","Picture read.");
	
	crossEdges(picture,width,height,80);	
	printf("%s\n","Cross Edge data generated read.");
	writePicture(picture, width, height,"cross.pgm");
	printf("%s\n","Cross picture written.");
	
	readPicture(picture,&width,&height,filename);
	printf("%s\n","Picture read.");
	
	sobelEdges(picture,width,height,80);	
	printf("%s\n","Sobel Edge data generated read.");
	writePicture(picture, width, height,"sobel.pgm");
	printf("%s\n","Sobel picture written.");
	return 0;
}
