package ei.game.scene;

import ei.engine.math.Vector2f;
import ei.engine.math.Vector2i;
import ei.engine.math.Vector3f;
import ei.engine.scene.Node;
import ei.engine.scene.Sprite;

public class Map {
	private static final int POS_SIZE = 50;
	private int width;
	private int hight;
	private GameEntity[][] map;
	private Node mapNode;
	
	public Map(int w, int h){
		this.width = w;
		this.hight = h;
		init();
	}
		
	private void init(){
		map = new GameEntity[width][hight];
		
		// init textures
		mapNode = new Node("MapNode");
		for(int i=0; i<width ;i++){
			for(int j=0; j<hight ;j++){
				Sprite s = new Sprite("MapPos("+i+","+j+")","data/map/sand.jpg");
				s.setLocation(new Vector3f(i*POS_SIZE,j*POS_SIZE,0));
				s.setSize(new Vector2f(POS_SIZE,POS_SIZE));
				mapNode.add(s);
			}
		}
	}
	
	/**
	 * Returns the size of the map
	 * 
	 * @return The size of the map
	 */
	public Vector2i getSize(){
		return new Vector2i(width,hight);
	}
	
	/**
	 * Returns the pos of the map by the pixel
	 * @param x x pixels
	 * @param y y pixels
	 * @return The pos thats in the coordinates
	 */
	public static Vector2i getPosByPixel(float x, float y){
		x = x/POS_SIZE;
		y = y/POS_SIZE;
		return new Vector2i((int)x, (int)y);
	}
	
	/**
	 * The coordinate of the map pos
	 * @param x x pos
	 * @param y y pos
	 * @return The coordinate of the pos
	 */
	public static Vector2f getPixelByPos(int x, int y){
		float xf = (POS_SIZE*x);
		float yf = (POS_SIZE*y);
		return new Vector2f(xf,yf);
	}
	
	/**
	 * Returns if the pos inthe map is empty
	 * 
	 * @param x The x pos
	 * @param y The y pos
	 * @return True if empty else false
	 */
	public boolean isPosEmpty(int x, int y){
		if(posExist(x,y) && map[x][y] == null){
			return true;
		}
		return false;
	}
	
	/**
	 * Returns true if the given pos exists on the map
	 * @param x The x pos
	 * @param y The y pos
	 * @return True if the given pos exists on the map
	 */
	public boolean posExist(int x, int y){
		if(x < 0 || y < 0 || x >= width || y >= hight)
			return false;
		return true;
	}
	
	/**
	 * Returns the object at the pos
	 * 
	 * @param x The x pos
	 * @param y The y pos
	 * @return The object in that pos
	 */
	public GameEntity getPos(int x, int y){
		return map[x][y];
	}
	
	/**
	 * Sets an object at the pos
	 * 
	 * @param e The object
	 * @param x The x pos
	 * @param y The y pos
	 */
	public void setPos(GameEntity e, int x, int y){
		map[x][y] = e;
	}
	
	/**
	 * Removes a object from that pos
	 * 
	 * @param x The x pos
	 * @param y The y pos
	 */
	public void removePos(int x, int y){
		map[x][y] = null;
	}
	
	/**
	 * Returns the map node
	 * 
	 * @return The map node
	 */
	public Node getMapNode(){
		return mapNode;
	}
	
	public Vector2i getPosIndex(GameEntity u){
		for(int i=0; i<width ;i++){
			for(int j=0; j<hight ;j++){
				if(map[i][j] == u){
					return new Vector2i(i,j);
				}
			}
		}
		return null;
	}
	
	/**
	 * Prints all the units on the map
	 *
	 */
	public void printAllUnits(){
		for(int i=0; i<width ;i++){
			for(int j=0; j<hight ;j++){
				if(map[i][j] != null){
					System.out.println("Unit("+map[i][j].getNode().getName()+"): "+i+" "+j);
				}
			}
		}
	}
}
