package de.fe1k.game9.systems;

import de.fe1k.game9.entities.Entity;
import de.fe1k.game9.events.Event;
import de.fe1k.game9.events.EventEntityDestroyed;
import de.fe1k.game9.events.EventEntityMoved;
import de.fe1k.game9.events.EventEntitySpawned;
import de.fe1k.game9.utils.Vector2i;
import de.nerogar.noise.util.Vector2f;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SystemEntityLookup implements GameSystem {
	private Map<Vector2i, List<Entity>> entityLookup = new HashMap<>();

	@Override
	public void start() {
		Event.register(EventEntityMoved.class, this::entityMoved);
		Event.register(EventEntitySpawned.class, this::entitySpawned);
		Event.register(EventEntityDestroyed.class, this::entityDestroyed);
		Entity.getAll().forEach(this::addEntity);
	}

	private void addEntity(Entity entity) {
		Vector2i pos = vector2fTo2i(entity.getPosition());
		if (!entityLookup.containsKey(pos)) {
			entityLookup.put(pos, new ArrayList<>());
		}
		entityLookup.get(pos).add(entity);
	}

	private void removeEntity(Entity entity) {
		removeEntity(entity, vector2fTo2i(entity.getPosition()));
	}

	private void removeEntity(Entity entity, Vector2i position) {
		if (entityLookup.containsKey(position)) {
			entityLookup.get(position).remove(entity);
		}
	}

	private Vector2i vector2fTo2i(Vector2f v) {
		return new Vector2i((int) Math.floor(v.getX()), (int) Math.floor(v.getY()));
	}

	private void entityMoved(EventEntityMoved event) {
		Vector2i oldPos = vector2fTo2i(event.from);
		removeEntity(event.entity, oldPos);
		addEntity(event.entity);
	}

	private void entitySpawned(EventEntitySpawned event) {
		addEntity(event.entity);
	}

	private void entityDestroyed(EventEntityDestroyed event) {
		removeEntity(event.entity);
	}

	public List<Entity> getAt(Vector2i pos) {
		List<Entity> result = entityLookup.get(pos);
		if (result == null) {
			return new ArrayList<>();
		}
		return result;
	}

	public List<Entity> getAt(int x, int y) {
		return getAt(new Vector2i(x, y));
	}

	@Override
	public void stop() {
		Event.unregister(EventEntityMoved.class, this::entityMoved);
		Event.unregister(EventEntitySpawned.class, this::entitySpawned);
		Event.unregister(EventEntityDestroyed.class, this::entityDestroyed);
	}
}

@@ -804,23 +804,71 @@
 ach(
-this::addEntity
+entity -%3E addEntity(entity, vector2fTo2i(entity.getPosition()))
 );%0A%09
@@ -907,22 +907,18 @@
 y entity
-) %7B%0A%09%09
+, 
 Vector2i
@@ -925,46 +925,16 @@
  pos
- = vector2fTo2i(entity.getPos
 ition
-());
+) %7B
 %0A%09%09i
@@ -965,16 +965,21 @@
 sKey(pos
+ition
 )) %7B%0A%09%09%09
@@ -998,16 +998,21 @@
 .put(pos
+ition
 , new Ar
@@ -1051,16 +1051,21 @@
 .get(pos
+ition
 ).add(en
@@ -1530,25 +1530,34 @@
 %7B%0A%09%09
-Vector2i oldPos =
+removeEntity(event.entity,
  vec
@@ -1581,18 +1581,16 @@
 rom)
+)
 ;%0A%09%09
-remove
+add
 Enti
@@ -1610,41 +1610,30 @@
 ty, 
-oldPos);%0A%09%09addEntity
+vector2fTo2i
 (event.
-entity
+to)
 );%0A%09
@@ -1707,32 +1707,74 @@
 ity(event.entity
+, vector2fTo2i(event.entity.getPosition())
 );%0A%09%7D%0A%0A%09private 

Fix SystemEntityLookup to use the event's to-location