package speiger.src.coreengine.ui.gui.component.base;

import speiger.src.coreengine.ui.gui.layout.box.IGuiBox;

public interface ILayoutComponent {
	public void calculateBounds(ILayoutScanner output);
	public IGuiBox getBox();
	
	public default float getX() {
		return getBox().getMinX();
	}
	
	public default float getY() {
		return getBox().getMinY();
	}
	
	public default float getWidth() {
		return getBox().getWidth();
	}
	
	public default float getHeight() {
		return getBox().getHeight();
	}
	
	public ILayoutComponent set(float x, float y);
	public ILayoutComponent bounds(float width, float height);
	public ILayoutComponent resize(float width, float height);
	public ILayoutComponent move(float moveX, float moveY);
	
	public static interface ILayoutScanner {
		public default void accept(IGuiBox box) { accept(box.getMinX(), box.getMinY(), box.getMaxX(), box.getMaxY()); }
		public void accept(float minX, float minY, float maxX, float maxY);
		public boolean acceptsInvisble();
		
		public static ArrayFetcher of() { return new ArrayFetcher(false); }
		public static ArrayFetcher includeInvisible() { return new ArrayFetcher(true); }
	}
	
	public static class ArrayFetcher implements ILayoutScanner {
		private static final int INDEX_MIN_X = 0;
		private static final int INDEX_MIN_Y = 1;
		private static final int INDEX_MAX_X = 2;
		private static final int INDEX_MAX_Y = 3;
		float[] result = new float[] {Float.MAX_VALUE, Float.MAX_VALUE, -Float.MAX_VALUE, -Float.MAX_VALUE};
		boolean includeInvisible = false;
		
		public ArrayFetcher(boolean includeInvisible) {
			this.includeInvisible = includeInvisible;
		}
		
		@Override
		public boolean acceptsInvisble() {
			return includeInvisible;
		}
		
		@Override
		public void accept(float minX, float minY, float maxX, float maxY) {
			result[INDEX_MIN_X] = Math.min(minX, result[INDEX_MIN_X]);
			result[INDEX_MIN_Y] = Math.min(minY, result[INDEX_MIN_Y]);
			result[INDEX_MAX_X] = Math.max(maxX, result[INDEX_MAX_X]);
			result[INDEX_MAX_Y] = Math.max(maxY, result[INDEX_MAX_Y]);
		}
		
		public void reset() {
			result[0] = Float.MAX_VALUE;
			result[1] = Float.MAX_VALUE;
			result[2] = -Float.MAX_VALUE;
			result[3] = -Float.MAX_VALUE;
		}
		
		public void hardReset() {
			result = new float[] {Float.MAX_VALUE, Float.MAX_VALUE, -Float.MAX_VALUE, -Float.MAX_VALUE};
		}
		
		public float[] result() {
			return result;
		}
		
		public float[] unscaledResult(IGuiBox owner) {
			float[] unscaled = new float[4];
			for(int i = 0;i<4;i++) {
				unscaled[i] = result[i] / owner.getScale();
			}
			return unscaled;
		}
	}
}
