package descriptors;

import java.awt.image.BufferedImage;

import preprocessing.Util;
import segmentation.Labels;
import segmentation.Regions;

public class Polar {
	
	final double M_PI = 3.14159265358979323846;
	
	public BufferedImage pol_computePolarImage (Labels lab, Regions[] regions, int studied_region, int ANGLE, int RAYON)
	{
		int bclX, bclY;
		int l;
		int d_max=0;
		double pas_angulaire;
		double pas_largeur;
		double r_pol;
		int r;
		double theta;
		Regions reg = regions[studied_region];

		int width = lab.getWidth();

		BufferedImage outimg = new BufferedImage(ANGLE, RAYON, BufferedImage.TYPE_INT_ARGB);

		int[] outarray = new int[ANGLE*RAYON];

		int x_min = reg.getXmin ();
		int x_max = reg.getXmax ();
		int y_min = reg.getYmin ();
		int y_max = reg.getYmax ();

		int xg = reg.getXg();
		int yg = reg.getYg();

		//System.out.println("Rayon : " +  RAYON + " Angle : " + ANGLE + " x_min : " + x_min + " x_max : " + x_max + " y_min : " + y_min+ " y_max : " + y_max);
		
		for(bclY = y_min; bclY <= y_max; bclY++)
			for(bclX = x_min; bclX <= x_max; bclX++) {
				if (lab.getValue(bclX + bclY*width) == studied_region) {
					int distance=(int)(Math.ceil(Math.sqrt( (bclX-xg)*(bclX-xg)+(bclY-yg)*(bclY-yg) ) ) ) ;
					d_max=(distance>d_max)?distance:d_max;
				}
			}

		pas_angulaire=( M_PI*2.0 / ANGLE ); //1.0/(double)RAYON;
		//System.out.println("pas_ang : " + pas_angulaire);
		pas_largeur=(double)d_max/(double)RAYON;
		//System.out.println("pas_largeur : " + pas_largeur + " dmax : " + d_max);
		r_pol=0;l=0;
		for(r=0;r<RAYON;r++) {
			for(theta=0;theta<(2.0*M_PI-0.00001);theta+=pas_angulaire) {
				int X=xg+(int)Math.round(r_pol*Math.cos(theta));
				int Y=yg+(int)Math.round(r_pol*Math.sin(theta));
				if (X > x_max || X < x_min) {
					outarray[l++]=0;
					continue;
				}
				if (Y > y_max || Y < y_min) {
					outarray[l++]=0;
					continue;
				}
				if (lab.getValue(X + Y * width) == studied_region) {
					outarray[l++]=255;
				} else {
					outarray[l++]=0;
				}
			}
			r_pol+=pas_largeur;
		}
		//for(r = 0;r < (ANGLE *RAYON);r++) {
		//	System.out.println("pos : " + r + " pixel : " + outarray[r]);
		//}
		
		int startX = 0; int startY = 0;
		Util.recoverBufferColorImage (outarray, ANGLE, RAYON);
		outimg.setRGB(startX, startY, ANGLE, RAYON, outarray, 0, ANGLE);
		return outimg;
	}
	
	public BufferedImage pol_TF (BufferedImage inimg, int ANGLE, int RAYON)
	{
		int width = ANGLE;
		int height = RAYON;

		int[] inarray = Util.transformBufferColorImage(inimg);
		
		BufferedImage outimg = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
		
		int[] outarray = new int[width*height];

		//System.out.println("Rayon : " +  RAYON + " Angle : " + ANGLE);
		
		int i,j,k;
		int offset, offsetY;
		int u;
		for(j = 0, offset = 0, offsetY = 0; j < RAYON; j++, offsetY += width) {
			for(u=-ANGLE/2+1,i=0;i<ANGLE;i++,u++) {
				double d1 = 0.0, d2 = 0.0;
				for(k=0;k<ANGLE;k++) {
					d1+=inarray[offsetY+k]*Math.cos((-2*M_PI*u*k)/ANGLE);
					d2+=inarray[offsetY+k]*Math.sin((-2*M_PI*u*k)/ANGLE);
					//if (k == 0 || k == (ANGLE - 1))
					//  System.out.println(" d1 : " + d1 + " inarray : " + inarray[offsetY+k] + " offset : " + offsetY+k + " cos : " + Math.cos(-2*Math.PI*u*k/ANGLE));
				}
				d1 = (d1/(double)ANGLE);
				d2 = (d2/(double)ANGLE);
				
			
				outarray[offset] = (int)(Math.round(Math.sqrt(d1*d1+d2*d2)));
				//outarray[offset] = (int)(Math.sqrt(Math.round(d1*d1+d2*d2)));
		
				//outarray[offset] = (int)(Math.round(Math.sqrt(d1*d1+d2*d2)));
				//System.out.println("j: " + j + " offset : " + offset + " outarray : " + outarray[offset] + " d1 : " + d1 + " d2 : " + d2);
				//System.out.println("round : " + Math.round(Math.sqrt(d1*d1+d2*d2)) + " sqrt : " + Math.sqrt(d1*d1+d2*d2));
				offset++;
			}
		}
		int startX = 0; int startY = 0;
		Util.recoverBufferColorImage (outarray, width, height);
		outimg.setRGB(startX, startY, width, height, outarray, 0, width);
		return outimg;
	}

}
