package de.eightbitboy.ecorealms.map;

import java.util.ArrayList;
import java.util.List;

public class Map {
	private int sizeX;
	private int sizeY;
	private MapEntity[] entities;
	private List<MapChangeListener> listeners = new ArrayList<MapChangeListener>();

	public Map(int sizeX, int sizeY) {
		this.sizeX = sizeX;
		this.sizeY = sizeY;
		initialize();
	}


	public int getSizeX() {
		return this.sizeX;
	}

	public int getSizeY() {
		return this.sizeY;
	}

	MapEntity[] getEntities() {
		return this.entities;
	}

	private void initialize() {
		entities = new MapEntity[sizeX * sizeY];
	}

	public void put(MapEntity entity) {
		if (!hasValidPosition(entity)) {
			//TODO Rather log this information!
			/*
			throw new InvalidMapAccessException(
					"The entity has an invalid position: " + entity.getPosition());
					*/
		} else {
			insert(entity);
		}
	}

	private void insert(MapEntity entity) {
		Position position = entity.getPosition();
		if (isClear(position)) {
			entities[getIndexForPosition(entity.getPosition())] = entity;
			notifyListeners();
		} else {
			//TODO Rather log this information!
			/*
			throw new InvalidMapAccessException(
					"The position is already occupied: " + entity.getPosition());
					*/
		}
	}

	/**
	 * The y-values are stored next to each other.
	 */
	private int getIndexForPosition(Position position) {
		return ((position.x % sizeX) * sizeY) + position.y;
	}

	public MapEntity get(Position position) {
		return entities[getIndexForPosition(position)];
	}

	public void remove(MapEntity entity) {
		entities[getIndexForPosition(entity.getPosition())] = null;
	}

	private boolean hasValidPosition(MapEntity entity) {
		Position position = entity.getPosition();

		return !(position.x < 0 ||
				position.y < 0 ||
				position.x >= this.sizeX ||
				position.y >= this.sizeY);
	}

	boolean isClear(Position position) {
		return entities[getIndexForPosition(position)] == null;
	}

	public void subscribe(MapChangeListener listener) {
		listeners.add(listener);
	}

	private void notifyListeners() {
		for (MapChangeListener listener : listeners) {
			listener.mapChanged();
		}
	}

	public List<MapEntity> getAllEntities() {
		List<MapEntity> e = new ArrayList<MapEntity>();
		for (MapEntity entity : entities) {
			if (entity != null) {
				e.add(entity);
			}
		}
		return e;
	}
}

@@ -32,16 +32,74 @@
 s.map;%0A%0A
+import org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;%0A%0A
 import j
@@ -161,16 +161,89 @@
 s Map %7B%0A
+%09private final Logger logger = LoggerFactory.getLogger(this.getClass());%0A
 %09private
@@ -807,36 +807,40 @@
 ODO 
-Rather log this information!
+Expect some log output in tests.
 %0A%09%09%09
@@ -1216,41 +1216,391 @@
 %09%09//
-TODO Rather log this information!
+FIXME%0A%09%09%09// https://www.slf4j.org/manual.html%0A%09%09%09// https://stackoverflow.com/questions/1827677/how-to-do-a-junit-assert-on-a-message-in-a-logger%0A%09%09%09// http://projects.lidalia.org.uk/slf4j-test/%0A%09%09%09Logger logger = LoggerFactory.getLogger(this.getClass());%0A%09%09%09logger.debug(%22This map position is already occupied: %22 + entity.getPosition());%0A%0A%0A%09%09%09//TODO Expect some log output in tests.
 %0A%09%09%09

Save progress