package uk.co.beercave.gunboat.renderers;

import uk.co.beercave.gunboat.ResourceManager;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.graphics.g2d.BitmapFont.TextBounds;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.Pool;
import com.badlogic.gdx.utils.Pool.Poolable;

public class GuiRenderer {

	public static GuiRenderer instance;
	public OrthographicCamera camera;
	private SpriteBatch batch;
	
	private interface GuiItem{};
	private class TextItem implements GuiItem, Poolable{
		public String text;
		public BitmapFont font;
		public float x;
		public float y;
		public float scale;
		public Color color = new Color();
		@Override
		public void reset() {
			text = null;
			font = null;
			x = 0;
			y = 0;
			scale = 1;
			color.set(1,1,1,1);
		}
	}
	private class SpriteItem implements GuiItem, Poolable{
		public TextureRegion tx;
		public float x;
		public float y;
		public float scalex;
		public float scaley;
		public Color color = new Color();
		@Override
		public void reset() {
			tx = null;
			x = 0;
			y = 0;
			scalex = 1;
			scaley = 1;
			color.set(1,1,1,1);
		}
	}
	private Pool<TextItem> textPool = new Pool<GuiRenderer.TextItem>(){

		@Override
		protected TextItem newObject() {
			return new TextItem();
		}
		
	};
	private Pool<SpriteItem> spritePool = new Pool<GuiRenderer.SpriteItem>(){
		
		@Override
		protected SpriteItem newObject() {
			return new SpriteItem();
		}
		
	};
	
	
	private Array<GuiItem> items;
	
	private GuiRenderer(){
		items = new Array<GuiRenderer.GuiItem>();
	}
	public static void initialise(OrthographicCamera camera, SpriteBatch batch) {
		if (instance == null) instance = new GuiRenderer();
		instance.camera = camera;
		instance.batch = batch;
	}
	
	private Vector3 touchpos = new Vector3();
	private boolean touched;
	private boolean justtouched;
	public static void update(){
		//get touch position relative to camera for GUI interactions this frame
		instance.touched = Gdx.input.isTouched();
		instance.justtouched = Gdx.input.justTouched();
		instance.touchpos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
		instance.camera.unproject(instance.touchpos);
	}
	public static void render(){
		instance.renderItems();
	}
	public void renderItems(){
		//explicit loop saves generating an iterator
		batch.begin();
		for(int i=items.size-1; i>=0; i--){
			GuiItem g = items.get(i);
			renderItem(g);
			items.removeIndex(i);
		}
		batch.end();
	}
	private void renderItem(GuiItem g) {
		if (g instanceof TextItem){
			TextItem t = (TextItem)g;
			t.font.setScale(t.scale);
			t.font.setColor(t.color);
			t.font.draw(batch,  t.text, t.x, t.y);
			t.font.setScale(1);
			t.font.setColor(1,1,1,1);
			textPool.free(t);
		}else if (g instanceof SpriteItem){
			SpriteItem s = (SpriteItem)g;
			batch.setColor(s.color);
			float w = s.tx.getRegionWidth();
			float h = s.tx.getRegionHeight();
			float w2 = w/2;
			float h2 = h/2;
			batch.draw(s.tx, s.x, s.y, w2, h2, w, h, s.scalex, s.scaley, 0);
			batch.setColor(1, 1, 1, 1);
		}
		
	}
	
	public static boolean Button(String text, float x, float y, float scale){
		return Button(ResourceManager.defaultFont, text, x, y, scale, Color.WHITE);
	}
	public static boolean Button(String text, float x, float y){
		return Button(ResourceManager.defaultFont, text, x, y, 1, Color.WHITE);
	}
	private static boolean Button(BitmapFont font, String text, float x, float y, float scale) {
		
		return Button(ResourceManager.defaultFont, text, x, y, scale, Color.WHITE);
	}
	
	public static boolean Button(String text, float x, float y, float scale, Color color){
		return Button(ResourceManager.defaultFont, text, x, y, scale, color);
	}
	public static boolean Button(String text, float x, float y, Color color){
		return Button(ResourceManager.defaultFont, text, x, y, 1, color);
	}
	private static Rectangle r = new Rectangle();
	private static boolean Button(BitmapFont font, String text, float x, float y, float scale, Color color) {
		TextItem item = instance.textPool.obtain();
		item.font = font;
		item.text = text;
		item.color.set(color);
		item.x = x;
		item.y = y;
		item.scale = scale;
		instance.items.insert(0, item);
		
		font.setScale(scale);
		TextBounds b = font.getBounds(text);
		font.setScale(1);
		r.set(x, y-b.height, b.width, b.height);
		if (instance.justtouched){
			Gdx.app.log("", String.format("Checking touch point %s against %s", instance.touchpos, r));
		}
		return instance.justtouched && r.contains(instance.touchpos.x, instance.touchpos.y);
	}
	
	public static void Text(String text, float x, float y, float scale){
		Text(ResourceManager.defaultFont, text, x, y, scale, Color.WHITE);
	}
	public static void Text(String text, float x, float y){
		Text(ResourceManager.defaultFont, text, x, y, 1, Color.WHITE);
	}
	private static void Text(BitmapFont font, String text, float x, float y, float scale) {

		Text(ResourceManager.defaultFont, text, x, y, scale, Color.WHITE);
	}
	
	public static void Text(String text, float x, float y, float scale, Color color){
		Text(ResourceManager.defaultFont, text, x, y, scale, color);
	}
	public static void Text(String text, float x, float y, Color color){
		Text(ResourceManager.defaultFont, text, x, y, 1, color);
	}
	private static void Text(BitmapFont font, String text, float x, float y, float scale, Color color) {
		TextItem item = instance.textPool.obtain();
		item.font = font;
		item.text = text;
		item.color.set(color);
		item.x = x;
		item.y = y;
		item.scale = scale;
		instance.items.insert(0, item);
		
	}

	public static void Sprite(TextureRegion tx, float x, float y, float scalex, float scaley){
		Sprite(tx, x, y, scalex, scaley, Color.WHITE);
	}
	public static void Sprite(TextureRegion tx, float x, float y, float scale){
		Sprite(tx, x, y, scale, Color.WHITE);
	}
	public static void Sprite(TextureRegion tx, float x, float y, float scale,
			Color color) {
		Sprite(tx, x, y, scale, scale, color);
	}
	public static void Sprite(TextureRegion tx, float x, float y, float scalex, float scaley,
			Color color) {
		SpriteItem item = instance.spritePool.obtain();
		item.tx = tx;
		item.x = x;
		item.y = y;
		item.scalex = scalex;
		item.scaley = scaley;
		item.color.set(color);
		instance.items.insert(0, item);
		
	}
	
	
	

}
