package com.cringe_studios.christmastreescanning.scanning;

import java.awt.Color;
import java.awt.Point;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

import com.cringe_studios.christmastreescanning.Point3D;

public class PointNormalizer {
	
	
	// This method normalizes the Point coordinates,
	// Optionally flips them horizontally
	// Adjusts the height (y-coordinate) to make the virtual points not squished (puts them into a rectangle)
	// Returns the Points as Point2D
	public Point2D[] normalizePoints(Point[] points, boolean isBacksite) {
		if(points == null) return null;
		
		Point2D normalizedPoints[] = new Point2D.Double[points.length];
		for(int i = 0; i < normalizedPoints.length; i++) {
			
		}
		
		//TODO is this still needed?
		
		if(isBacksite) {
			for(int i = 0; i < normalizedPoints.length; i++) {
				normalizedPoints[i].setLocation(-normalizedPoints[i].getX(), normalizedPoints[i].getY()); 
			}
		}
		
		return normalizedPoints;
	}
	
	/**
	 * Normalizes 3D points with the given parameters and returns a NEW array with the normalized points. To see which coordinate dimension represents what direction, view Point3D class
	 * @param points
	 * @param baseline for z coordinates. Can be different to the lowest LED
	 * @param minX minimal X value of LED box
	 * @param minY minimal Y value of LED box
	 * @param maxX maximal X value of LED box
	 * @param maxY maximal Y value of LED box
	 * @return new Array with  normalized Points
	 */
	public Point3D[] normalizePoints(Point3D[] points, double baseline, double minX, double minY, double maxX, double maxY) {		
		Point3D normalizedPoints[] = new Point3D[points.length];
		for(int i = 0; i < normalizedPoints.length; i++) {
			double normalizedX = (points[i].x - minX) / (maxX - minX);
			double normalizedY = (points[i].y - minY) / (maxY - minY);
			double normalizedZ = ((baseline - points[i].z) - minX) / (maxX - minX);
			
			normalizedX = normalizedX * 2.0 - 1.0;
			normalizedY = normalizedY * 2.0 - 1.0;
			
			normalizedPoints[i] = new Point3D(normalizedX, normalizedY, normalizedZ);
		}
		
		return normalizedPoints;
	}
	
	public Point3D[] normalizePoints(Point3D[] points, double baseline) {
		double lowestX = Double.POSITIVE_INFINITY;
		double highestX = Double.NEGATIVE_INFINITY;
		
		for(int i = 0; i < points.length; i++) {
			if(lowestX > points[i].x) {
				lowestX = points[i].x;
			}
			
			if(highestX < points[i].x) {
				highestX = points[i].x;
			}
		}
		
		return normalizePoints(points, baseline, lowestX, highestX, lowestX, highestX);
	}
	
	public Point3D[] normalizePoints(Point3D[] points) {
		double lowestZ = Double.POSITIVE_INFINITY;
		
		for(int i = 0; i < points.length; i++) {
			if(lowestZ > points[i].z) {
				lowestZ = points[i].z;
			}
		}
		
		return normalizePoints(points, lowestZ);
	}
}
