package de.samdev.colorrunner.game.renderer;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
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.glutils.ShapeRenderer;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector3;

public abstract class AbstractGameRenderer {
	public final static float GAME_HEIGHT = 512;
	public final static float MIN_GAME_WIDTH = 672; // ~ 512 * (4/3)
	public final static float MAX_GAME_WIDTH = 1024; // ~ 512 * (2/1) // ~~ 16:9
	
	private final static float FREE_ROAM_WIDTH = 1f/2f;

	private int debugTextCount;
	private  int hudTextCount;
	
	protected OrthographicCamera cam;
	protected ShapeRenderer shapeRenderer;

	protected BitmapFont font = new BitmapFont();
	protected BitmapFont font2 = new BitmapFont();
	protected SpriteBatch spriteBatch = new SpriteBatch();
	protected SpriteBatch fontBatch = new SpriteBatch();
	protected SpriteBatch fontBatch2 = new SpriteBatch();

	public AbstractGameRenderer(float width, float height) {
		cam = new OrthographicCamera();

		shapeRenderer = new ShapeRenderer();

		resize(width, height);
	}

	public void render() {
		Gdx.gl.glClearColor(0.22f, 0.22f, 0.22f, 1f);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

		// #################

		doRender();
	}

	protected void updateCameraOffset(float lookAtX) {
		if (lookAtX > cam.position.x - cam.viewportWidth * FREE_ROAM_WIDTH/2) {
			cam.position.x += lookAtX - cam.position.x + cam.viewportWidth * FREE_ROAM_WIDTH/2;
			cam.update();
			updateCamMatrices();
		}

		if (lookAtX < cam.position.x - cam.viewportWidth/2) {
			cam.position.x += lookAtX - cam.position.x + cam.viewportWidth/2;
			cam.update();
			updateCamMatrices();
		}
	}

	public Rectangle getCamViewRectangle() {
		return new Rectangle(cam.position.x - cam.viewportWidth/2, cam.position.y - cam.viewportHeight/2, cam.viewportWidth, cam.viewportHeight);
	}

	public void resize(float width, float height) {
		float cam_width = (width / height) * GAME_HEIGHT;

		if (cam_width < MIN_GAME_WIDTH)
			Gdx.app.error("SIZE", "Minimal aspect ratio is 4:3");

		if (cam_width > MAX_GAME_WIDTH)
			Gdx.app.error("SIZE", "Maximal aspect ratio is 2:1");

		cam.setToOrtho(false, cam_width, GAME_HEIGHT);
		updateCamMatrices();
	}

	private void updateCamMatrices() {
		shapeRenderer.setProjectionMatrix(cam.combined);
		spriteBatch.setProjectionMatrix(cam.combined);
		fontBatch.setProjectionMatrix(cam.combined);
	}

	protected void beginDebug() {
		fontBatch.begin();
		font.setColor(1, 0, 1, 1);

		debugTextCount = 0;
	}
	protected void beginHud(){
		fontBatch2.begin();
		font2.setColor(Color.RED);
		//font2.setColor(0, 1, 1, 1);

		//hudTextCount = 0;
	}

	protected void renderDebug(String s) {
		Vector3 coords = cam.unproject(new Vector3(10, 10, 0));
		font.draw(fontBatch, s, coords.x, coords.y - debugTextCount++ * 20);
	}
	protected void renderHud(String s, int xCoord){
		//Vector3 coords = cam.unproject(new Vector3(10, 10, 0));
		//if (hudTextCount == 0)
		//	font2.setColor(Color.RED);
		//if (hudTextCount == 1)
		//	font2.setColor(Color.GREEN);

		//hudTextCount++;
		//font2.draw(fontBatch2, s, xCoord, Gdx.graphics.getHeight() - 20);
	}

	protected void endDebug() {
		fontBatch.end();
	}

	protected void endHud(){
		fontBatch2.end();
	}
	
	public abstract void doRender();
}
