package zero1hd.rhythmbullet.graphics.ui.components;

import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
import com.badlogic.gdx.graphics.g2d.NinePatch;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Widget;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.scenes.scene2d.utils.ScissorStack;

public class ScrollingText extends Widget {
	Rectangle scissors = new Rectangle();
	Rectangle clipBounds = new Rectangle();
	
	GlyphLayout gLayout;
	String text1;
	String text2;
	BitmapFont font;
	private float textHeight;
	private float text1Width;
	private float text2Width;
	
	private boolean dupFirstText;
	private boolean scrollOnHover;
	private boolean scroll;
	
	private float text1Offset, text2Offset;
	
	private NinePatch background;
	
	private Vector2 coords;
	
	private float targetDelta;
	
	public ScrollingText(String text, String text2, Skin skin, boolean scrollOnHover, boolean useBackground, float targetDelta) {
		super();
		font = skin.getFont("default-font");
		init(text, text2, skin, scrollOnHover, useBackground);
		this.targetDelta = targetDelta;
	}
	
	public ScrollingText(String text, String text2, Skin skin, String fontName, Color color, boolean scrollOnHover, boolean useBackground) {
		super();
		font = skin.getFont(fontName);
		font.setColor(color);
		init(text, text2, skin, scrollOnHover, useBackground);
	}
	
	private void init(String text1, String text2, Skin skin, boolean scrollOnHover, boolean useBackground) {
		setName(text1);
		if (useBackground) {
			this.background = skin.getPatch("side-bars");
		}
		
		this.scrollOnHover = scrollOnHover;
		
		coords = new Vector2();
		addListener(new ClickListener() {
			@Override
			public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) {
				scroll = true;
				super.enter(event, x, y, pointer, fromActor);
			}
			
			@Override
			public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) {
				scroll = false;
				super.exit(event, x, y, pointer, toActor);
			}
			
			@Override
			public void clicked(InputEvent event, float x, float y) {
			}
		});
		
		setText(text1, text2);
		layout();
	}
	
	public float getFontHeight() {
		return textHeight;
	}
	
	public float getFontWidth() {
		return text1Width;
	}
	
	@Override
	public void layout() {
		super.layout();

		if (getHeight() < (textHeight+4)) {
			setHeight(textHeight + 4);
		}
		clipBounds.setSize(getWidth()-2, getHeight()*1.5f);
		
		text2Offset = clipBounds.getWidth();
		if (text1Width < clipBounds.getWidth()) {
			text1Offset = (clipBounds.getWidth()-text1Width)/2f;
		}
	}
	
	public void scroll(float delta) {
		if (text1Offset >= -text1Width) {
			text1Offset -= 60*targetDelta;
			if ((text1Offset < - Math.abs((text1Width - clipBounds.getWidth())) - 50) || text2Offset != clipBounds.getWidth()) {
				text2Offset -= 60*targetDelta;
				if (text2Offset <= -text2Width) {
					text2Offset = clipBounds.getWidth();
				}
			}

		} else {
			text2Offset -= 60*targetDelta;
			if (text2Offset < - Math.abs((text2Width - clipBounds.getWidth())) - 50) {
				text1Offset = clipBounds.getWidth();
			}
		}
	}
	
	@Override
	public void act(float delta) {
		clipBounds.setSize(getWidth()-2, getHeight()*1.5f);
		if (dupFirstText) {
			if (text1Width > clipBounds.getWidth()) {
				if (scrollOnHover) {
					if (scroll || text1Offset < 0 || text1Offset > 2) {
						scroll(delta);
					}
				} else {
					scroll(delta);
				}
			}
		} else {
			if (text1Width + text2Width > clipBounds.getWidth()) {
				if (scrollOnHover) {
					if (scroll || text1Offset < 0 || text1Offset > 2) {
						scroll(delta);
					}
				} else {
					scroll(delta);
				}
			}
		}
		super.act(delta);
	}
	
	@Override
	public void draw(Batch batch, float parentAlpha) {
		if (background != null) {
			background.draw(batch, getX(), getY(), getWidth(), getHeight());
		}
		coords.x = getX();
		coords.y = getY();
		
		clipBounds.setX(coords.x+1);
		clipBounds.setY(coords.y - 0.5f*getHeight());
		
		getStage().calculateScissors(clipBounds, scissors);
		batch.flush();
		if (ScissorStack.pushScissors(scissors)) {
			font.draw(batch, text1, coords.x + text1Offset, coords.y + getFontHeight() + 4);
			font.draw(batch, text2, coords.x + text2Offset, coords.y + getFontHeight() + 4);
			batch.flush();
			ScissorStack.popScissors();
		}
		
		super.draw(batch, parentAlpha);
	}
	
	@Override
	public float getMinHeight() {
		return textHeight;
	}
	
	/**
	 * Sets the two strings that will be scrolling.
	 * @param text1 cannot be null.
	 * @param text2 can be null.
	 */
	public void setText(String text1, String text2) {
		this.text1 = text1;
		gLayout = new GlyphLayout(font, text1);
		text1Width = gLayout.width;
		textHeight = gLayout.height;
		
		if (text2 != null) {
			this.text2 = text2;
			gLayout = new GlyphLayout(font, text2);
			text2Width = gLayout.width;
		} else {
			dupFirstText = true;
			this.text2 = text1;
			this.text2Width = text1Width;
		}
		
		layout();
	}
}
