package net.alcuria.umbracraft.engine.map;

import net.alcuria.umbracraft.Config;
import net.alcuria.umbracraft.Game;
import net.alcuria.umbracraft.definitions.tileset.TilesetDefinition;
import net.alcuria.umbracraft.util.O;

import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectMap;

/** Manages all of the game's tile texture regions needed to render a map, both
 * standard and auto-tiled.
 * @author Andrew Keturi */
public class TileView {

	private static final int[] xOffsets = { 0, 1, 0, 1 };
	private static final int[] yOffsets = { 1, 1, 0, 0, };
	private final ObjectMap<Integer, Array<TextureRegion>> autoTiles;
	private final Array<TextureRegion> tiles;

	public TileView(String filename, TilesetDefinition definition) {

		// ensure we have everything we need
		O.notNull(filename);
		O.notNull(definition);
		// add regular tile textures
		tiles = new Array<TextureRegion>();
		final Texture texture = Game.assets().get("tiles/" + filename + ".png", Texture.class); //FIXME: hardcoded, bad andrew !!
		for (int i = 0; i < Math.pow(Config.tilesetWidth / Config.tileWidth, 2); i++) {
			final int x = (i * Config.tileWidth) % Config.tilesetWidth;
			final int y = (i / Config.tileWidth) * Config.tileWidth;
			final int w = Config.tileWidth;
			tiles.add(new TextureRegion(texture, x, y, w, w));
		}

		// create autotile object map, mapping a texture id from the editor to an array of its regions
		autoTiles = new ObjectMap<Integer, Array<TextureRegion>>();
		final int[] terrainIds = { definition.terrain1, definition.terrain2, definition.terrain3, definition.terrain4, definition.overlay };

		// for each of the terrain types we have, if it's valid, add it to the map
		for (int j = 0; j < terrainIds.length; j++) {
			if (terrainIds[j] > 0) {

				// we have a valid terrain id, let's get it's absolute pixel coordinates on the tileset image
				Game.debug("Valid terrain: " + terrainIds[j]);
				final int absX = (terrainIds[j] * Config.tileWidth) % Config.tilesetWidth;
				final int absY = (terrainIds[j] / Config.tileWidth) * Config.tileWidth;
				Game.debug(String.format("got abs x=%d y=%d", absX, absY));

				// now, let's get a series zero-based local x and y coordinates for the autotiles
				Array<TextureRegion> regions = new Array<TextureRegion>();
				for (int i = 0; i < 48; i++) {
					final int locX = (i % 6) * Config.tileWidth / 2;
					final int locY = (i / 6) * Config.tileWidth / 2;

					// we can add each of these to the absolute pixel coordinates and get the location of the autotile region on the tileset
					Game.debug(String.format("Adding texture region at x=%d y=%d", absX + locX, absX + locY));
					regions.add(new TextureRegion(texture, absX + locX, absY + locY, Config.tileWidth / 2, Config.tileWidth / 2));
				}

				// lastly, add the newly-created array of autotile texture regions to our autotile object map
				autoTiles.put(terrainIds[j], regions);
			}
		}

	}

	public void draw(AutoTileAttributes attributes, int x, int y) {
		final int type = attributes.getType();
		final int w = Config.tileWidth / 2;
		if (autoTiles.containsKey(type)) {
			Array<TextureRegion> autoTileRegions = autoTiles.get(type);

			// for each corner (top left, top right, bot left, bot right, we want to draw the autotile
			for (int idx = 0; idx < xOffsets.length; idx++) {
				int corner = attributes.getCorner(idx);
				Game.batch().draw(autoTileRegions.get(corner), x + xOffsets[idx] * w, y + yOffsets[idx] * w, w, w);
			}
		} else {
			Game.batch().draw(get(type), x, y, w, w);
		}
	}

	public TextureRegion get(int id) {
		return tiles.get(id);
	}

}

@@ -499,16 +499,77 @@
 o-tiled.
+ Only one instance of this class is needed per map%0A * object.
 %0A * @aut
@@ -3089,24 +3089,201 @@
 %09%7D%0A%09%09%7D%0A%0A%09%7D%0A%0A
+%09/** Draws either the autotile or regular tile at this coordinate%0A%09 * @param attributes tile attributes for this location%0A%09 * @param x x coordinate%0A%09 * @param y y coordinate */%0A
 %09public void

Add some documentation