package com.cringe_studios.christmastreescanning;

import java.awt.geom.Point2D;
import java.util.Arrays;

import com.cringe_studios.christmastreescanning.scanning.PointInterpolator;

public class Homograph2 implements Homograph{
	// The 3D Homograph simply tries to find an intersection of two lines. One line comes from the "front" side, and the other line comes from the "right" side. These two sides are 90° apart.
	
	SingleHomograph homographs[];
	
	//Simple Implementation; does not account for:
	// - scanning error
	// - incorrect rotation of tree
	// - change of camera type midway through
	// - rotation of camera (accidently hitting laptop while scanning)
	// - different position of camera (laptop was moved while scanning)
	private class SingleHomograph{
		Point2D frontSidePoint;
		Point2D rightSidePoint;
		
		Point3D mergedPoint;
		
		public SingleHomograph(Point2D newFrontSidePoint, Point2D newRightSidePoint) {
			this.frontSidePoint = newFrontSidePoint;
			this.rightSidePoint = newRightSidePoint;
		}
		
		public void merge() {
			double newz = new PointInterpolator(frontSidePoint, rightSidePoint).getCenter().getY();
			double newx = frontSidePoint.getX(); //baseline
			double newy = rightSidePoint.getX(); //coming out of the image
			mergedPoint = new Point3D(newx, newy, newz);
		}
		
		public Point3D getPoint() {
			return mergedPoint;
		}
	}
	
	public Homograph2(Point2D[] frontSidePoints, Point2D[] rightSidePoints) {
		homographs = new SingleHomograph[frontSidePoints.length];
		for(int i = 0; i < frontSidePoints.length; i++) {
			homographs[i] = new SingleHomograph(frontSidePoints[i], frontSidePoints[i]);
		}
	}
	
	@Override
	public void merge() {
		// The implementation does not have to be perfect, as part of the requirement is, that after the scanning, the LEDs Position will be tested.
		
		Arrays.stream(homographs).forEach(i -> i.merge());
	}

	@Override
	public void renormalize() {
		//After the points are merged, depending on the implementation of the merging algorithm, the points might need to be renormalized
		//This specific Algorithm does not need to be renormalized
		//TODO double check that fact with a test
		
	}

	@Override
	public Point3D[] getPoints() {		
		return Arrays.stream(homographs).map(i -> i.getPoint()).toArray(Point3D[]::new);
	}
}
