#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <vector>
#include <cv.h>
#include <highgui.h>

using namespace std;


//Ocho vecinos
#define A0 data[u*step+v*channels+k]
#define A1 data[u*step+(v+1)*channels+k]
#define A2 data[(u-1)*step+(v+1)*channels+k]
#define A3 data[(u-1)*step+(v)*channels+k]
#define A4 data[(u-1)*step+(v-1)*channels+k]
#define A5 data[u*step+(v-1)*channels+k]
#define A6 data[(u+1)*step+(v-1)*channels+k]
#define A7 data[(u+1)*step+(v)*channels+k]
#define A8 data[(u+1)*step+(v+1)*channels+k]

typedef struct{
	int x;
	int y;
}posicion;
typedef struct{
	int R,G,B;
}color;


typedef struct{
	posicion ini;
	posicion fin;
}cuadrado;

typedef struct {
	IplImage *img;
	char name[32];
	vector<cuadrado> mano; 
	vector<cuadrado> nomano; 
}imagen;

int trackbar=0;


void visor(int position){	
}


int main(){
	FILE * fmano;
	FILE * fnomano;
	FILE * fpixel;
	FILE * fpixelHSV;
	FILE * fpixel3;
	char buffer[200];
	int height,width;
	vector<imagen> imgs;
	imagen img;
	cuadrado cuad;
	int cont=0;

	fopen_s(&fmano,"MANO.txt","r");
	if(fmano==NULL){
		printf("Error en el fichero MANO.txt\n");
		exit(0);
	}

	fopen_s(&fnomano,"NoMANO.txt","r");
	if(fnomano==NULL){
		printf("Error en el fichero NoMANO.txt\n");
		exit(0);
	}
	fopen_s(&fpixel,"Pixeles.txt","w");
	if(fpixel==NULL){
		printf("Error en el fichero Pixeles.txt\n");
		exit(0);
	}
	fopen_s(&fpixelHSV,"PixelesHSV.txt","w");
	if(fpixelHSV==NULL){
		printf("Error en el fichero PixelesHSV.txt\n");
		exit(0);
	}
	fopen_s(&fpixel3,"PixelesNxN.txt","w");
	if(fpixel3==NULL){
		printf("Error en el fichero PixelesNxN.txt\n");
		exit(0);
	}

	//Leer cuadrados Mano
	while( fgets(buffer,200,fmano) != NULL ){
		if(buffer[0] != '\t'){
			int length=strlen(buffer);
			strncpy_s(img.name, buffer,length-1);
			img.img = cvLoadImage(img.name,1);
			imgs.push_back(img);
		}
		else{
			sscanf_s(buffer,"\t(%d,%d)  (%d,%d)",&cuad.ini.x, &cuad.ini.y, &cuad.fin.x, &cuad.fin.y);
			imgs.back().mano.push_back(cuad);
		}
	}

	//Leer cuadrados NoMano
	int k=-1;
	while( fgets(buffer,200,fnomano) != NULL ){
		if(buffer[0] != '\t'){
			k++;
		}
		else{
			sscanf_s(buffer,"\t(%d,%d)  (%d,%d)",&cuad.ini.x, &cuad.ini.y, &cuad.fin.x, &cuad.fin.y);
			imgs[k].nomano.push_back(cuad);
		}
	}
	int step;
	if(imgs.size() ==0){
		printf("No se ha cargado ninguna imagen\n");
		return 0;
	}
	cvNamedWindow("ventana",1);
	
	if(imgs.size() == 1 ){
		trackbar=0;
	}
	else {
		cvCreateTrackbar("Foto","ventana",&trackbar,imgs.size()-1, visor);
	}
	int n;
	int key;

	while( 1 ) {
		n = imgs[trackbar].mano.size();
		IplImage *temp;
		temp = cvCloneImage(imgs[trackbar].img);
		for ( int j = 0; j < n ; j++){
			cvRectangle( temp , cvPoint(imgs[trackbar].mano[j].ini.x,imgs[trackbar].mano[j].ini.y),cvPoint(imgs[trackbar].mano[j].fin.x, imgs[trackbar].mano[j].fin.y),cvScalar(0xff,0x00,0x00));
		}
		n = imgs[trackbar].nomano.size();
		for ( int j = 0; j < n ; j++){
			cvRectangle( temp , cvPoint(imgs[trackbar].nomano[j].ini.x,imgs[trackbar].nomano[j].ini.y),cvPoint(imgs[trackbar].nomano[j].fin.x, imgs[trackbar].nomano[j].fin.y),cvScalar(0x00,0x00,0xff));
		}
		cvShowImage("ventana",temp);


		key=(cvWaitKey(10) & 255);


		
		if( key == 48) { //si se pulsa '0' escribe en el fichero de pixeles HSV
			fprintf(fpixelHSV,"1");//Numero de caracteristicas
			IplImage * tmp= cvCreateImage(cvGetSize(imgs[0].img),8,3);
			for(int i=0; i < imgs.size(); i++){
				step= imgs[i].img->widthStep;

				//fprintf(fpixelHSV,"%s\n",imgs[i].name);
				cvCvtColor(imgs[i].img ,tmp, CV_RGB2HSV);
				uchar* data      = (uchar *) tmp->imageData;
				for( int j = 0; j < imgs[i].mano.size(); j++)
					for( int u = imgs[i].mano[j].ini.y; u <= imgs[i].mano[j].fin.y; u++)
						for( int v = imgs[i].mano[j].ini.x; v <= imgs[i].mano[j].fin.x; v++)
							fprintf(fpixelHSV,"\n%d %d %d 1", data[u*step+v*3],data[u*step+v*3+1],data[u*step+v*3+2]);

				fflush(fpixel);
				for( int j = 0; j < imgs[i].nomano.size(); j++)
					for( int u = imgs[i].nomano[j].ini.y; u <= imgs[i].nomano[j].fin.y; u++)
						for( int v = imgs[i].nomano[j].ini.x; v <= imgs[i].nomano[j].fin.x; v++)
							fprintf(fpixelHSV,"\n%d %d %d 0", data[u*step+v*3],data[u*step+v*3+1],data[u*step+v*3+2]);
				fflush(fpixel);
			}
		}

		if( key == 49) { //si se pulsa '1' escribe en el fichero de pixeles RGB

			fprintf(fpixel,"1");//Numero de caracteristicas
			for(int i=0; i < imgs.size(); i+=1){
				step= imgs[i].img->widthStep;
				uchar* data      = (uchar *) imgs[i].img->imageData;
				//fprintf(fpixel,"%s",imgs[i].name);
				for( int j = 0; j < imgs[i].mano.size(); j++)
					for( int u = imgs[i].mano[j].ini.y; u <= imgs[i].mano[j].fin.y; u++)
						for( int v = imgs[i].mano[j].ini.x; v <= imgs[i].mano[j].fin.x; v++){
							int B=data[u*step+v*3];
							int G=data[u*step+v*3+1];
							int R=data[u*step+v*3+2];

							fprintf(fpixel,"\n%d %d %d 1", B,G,R);
							cont++;
						}

				fflush(fpixel);
				for( int j = 1; j < imgs[i].nomano.size(); j+=1)
					for( int u = imgs[i].nomano[j].ini.y; u <= imgs[i].nomano[j].fin.y; u++)
						for( int v = imgs[i].nomano[j].ini.x; v <= imgs[i].nomano[j].fin.x; v++){
							fprintf(fpixel,"\n%d %d %d 0", data[u*step+v*3],data[u*step+v*3+1],data[u*step+v*3+2]);
							cont++;
						}
				fflush(fpixel);
				
			}
		}
		if( key == 51 || key == 53 || key == 55 || key == 57) { 
			if(key==51) key = 3;					//si se pulsa '3' escribe en el fichero de ventanas 3x3
			if(key==53) key = 5;					//si se pulsa '5' escribe en el fichero de ventanas 5x5
			if(key==55) key = 7;					//si se pulsa '7' escribe en el fichero de ventanas 7x7
			if(key==57) key = 9;					//si se pulsa '7' escribe en el fichero de ventanas 9x9


			
			fprintf(fpixel3,"%d", (key*key));//Numero de caracteristicas
			int borde = int(key/2);

			for(int i=0; i < imgs.size(); i+=1){
				step= imgs[i].img->widthStep;
				width= imgs[i].img->width;
				height= imgs[i].img->height;
				uchar* data      = (uchar *) imgs[i].img->imageData;
				//fprintf(fpixel3,"%s\n",imgs[i].name);
				for( int j = 0; j < imgs[i].mano.size(); j++){
					int u, U;
					if(imgs[i].mano[j].ini.y - borde < 0)
						u = borde;	
					else 
						u = imgs[i].mano[j].ini.y;

					if(imgs[i].mano[j].fin.y + borde >= height)
						U = height - borde;	
					else 
						U = imgs[i].mano[j].fin.y;

					for(; u < U; u++){
						int v,V;

						if(imgs[i].mano[j].ini.x - borde < 0)
							v = borde;	
						else 
							v = imgs[i].mano[j].ini.x;

						if(imgs[i].mano[j].fin.x + borde >= width)
							V = width - borde;	
						else 
							V = imgs[i].mano[j].fin.x;

						for(; v < V; v++){
							fprintf(fpixel3,"\n");
							for(int m = -1*borde; m <= borde; m++){
								for(int n = -1*borde; n <= borde; n++){
									fprintf(fpixel3,"%d %d %d ",data[(u+m)*step+(v+n)*3],data[(u+m)*step+(v+n)*3+1],data[(u+m)*step+(v+n)*3+2]);
								}
							}
							fprintf(fpixel3,"1");
							cont++;
						}
					}
				}
				fflush(fpixel3);
				for( int j = 0; j < imgs[i].nomano.size(); j+=1){
					int u, U;
					if(imgs[i].nomano[j].ini.y - borde < 0)
						u = borde;	
					else 
						u = imgs[i].nomano[j].ini.y;

					if(imgs[i].nomano[j].fin.y + borde >= height)
						U = height - borde;	
					else 
						U = imgs[i].nomano[j].fin.y;

					for(; u < U; u++){
						int v,V;

						if(imgs[i].nomano[j].ini.x - borde < 0)
							v = borde;	
						else 
							v = imgs[i].nomano[j].ini.x;

						if(imgs[i].nomano[j].fin.x + borde >= width)
							V = width - borde;	
						else 
							V = imgs[i].nomano[j].fin.x;

						for(; v < V; v++){
							fprintf(fpixel3,"\n");
							for(int m = -1*borde; m <= borde; m++){
								for(int n = -1*borde; n <= borde; n++){
									fprintf(fpixel3,"%d %d %d ",data[(u+m)*step+(v+n)*3],data[(u+m)*step+(v+n)*3+1],data[(u+m)*step+(v+n)*3+2]);
								}
							}
							fprintf(fpixel3,"0");
							cont++;
						}

					}
				}
				fflush(fpixel3);
			}
		}


		if( key == 27 ) break;
	}

	fclose(fmano);
	fclose(fnomano);
	fclose(fpixel);
	fclose(fpixel3);
	n = imgs.size();
	for(int k=0; k < n; k++){
		cvReleaseImage(&imgs[k].img);
	}
	cvDestroyWindow( "ventana" );
}

