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

import speiger.src.coreengine.math.MathUtils;
import speiger.src.coreengine.rendering.guiOld.GuiComponent;
import speiger.src.coreengine.rendering.guiOld.base.IButtonComponent;
import speiger.src.coreengine.rendering.guiOld.helper.box.IGuiBox;

public class ScrollBarComponent extends GuiComponent implements IButtonComponent
{
	public static final int FLAG_HORIZONTAL = 1 << 20;
	public static final int FLAG_INVERTED = 1 << 21;
	int color;
	float lastMouse = -1;
	int current;
	int max;
	
	public ScrollBarComponent(int color)
	{
		super(0F, 0F, 0F, 0F);
		this.color = color;
	}
	
	public ScrollBarComponent(int color, int max)
	{
		super(0F, 0F, 0F, 0F);
		this.color = color;
		this.max = max;
	}
	
	public ScrollBarComponent(int color, int max, int current)
	{
		super(0F, 0F, 0F, 0F);
		this.color = color;
		this.max = max;
		this.current = current;
	}
	
	public ScrollBarComponent(float x, float y, float width, float height, int color)
	{
		super(x, y, width, height);
		this.color = color;
	}
	
	public ScrollBarComponent(float x, float y, float width, float height, int color, int max)
	{
		super(x, y, width, height);
		this.color = color;
		this.max = max;
	}
	
	public ScrollBarComponent(float x, float y, float width, float height, int color, int max, int current)
	{
		super(x, y, width, height);
		this.color = color;
		this.max = max;
		this.current = current;
	}
	
	@Override
	public void init()
	{
		
	}
	
	public ScrollBarComponent setColor(int color)
	{
		this.color = color;
		return this;
	}
	
	public ScrollBarComponent setScrollMax(int max)
	{
		this.max = max;
		return addScroll(0);
	}
	
	public ScrollBarComponent addScroll(int add)
	{
		return setScrollCurrent(current + add);
	}
	
	public ScrollBarComponent setScrollEnd()
	{
		return setScrollCurrent(max);
	}
	
	public ScrollBarComponent setScrollStart()
	{
		return setScrollCurrent(0);
	}
	
	public ScrollBarComponent setScrollCurrent(int current)
	{
		this.current = (int)MathUtils.clamp(0F, Math.max(0, max - getBaseRange()), current);
		return this;
	}
	
	protected int getCurrent()
	{
		return current;
	}
	
	protected void setCurrent(int value)
	{
		current = value;
	}
	
	public ScrollBarComponent setHorizontal(boolean value)
	{
		setFlag(FLAG_HORIZONTAL, value);
		return this;
	}
	
	public ScrollBarComponent setInverted(boolean value)
	{
		setFlag(FLAG_INVERTED, value);
		return this;
	}
	
	public boolean isHorizontal()
	{
		return isFlagSet(FLAG_HORIZONTAL);
	}
	
	public int getScroll()
	{
		return current;
	}
	
	public boolean isAtEnd()
	{
		return (max - getBaseRange()) <= current;
	}
	
	public boolean isInUse()
	{
		return (max - getBaseRange()) > 0F;
	}
	
	public float getRequiredSpace()
	{
		return (max - getBaseRange()) > 0F ? (isHorizontal() ? getBox().getHeight() : getBox().getWidth()) : 0F;
	}
	
	@Override
	public boolean isComponentColliding(int mouseX, int mouseY)
	{
		return isInUse() && isHovered(mouseX, mouseY);
	}
	
	@Override
	public boolean renderSelf(int mouseX, int mouseY, float particalTicks)
	{
		float baseRange = getBaseRange();
		float extra = max - baseRange;
		if(extra <= 0)
		{
			return true;
		}
		IGuiBox box = getBox();
        float range = getRange();
        float min = getCurrent() * (baseRange - range) / extra;
        float brightness = getActiveBrightness();
		getRenderer().setBrightness(brightness * 0.5F).drawQuad(box, color);
		if(isHorizontal()) getRenderer().setBrightness(brightness * 1F).drawQuad(box.getMinX(min), box.getMinY(), box.getMinX(min + range), box.getMaxY(), 0.01F, color);
		else getRenderer().setBrightness(brightness * 1F).drawQuad(box.getMinX(), box.getMinY(min), box.getMaxX(), box.getMinY(min + range), 0.01F, color);
		getRenderer().setBrightness(1F);
		return true;
	}
	
	@Override
	public boolean onClick(int button, int mouseX, int mouseY)
	{
		float baseRange = getBaseRange();
		float extra = max - baseRange;
		if(extra <= 0F)
		{
			return false;
		}
		float range = getRange();
		float pos = (baseRange - range) / extra;
		float start = Math.max(0F, getCurrent() * pos);
		IGuiBox box = getBox();
	    float currentPos = (isHorizontal() ? box.getMinX(start) : box.getMinY(start)) + ((range * box.getScale()) / 2F);
	    float mouse = isHorizontal() ? mouseX : mouseY;
	    if(mouse < currentPos)
	    {
	    	setCurrent((int)Math.max(0F, getCurrent() - (((currentPos - mouse) / pos) / box.getScale())));
	    }
	    else if(mouse > currentPos)
	    {
	    	setCurrent((int)Math.min(extra, getCurrent() + (((mouse - currentPos) / pos) / box.getScale())));
	    }
	    lastMouse = mouse;
		return true;
	}
	
	@Override
	public boolean onDrag(int mouseX, int mouseY)
	{
		if(lastMouse != -1F)
		{
			float range = getRange();
			IGuiBox box = getBox();
			float mouse = (isHorizontal() ? mouseX - box.getMinX() : mouseY - box.getMinY()) - ((range * box.getScale()) / 2F);
			float baseRange = getBaseRange();
			float extra = max - baseRange;			
			setCurrent((int)MathUtils.clamp(0F, Math.max(0F, extra), (mouse / ((baseRange - range) / extra)) / box.getScale()));
			return true;
		}
		return false;
	}
	
	@Override
	public void onRelease(int button, int mouseX, int mouseY)
	{
		lastMouse = -1F;
	}
	
	@Override
	public boolean onScroll(int scroll, int mouseX, int mouseY)
	{
		float extra = max - getBaseRange();
		if(extra > 0F)
		{
			setCurrent((int)MathUtils.clamp(0, extra, current - (scroll * (extra / 10F))));
			return true;
		}
		return false;
	}
	
	protected float getBaseRange()
	{
		return isHorizontal() ? getBox().getBaseWidth() : getBox().getBaseHeight();
	}
	
	protected float getRange()
	{
		float value = getBaseRange();
		return MathUtils.clamp(10F, value, ((value * value) / max));
	}

}
