package speiger.src.coreengine.rendering.inputOld.window;

import java.util.List;

import org.lwjgl.PointerBuffer;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.glfw.GLFWVidMode;

import speiger.src.collections.longs.maps.impl.hash.Long2ObjectLinkedOpenHashMap;
import speiger.src.collections.longs.maps.interfaces.Long2ObjectMap;
import speiger.src.collections.objects.lists.ObjectArrayList;

public class Monitor
{
	final long monitor;
	List<VideoMode> modes = new ObjectArrayList<>();
	VideoMode defaultMode;
	int xOffset;
	int yOffset;
	
	public Monitor(long monitor) {
		this.monitor = monitor;
		GLFWVidMode.Buffer buffer = GLFW.glfwGetVideoModes(monitor);
		for(int i = buffer.limit() - 1;i >= 0;--i) {
			VideoMode videomode = new VideoMode(this, buffer.position(i));
			if(videomode.redBits() >= 8 && videomode.greenBits() >= 8 && videomode.blueBits() >= 8)
				modes.add(videomode);
		}
		defaultMode = new VideoMode(this, GLFW.glfwGetVideoMode(monitor));
		int[] xPos = new int[1];
		int[] yPos = new int[1];
		GLFW.glfwGetMonitorPos(monitor, xPos, yPos);
		xOffset = xPos[0];
		yOffset = yPos[0];
	}
	
	public String getMonitorName() {
		return GLFW.glfwGetMonitorName(monitor);
	}
	
	public long getMonitorId() {
		return monitor;
	}
	
	public int size() {
		return modes.size();
	}
	
	public VideoMode getMode(int index) {
		return modes.get(index);
	}
	
	public boolean contains(VideoMode mode) {
		return modes.indexOf(mode) != -1;
	}
	
	public List<VideoMode> getVideoMods() {
		return new ObjectArrayList<>(modes);
	}
	
	public VideoMode getDefaultMode() {
		return defaultMode;
	}
	
	public int getXOffset() {
		return xOffset;
	}
	
	public int getYOffset() {
		return yOffset;
	}
	
	public long getInBounds(Window window) {
		if(xOffset <= window.getXPos() + window.getActualWidth() && xOffset + defaultMode.width() >= window.getXPos() && yOffset <= window.getYPos() + window.getActualHeight() && yOffset + defaultMode.height() >= window.getYPos()) {
			int xArea = Math.abs(window.getActualWidth() * defaultMode.width());
			int yArea = Math.abs(window.getActualHeight() * defaultMode.height());
			int areaI = (Math.min(window.getXPos() + window.getActualWidth(), xOffset + defaultMode.width()) - Math.max(window.getXPos(), xOffset)) * (Math.min(window.getYPos() + window.getActualHeight(), yOffset + defaultMode.height()) - Math.max(window.getYPos(), yOffset));
			return (xArea + yArea) - areaI;
		}
		return 0L;
	}
	
	public static Long2ObjectMap<Monitor> createMonitors() {
		Long2ObjectMap<Monitor> monitors = new Long2ObjectLinkedOpenHashMap<>();
		PointerBuffer buffer = GLFW.glfwGetMonitors();
		for(int i = 0,m=buffer.limit();i<m;i++) {
			long id = buffer.get();
			monitors.put(id, new Monitor(id));
		}
		return monitors;
	}
}
