package com.elphel.imagej.orthomosaic;

import java.awt.Rectangle;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicInteger;

import com.elphel.imagej.common.PolynomialApproximation;
import com.elphel.imagej.tileprocessor.ImageDtt;

public class FloatImageData {
	public int       width;
	public int       height;
	public int       zoom_lev;
	public double [] vert = new double[2]; // x,y offset (in meters) of the point under the camera
	public float[]   data;
	public FloatImageData (
			int       width,
			int       height,
			int       zoom_lev,
			double [] vert, // x,y pixel offset of the point under the camera
			float[]   data) {
		this.width = width;
		this.height = height;
		this.zoom_lev = zoom_lev;
		this.vert = vert.clone();
		this.data = data;
	}

	public static int getZoomLevel(
			double pix_in_meters) {
		return getZoomLevel (pix_in_meters, null, null);
	}
	
	public static boolean isZoomValid(double pix_in_meters) {
		boolean [] is_zoom_valid = new boolean[1];
		getZoomLevel(pix_in_meters,is_zoom_valid, null);
		return is_zoom_valid[0];
	}
	
	public static double needZoomIn(double pix_in_meters) {
		double  [] extra_zoom = new double[1];
		getZoomLevel(pix_in_meters,null, extra_zoom);
		return extra_zoom[0];
	}
	
	/**
	 * Find scale level (0: 1pix/cm, 1 - 2pix/cm, -1 - 0.5 pix/cm) from pixel size in meters
	 * If scale does not match, provide false in optional valid_zoom[0]
	 * zoom_in_extra  
	 * @param pix_size_in_meters pixel size in meters (e.g. 0.02 means 2cm/pix)
	 * @param valid_zoom if provided boolean[1] will return true for valid scale
	 * @param zoom_in_extra enlarge (1.0x..2.0x) (reduce pixel size) to get to the standard scale 
	 * @return zoom level (the higher - the more detailed) 0: - 1cm/pix,-1: 2cm/pix, 1: 0.5 cm/pix 
	 */
	
	public static int getZoomLevel(
			double pix_size_in_meters, // pixel size in meters
			boolean [] valid_zoom,
			double []  zoom_in_extra) {
		int zl = 0;
		double e = 1E-6;
		double pix_size_in_cm = 100 * pix_size_in_meters; // pixel size in cm
		boolean vz = true;
		double ze = 1.0;
		if (pix_size_in_cm > (1.0-e)) { // low resolution, pixel size > 1cm
			zl++;
			while (pix_size_in_cm > (1.0-e)) {
				zl--;		
				pix_size_in_cm /= 2;
			} // exits with (1-e) >= pix_in_cm > 0.5 - e/2
			vz = pix_size_in_cm < (0.5+e);
			if (!vz) {
				ze = 2.0 * pix_size_in_cm;
			}
		} else { // high resolution, pixel size < 1 
//			zl--;
			while (pix_size_in_cm <= (1.0-e)) {
				zl++;		
				pix_size_in_cm *= 2;
			}// exits with (2-2*e) >= pix_in_cm > (1-e)
			vz = pix_size_in_cm < (1.0 + e);
			if (!vz) {
				ze = pix_size_in_cm;
			}
		}
		if (valid_zoom != null) {
			valid_zoom[0] = vz; 
		}
		if (zoom_in_extra != null) {
			zoom_in_extra[0] = ze;
		}
		return zl;
	}
	
	// processing altitudes to remove non-flat surfaces from fitting ortho maps
	
}
