package projectzombie.menu.gui;

import java.util.ArrayList;

import org.lwjgl.opengl.GL33;

import gl_engine.matrix.Matrix4;
import gl_engine.vec.Vec2d;
import gl_engine.vec.Vec3d;
import projectzombie.Main;
import projectzombie.init.Models;

public class GUIContainerSlider implements GUIComponent, GUIContainer
{
	private ArrayList<GUIComponent> components = new ArrayList<GUIComponent>();
	private Vec2d pos;
	private Vec2d size;
	private double length;
	private double scroll = 0;
	
	public GUIContainerSlider(Vec2d pos, Vec2d size, double length)
	{
		if(length < 0) {
			length = 0;
		}
		
		this.pos = pos;
		this.size = size;
		this.length = length;
	}
	
	public void setLength(double length)
	{
		if(length < 0) {
			length = 0;
		}
		
		this.length = length;
	}

	@Override
	public void add(GUIComponent c) {
		components.add(c);
	}

	@Override
	public void render(Matrix4 matrix, Vec2d mousePos, boolean canHover)
	{
		if(mousePos.y < pos.y || mousePos.y > pos.y + size.y) {
			canHover = false;
		}
		
		matrix = Matrix4.multiply(matrix, Matrix4.translate(0, scroll, 0));
		mousePos = mousePos.add(new Vec2d(0, -scroll));
		
		GL33.glUniform1i(Main.window.glsl_do_discard_coords, 1);
		GL33.glUniform4f(Main.window.glsl_discard_coords,
				(float)pos.x, (float)pos.y, (float)(pos.x + size.x), (float)(pos.y + size.y));
		
		for(GUIComponent c : components) {
			c.render(matrix, mousePos, canHover);
		}
		
		if(length > 0)
		{
			GL33.glUniform4f(Main.window.glsl_color, 0.25f, 0.25f, 0.25f, 1);
			
			double start = size.y * scroll / (length + size.y);
			double end = size.y * (scroll + size.y) / (length + size.y);
			
			Matrix4 matrix_scroll_bar = Matrix4.translate(
					pos.x + size.x - 0.125f,
					pos.y + size.y - end, 0);
			
			matrix_scroll_bar = Matrix4.multiply(Matrix4.scale(
					new Vec3d(1, (float)(end - start), 1)), matrix_scroll_bar);
			
			Models.UI_PIXEL_WHITE.setModel(matrix_scroll_bar);
			Models.UI_PIXEL_WHITE.render();
			
			GL33.glUniform4f(Main.window.glsl_color, 1, 1, 1, 1);
		}
		
		GL33.glUniform1i(Main.window.glsl_do_discard_coords, 0);
	}

	@Override
	public void update(Vec2d mousePos)
	{
		if(mousePos.y < pos.y || mousePos.y > pos.y + size.y) {
			return;
		}
		
		mousePos = mousePos.add(new Vec2d(0, -scroll));
		
		for(GUIComponent c : components) {
			c.update(mousePos);
		}
	}

	@Override
	public boolean checkMouseHover(Vec2d pos) {
		return true;
	}

	@Override
	public void onRightClick(Vec2d mousePos)
	{
		if(mousePos.y < pos.y || mousePos.y > pos.y + size.y) {
			return;
		}
		
		mousePos = mousePos.add(new Vec2d(0, -scroll));
		
		for(GUIComponent c : components) {
			if(c.checkMouseHover(mousePos)) {
				c.onRightClick(mousePos);
			}
		}
	}

	@Override
	public void onMouseClick(Vec2d mousePos)
	{
		if(mousePos.y < pos.y || mousePos.y > pos.y + size.y) {
			return;
		}
		
		mousePos = mousePos.add(new Vec2d(0, -scroll));
		
		for(GUIComponent c : components) {
			if(c.checkMouseHover(mousePos)) {
				c.onMouseClick(mousePos);
			}
		}
	}

	@Override
	public void onActivate() {
		for(GUIComponent c : components) {
			c.onActivate();
		}
	}

	@Override
	public void onBack() {
		for(GUIComponent c : components) {
			c.onBack();
		}
	}
	
	@Override
	public void onScroll(Vec2d mousePos, double amount)
	{
		// Only scroll if the mouse is hovering over the scroll area
		if(
				mousePos.x > pos.x && mousePos.x < pos.x + size.x &&
				mousePos.y > pos.y && mousePos.y < pos.y + size.y)
		{
			scroll -= amount;
			
			if(scroll < 0) {
				scroll = 0;
			}
			
			if(scroll > length) {
				scroll = length;
			}
		}
		
		for(GUIComponent c : components) {
			c.onScroll(mousePos, amount);
		}
	}
	
	@Override
	public void clear() {
		components.clear();
	}
	
	@Override
	public GUIItemSlot getHoveringItemSlot(Vec2d mousePos)
	{
		if(mousePos.y < pos.y || mousePos.y > pos.y + size.y) {
			return null;
		}
		
		mousePos = mousePos.add(new Vec2d(0, -scroll));
		
		for(GUIComponent c : components)
		{
			if(c.checkMouseHover(mousePos))
			{
				if(c instanceof GUIItemSlot) {
					return (GUIItemSlot)c;
				}
				
				if(c instanceof GUIContainer)
				{
					GUIItemSlot slot = ((GUIContainer)c).getHoveringItemSlot(mousePos);
					
					if(slot != null) {
						return slot;
					}
				}
			}
		}
		
		return null;
	}

}
