package levelGen;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Rectangle;
import com.ld50.game.HF;

import Global.Global;

public class NewTile extends Sprite {
	public enum State {
		DEEPESTWATER, DEEPWATER, WATER, SAND, GRASS, ROCK, DARKROCK, SNOW, LAVA
	};

	public State currentState;
	public State previousState;
	// private Animation<TextureRegion> main; this is for animated ones
	// private float _animBreakingTimer;
	private TextureAtlas atlasTile;
	private TextureRegion t;
	private TextureRegion bt;
	private TextureRegion c;
	// private boolean isMain = true;// is the animation set to main
	public float speed;
	public Rectangle rect;
	private int _sw;// sprite width
	private int _sh;// sprite height
	// sfx
	private float r;
	private float g;
	private float b;
	private float fadeTimer = MathUtils.random(.7f, 1f);
	private boolean dark;
	private float fadeRate = MathUtils.random(.0015f, .003f);
	// private boolean isDiagSpeed;
	public float normalSpeed;
	public float diagSpeed;
	public float sprintSpeed;
	private String _k;
	private Integer _o;
	private float toDarkTimer = 1f;
	private boolean positive;
	private float alpha = 0;
	private float aTimer;
	private boolean isA;

	public NewTile(float _x, float _y) {
		rect = new Rectangle();
		// these help to tell the tiles where to start, assemble directly around the player. We'll use a hashmap to grab the correct textures. i think.
		rect.x = (int) _x + (int) Global.P.x - (HF.TW * 17);// HF.MW + 928;
		rect.y = (int) _y + (int) Global.P.y - (HF.TH * 4);// 26
		rect.width = 64;
		rect.height = 64;

		_sw = 64;
		_sh = 64;
		// this is for the animations
		currentState = State.WATER;
		previousState = State.WATER;
		// _animBreakingTimer = 0f;//for animations
		speed = 3f;
		normalSpeed = speed;// how fast the goes//not sure here.
		diagSpeed = speed / 2;

		// get Tile atlas
		atlasTile = new TextureAtlas(Gdx.files.internal("tiles.txt"));
		// still frames
		t = new TextureRegion(atlasTile.findRegion("tile_spritesheet"), (0 * _sw), 0, _sw, _sh);
		bt = new TextureRegion(atlasTile.findRegion("tile_spritesheet"), (1 * _sw), 0, _sw, _sh);
		c = new TextureRegion(atlasTile.findRegion("tile_spritesheet"), (2 * _sw), 0, _sw, _sh);
		// animated frames
		/*
		 * Array<TextureRegion> frames = new Array<TextureRegion>(); frames.add(new TextureRegion(atlasTile.findRegion("tile_spritesheet"), (0 * _sw), (0 *
		 * _sh), _sw, _sh)); frames.add(new TextureRegion(atlasTile.findRegion("tile_spritesheet"), (1 * _sw), (0 * _sh), _sw, _sh)); frames.add(new
		 * TextureRegion(atlasTile.findRegion("tile_spritesheet"), (2 * _sw), (0 * _sh), _sw, _sh)); frames.add(new
		 * TextureRegion(atlasTile.findRegion("tile_spritesheet"), (1 * _sw), (0 * _sh), _sw, _sh)); main = new Animation<TextureRegion>(.05f, frames,
		 * PlayMode.LOOP);// was .06f frames.clear();
		 */// definitely starts right. then we say, when the line is one length + one _sw worth which would be what in actual numbers?
			// these two are specifically sprite settings to set the sprite's initial bounds and region
			// assign random color
		setBounds(0, 0, _sw, _sh);
		setOriginCenter();
		// set the correct region based on WHERE IT IS on the map. This will be updateable on the map...
		_k = ("" + Math.abs((int) rect.x / HF.TW) + "," + Math.abs((int) rect.y / HF.TH));// this should work if the tiles are reduced by
		// System.out.println("k: " + _k); // the tilesize as
		// coords. i think.
		_o = Level.Map.get(_k);
		// System.out.println("o: " + _o);
		// THESE DO NOT RENDER THEMSELVES PLEEEEEASE DO NOT UPDATE THESE THINKING THEY WILL CHANGE THE COLOR OF THE TILEESSSSSS
		// THESE DO NOT RENDER THEMSELVES PLEEEEEASE DO NOT UPDATE THESE THINKING THEY WILL CHANGE THE COLOR OF THE TILEESSSSSS
		// THESE DO NOT RENDER THEMSELVES PLEEEEEASE DO NOT UPDATE THESE THINKING THEY WILL CHANGE THE COLOR OF THE TILEESSSSSS
		// THESE DO NOT RENDER THEMSELVES PLEEEEEASE DO NOT UPDATE THESE THINKING THEY WILL CHANGE THE COLOR OF THE TILEESSSSSS
		// THESE DO NOT RENDER THEMSELVES PLEEEEEASE DO NOT UPDATE THESE THINKING THEY WILL CHANGE THE COLOR OF THE TILEESSSSSS
		// THESE DO NOT RENDER THEMSELVES PLEEEEEASE DO NOT UPDATE THESE THINKING THEY WILL CHANGE THE COLOR OF THE TILEESSSSSS
		if (_o == null) {// set texture, not color here. i think... but it's just initial. the states below update constantly. ;-)
			setRegion(t);
		} else if (_o == 2) {
			setRegion(bt);
		} else if (_o == 0 || _o == 3 || _o == 4) {
			setRegion(c);
		} else {
			setRegion(t);
		}
	}

	// for all the animations: //this isn't even updated unless i call it from the other screen oh bother. *facepalm*
	public void Update(OrthographicCamera camera) {
		handleInput(camera);
	}

	// for all the animations: //this isn't even updated unless i call it from the other screen oh bother. *facepalm*
	public TextureRegion getFrame(OrthographicCamera camera) {
		Update(camera);
		if (toDarkTimer <= .8f)
			positive = true;
		if (toDarkTimer > 1f)
			positive = false;
		if (positive)
			toDarkTimer += .001f;
		else
			toDarkTimer -= .001f;
		if (aTimer <= .1f)
			isA = true;
		if (aTimer > 1f)
			isA = false;
		if (isA)
			aTimer += .0005f;
		else
			aTimer -= .0005f;

		currentState = getState();

		TextureRegion region;
		switch (currentState) {
		case WATER:
			region = c;
			break;
		case DEEPWATER:
			region = c;
			break;
		case DEEPESTWATER:
			region = c;
			break;
		case ROCK:
			region = bt;
			break;
		default:
			region = t;
			break;
		}
		/*
		 * if (isMain) _animBreakingTimer += dt; else _animBreakingTimer = 0;
		 */

		return region;
	}

	public State getState() {
		_k = ("" + Math.abs((int) rect.x / HF.TW) + "," + Math.abs((int) rect.y / HF.TH));
		_o = Level.Map.get(_k);
		if (_o == null) {// this is out of bounds. heheh
			r = MathUtils.random(toDarkTimer, 1f);
			g = MathUtils.random(toDarkTimer, 1f);
			b = MathUtils.random(toDarkTimer, 1f);
			alpha = aTimer;
			return State.LAVA;
		} else if (_o == 0) {
			r = .5f;
			g = .5f;
			b = 1f;
			return State.WATER;
		} else if (_o == 1) {
			r = .8f;
			g = .8f;
			b = .8f;
			return State.ROCK;
		} else if (_o == 2) {
			r = .4f;
			g = .6f;
			b = .4f;
			return State.GRASS;
		} else if (_o == 3) {
			r = .6f;
			g = .6f;
			b = .6f;
			return State.DEEPWATER;
		} else if (_o == 4) {
			r = .4f;
			g = .4f;
			b = .7f;
			return State.DEEPESTWATER;
		} else if (_o == 5) {
			r = .4f;
			g = .4f;
			b = .4f;
			return State.DARKROCK;
		} else if (_o == 6) {
			r = .5f;
			g = .5f;
			b = .5f;
			return State.SNOW;
		} else if (_o == 7) {
			r = .6f;
			g = .6f;
			b = .4f;
			return State.SAND;
		} else if (_o == 8) {
			r = .5f;
			g = 0;
			b = 0;
			return State.LAVA;
		} else {
			r = 1;
			g = 0;
			b = 0;
			return State.LAVA;
		}
	}

	// so, the moving the tiles individually with the movement isn't going to work so far as i can tell becaues of the desire for variance of speed.
	// but, i'd like to try the camera as a border and as the camera moves over the edge or as the tiles move across the edge of the camera, they move
	// or draw new textures based on where they are pulled or drawn from. they all will have coordinates, or a lookup table as to what they are. I'm
	// not totally versed in it, but I do want to try. What ineed though is a base renderer that will render my tiles in a perfect continous loop just
	// being able to handle the default tiles. I think I will do some math and try to get this right.
	// what size should the tiles be. They are 64x64. what width should I start with.
	private void handleInput(OrthographicCamera camera) {
		// input controls
		int _os = HF.TW;// one tile size (offset)//clamp does nothing here i was just seeing what it does.
		int w = HF.MW / 2 + HF.TW + _os;
		int h = HF.MH / 2 + HF.TH + _os;

		int leftEdge = (int) camera.position.x - w;// seems to be accurate.
		int rightEdge = (int) camera.position.x + w;// leftEdge + _w;// still off for some reason.
		int topEdge = (int) camera.position.y + h;// 720 - 400 = 320. 720/2 = 360. hmmm
		int bottomEdge = (int) camera.position.y - h;// why are they both using this offset?? i'm so confused. I didn't even think about this.??
		if (rect.x < leftEdge)// if you are left of the map + a tile segment move to the right side of the tiles
			rect.x += HF.LW * HF.TW;
		if (rect.x > rightEdge - _os)
			rect.x -= HF.LW * HF.TW;// now it's moving based on the rect.x location.
		if (rect.y < bottomEdge)
			rect.y += HF.LH * HF.TH;
		if (rect.y > topEdge - _os)
			rect.y -= HF.LH * HF.TH;
	}

	public void RenderNewTile(HF game, OrthographicCamera camera) {// hmmm i think it just needs placed before? it gets here.
		if (_o == null || _o <= 0)
			fadeTimer = 1f;
		else {
			if (fadeTimer <= .7f)// this will be really good for water and lava tiles.
				dark = true;
			else if (fadeTimer >= 1f)
				dark = false;
			if (dark)
				fadeTimer += fadeRate;
			else
				fadeTimer -= fadeRate;
		}
		// System.out.println("alpha: " + alpha);
		if (_o == null)
			game.batch.setColor(r, g, b, alpha);
		else
			game.batch.setColor(r, g, b, fadeTimer);
		game.batch.draw(getFrame(camera), rect.x, rect.y);
	}
}
