package org.nusco.narjillos.application.utilities;

import org.nusco.narjillos.core.geometry.Vector;
import org.nusco.narjillos.core.things.Thing;
import org.nusco.narjillos.creature.Egg;
import org.nusco.narjillos.creature.Narjillo;
import org.nusco.narjillos.experiment.environment.FoodPellet;

public class ThingTracker {

	private static final long DEMO_MODE_FOCUS_TIME_IN_SECONDS = 12;

	private static final long DEMO_MODE_ZOOM_TIME_IN_SECONDS = 3;

	private final Viewport viewport;

	private final Locator locator;

	private Thing target;

	private boolean demoMode;

	private long lastDemoTrackingTime;

	public ThingTracker(Viewport viewport, Locator locator) {
		this.viewport = viewport;
		this.locator = locator;
	}

	public synchronized void tick() {
		if (!isTracking())
			return;

		viewport.centerOn(target);

		if (isDemoMode()) {
			if (hasBeenDemoTrackingFor(DEMO_MODE_FOCUS_TIME_IN_SECONDS + DEMO_MODE_ZOOM_TIME_IN_SECONDS))
				startTrackingRandomLivingThing();
			else if (hasBeenDemoTrackingFor(DEMO_MODE_FOCUS_TIME_IN_SECONDS))
				viewport.zoomOut();
		}

		if (target.getLabel().equals(Narjillo.LABEL)) {
			Narjillo narjillo = (Narjillo) target;
			if (narjillo.isDead()) {
				if (isDemoMode())
					startTrackingRandomLivingThing();
				else {
					Thing nextClosestNarjillo = locator.findNarjilloAt(narjillo.getPosition());
					startTracking(nextClosestNarjillo);
				}
			}
		}

		if (target.getLabel().equals(Egg.LABEL) || target.getLabel().equals(FoodPellet.LABEL)) {
			if (target.getInteractor() != Thing.NULL)
				startTracking(target.getInteractor());
		}
	}

	public synchronized void stopTracking() {
		target = null;
		demoMode = false;
	}

	public void toggleDemoMode() {
		demoMode = !demoMode;
		if (!isDemoMode())
			return;
		viewport.zoomToMaxLevel();
		startTrackingRandomLivingThing();
	}

	public String getStatus() {
		if (isDemoMode())
			return "demo";
		if (isTracking())
			return "following";
		return "freeroaming";
	}

	private synchronized boolean isTracking() {
		return target != null && target != Thing.NULL;
	}

	private boolean hasBeenDemoTrackingFor(long seconds) {
		long secondsSinceLastDemoTracking = (System.currentTimeMillis() - lastDemoTrackingTime) / 1000;
		return secondsSinceLastDemoTracking > seconds;
	}

	public void startTrackingThingAt(Vector position) {
		startTracking(locator.findThingAt(position));
	}

	public void startTracking(Thing target) {
		if (target == null || target == Thing.NULL) {
			stopTracking();
			return;
		}

		this.target = target;
		viewport.centerAndZoomOn(target);
	}

	private void startTrackingRandomLivingThing() {
		Thing target = locator.findRandomLivingThing();
		startTracking(target);
		lastDemoTrackingTime = System.currentTimeMillis();
	}

	private boolean isDemoMode() {
		return demoMode;
	}
}

@@ -791,16 +791,49 @@
 eturn;%0A%0A
+%09%09Thing currentTarget = target;%0A%0A
 %09%09viewpo
@@ -844,17 +844,24 @@
 enterOn(
-t
+currentT
 arget);%0A
@@ -1114,33 +1114,40 @@
 t();%0A%09%09%7D%0A%0A%09%09if (
-t
+currentT
 arget.getLabel()
@@ -1207,17 +1207,24 @@
 rjillo) 
-t
+currentT
 arget;%0A%09
@@ -1462,25 +1462,32 @@
 %0A%09%09%7D%0A%0A%09%09if (
-t
+currentT
 arget.getLab
@@ -1508,25 +1508,32 @@
 g.LABEL) %7C%7C 
-t
+currentT
 arget.getLab
@@ -1568,25 +1568,32 @@
 )) %7B%0A%09%09%09if (
-t
+currentT
 arget.getInt
@@ -1631,25 +1631,32 @@
 artTracking(
-t
+currentT
 arget.getInt
@@ -2460,32 +2460,32 @@
 tion));%0A%09%7D%0A%0A
-
 %09public 
 void startTr
@@ -2464,32 +2464,45 @@
 ));%0A%09%7D%0A%0A%09public 
+synchronized 
 void startTracki

Fix bug with tracker when tracked narjillo dies