package speiger.src.coreengine.rendering.gui.components;

import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
import speiger.src.coreengine.rendering.gui.helper.constrains.ConditionalConstraint;
import speiger.src.coreengine.rendering.gui.helper.constrains.Constrains;

public class ScrollWindowComponent extends WindowComponent
{
	public static final int FLAG_CORNER = 1 << 26;
	ScrollBarComponent horizontalBar = new ScrollBarComponent(ColorUtils.LIGHT_GRAY).setHorizontal(true);
	ScrollBarComponent verticalBar = new ScrollBarComponent(ColorUtils.LIGHT_GRAY);
	protected PanelComponent container = new PanelComponent().setManualRenderer(true).cast();
	PanelComponent viewPort = new PanelComponent().setManualRenderer(true).cast();
	
	public ScrollWindowComponent(int flags, String name)
	{
		super(0F, 0F, 0F, 0F, flags, name);
	}
	
	public ScrollWindowComponent(float x, float y, float width, float height, int flags, String name)
	{
		super(x, y, width, height, flags, name);
	}
	
	@Override
	public void init()
	{
		super.init();
		addChild(horizontalBar.onChange(minimizedListener), Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : verticalBar::isInUse, true, 5F));
		addChild(verticalBar.onChange(minimizedListener), Constrains.verticalScrollBar(isFlagSet(FLAG_CORNER) ? () -> true : horizontalBar::isInUse, 7.5F, 5F));
		viewPort.addChild(container);
		container.onChange(this::recalculateSize).onChange(minimizedListener);
		addChild(viewPort.set(0F, 7.5F), Constrains.width(ConditionalConstraint.parent(verticalBar::isInUse, 0F, 5F)).height(ConditionalConstraint.parent(horizontalBar::isInUse, 0F, 5F)).build());
	}
	
	public <T extends GuiComponent> T addComponent(T comp)
	{
		return container.addChild(comp);
	}
	
	public <T extends GuiComponent> T addComponent(T comp, Constrains constraints)
	{
		return container.addChild(comp, constraints);
	}
	
	public PanelComponent getContainer()
	{
		return container;
	}
	
	public PanelComponent getViewPort()
	{
		return viewPort;
	}
	
	public ScrollWindowComponent setForcedCorner(boolean value)
	{
		if(setFlag(FLAG_CORNER, value) && getGui() != null)
		{
			addConstrains(horizontalBar, Constrains.scrollBar(isFlagSet(FLAG_CORNER) ? () -> true : verticalBar::isInUse, true, 5F));
			addConstrains(verticalBar, Constrains.verticalScrollBar(isFlagSet(FLAG_CORNER) ? () -> true : horizontalBar::isInUse, 7.5F, 5F));
			onChanged(false);
		}
		return this;
	}
	
	protected void recalculateSize(GuiComponent owner)
	{
		float maxX = 0F;
		float maxY = 0F;
		for(GuiComponent component : container.getChildren())
		{
			IGuiBox box = component.getBox();
			maxX = Math.max(maxX, box.getBaseX() + box.getBaseWidth());
			maxY = Math.max(maxY, box.getBaseY() + box.getBaseHeight());
		}
		horizontalBar.setScrollMax((int)maxX);
		verticalBar.setScrollMax((int)maxY);
		horizontalBar.onChanged(true);
		verticalBar.onChanged(true);
		owner.bounds(maxX, maxY).set(-horizontalBar.getScroll(), -verticalBar.getScroll());
	}
	
	@Override
	protected boolean updateSelf(int mouseX, int mouseY, float particalTicks)
	{
		super.updateSelf(mouseX, mouseY, particalTicks);
		container.set(-horizontalBar.getScroll(), -verticalBar.getScroll());
		return true;
	}
	
	@Override
	protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
	{
		super.renderSelf(mouseX, mouseY, particalTicks);
		renderChildren(mouseX, mouseY, particalTicks);
		if(container.isVisible())
		{
			enableScissors(viewPort.getBox());
			getRenderer().translate(0F, 0F, 0.1F);
			container.render(mouseX, mouseY, particalTicks);
			getRenderer().translate(0F, 0F, -0.1F);
			disableScissors();
		}
		return false;
	}
}
