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 (!isFollowing())
			return;

		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)) {
			startTracking(target.getInteractor());
		}

		viewport.centerOn(target);
	}

	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 (isFollowing())
			return "following";
		return "freeroaming";
	}

	private synchronized boolean isFollowing() {
		return target != 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;
	}
}

@@ -767,22 +767,21 @@
 %09if (!is
-Follow
+Track
 ing())%0A%09
@@ -791,16 +791,46 @@
 eturn;%0A%0A
+%09%09viewport.centerOn(target);%0A%0A
 %09%09if (is
@@ -1500,29 +1500,19 @@
 )) %7B%0A%09%09%09
-startTracking
+if 
 (target.
@@ -1530,44 +1530,70 @@
 or()
-);%0A%09%09%7D%0A%0A%09%09viewport.centerOn(target);
+ != Thing.NULL)%0A%09%09%09%09startTracking(target.getInteractor());%0A%09%09%7D
 %0A%09%7D%0A
@@ -1909,22 +1909,21 @@
 %09%09if (is
-Follow
+Track
 ing())%0A%09
@@ -2008,14 +2008,13 @@
 n is
-Follow
+Track
 ing(
@@ -2040,16 +2040,40 @@
  != null
+ && target != Thing.NULL
 ;%0A%09%7D%0A%0A%09p

Fix tracking bug