package main.maps;

import java.util.ArrayList;

import ea.Knoten;
import ea.Ticker;
import main.DoorTile;
import main.Main;
import main.Tile;
import main.entities.Entity;
import main.entities.LivingEntity;
import main.entities.player.Player;

/**
 * Auf der Map sind alle Entities, sowie die Tiles gespiechert.
 */
public abstract class Map extends Knoten implements Ticker {

	protected Tile[][] tiles; // Die Tiles der map in einem 2D Array.
	private ArrayList<Entity> entities;

	public DoorTile topDoor;
	public DoorTile leftDoor;
	public DoorTile rightDoor;
	public DoorTile bottomDoor;

	public Map(int width, int height) {
		tiles = new Tile[width][height];

		entities = new ArrayList<>(100);

		Main.instance.manager.anmelden(this, 20);
	}

	/**
	 * Gibt das Tile-Objekt an der gegebenen Koordinate zurück. (nur wenn es
	 * existiert)
	 */
	public Tile getTile(int x, int y) {
		if (x >= 0 && x < tiles.length && y >= 0 && y < tiles[0].length) {
			return tiles[x][y];
		}
		return null;
	}

	@Override
	public void tick() {
		for (int i = 0; i < entities.size(); i++) {
			Entity e = entities.get(i);
			if (e.isReadyToDelete()) {
				if (e instanceof LivingEntity) {
					entfernen(((LivingEntity) e).actionFigur);
				}
				Main.instance.manager.abmelden(e);
				entities.remove(e);
			}
		}
	}

	public int getWidth() {
		return tiles.length;
	}

	public int getHeight() {
		return tiles[0].length;
	}

	public ArrayList<Entity> getEntities() {
		return entities;
	}

	public void addLivingEntity(LivingEntity e) {
		entities.add(e);
		add(e.actionFigur);
	}

	public abstract Map clone();

	public void cloneTiles(Map map) {
		for (int x = 0; x < map.getWidth(); x++) {
			for (int y = 0; y < map.getHeight(); y++) {
				tiles[x][y] = map.getTile(x, y).clone();
				if (tiles[x][y] instanceof DoorTile) {
					DoorTile dt = (DoorTile) tiles[x][y];
					if (dt.getSide() == DoorTile.TOP) {
						topDoor = dt;
						topDoor.setMap(this);
					}
					if (dt.getSide() == DoorTile.BOTTOM) {
						bottomDoor = dt;
						bottomDoor.setMap(this);
					}
					if (dt.getSide() == DoorTile.LEFT) {
						leftDoor = dt;
						leftDoor.setMap(this);
					}
					if (dt.getSide() == DoorTile.RIGHT) {
						rightDoor = dt;
						rightDoor.setMap(this);
					}
				}
				add(tiles[x][y]);
			}
		}
	}

	public void start() {
		if (topDoor != null) {
			Main.instance.manager.anmelden(topDoor, 50);
		}
		if (bottomDoor != null) {
			Main.instance.manager.anmelden(bottomDoor, 50);
		}
		if (leftDoor != null) {
			Main.instance.manager.anmelden(leftDoor, 50);
		}
		if (rightDoor != null) {
			Main.instance.manager.anmelden(rightDoor, 50);
		}
		for (Entity e : entities) {
			if (!(e instanceof Player)) {
				Main.instance.manager.anmelden(e, 20);
			}
		}
	}

	public void stop() {
		if (topDoor != null) {
			Main.instance.manager.abmelden(topDoor);
		}
		if (bottomDoor != null) {
			Main.instance.manager.abmelden(bottomDoor);
		}
		if (leftDoor != null) {
			Main.instance.manager.abmelden(leftDoor);
		}
		if (rightDoor != null) {
			Main.instance.manager.abmelden(rightDoor);
		}
		for (Entity e : entities) {
			if (!(e instanceof Player)) {
				Main.instance.manager.abmelden(e);
			}
		}
	}

	public void connectDoors(DoorTile door, DoorTile door2) {
		door.setConnectedDoor(door2);
		door2.setConnectedDoor(door);
	}
}
