package net.mostlyoriginal.game.system.render;

import com.artemis.Aspect;
import com.artemis.ComponentMapper;
import com.artemis.Entity;
import com.artemis.EntitySystem;
import com.artemis.annotations.Wire;
import com.artemis.utils.ImmutableBag;
import net.mostlyoriginal.api.component.basic.Pos;
import net.mostlyoriginal.game.Path;
import net.mostlyoriginal.game.component.Layer;
import net.mostlyoriginal.game.component.Persistable;
import net.mostlyoriginal.game.component.Routable;
import net.mostlyoriginal.game.component.Team;
import net.mostlyoriginal.game.component.buildings.ResourceNode;
import net.mostlyoriginal.game.component.buildings.Techpoint;
import net.mostlyoriginal.game.component.ui.RenderMask;
import net.mostlyoriginal.game.manager.LayerManager;

/**
 * Techpoint Symmetry
 * <p/>
 * Per team, highlight the shortest paths from techpoint to resource towers, and paths up to 5 seconds longer.
 * Marines Highlighted in blue, aliens in red.
 * <p/>
 * Helps determine what techpoints have the most access to RTs for each team, in an unchallenged situation.
 * Since travel speed is asymmetrical the dynamics change depending on the claimed techpoints.
 *
 * @author Daan van Yperen
 */
@Wire
public class TechpointSymmetrySystem extends EntitySystem {

	public static final float MAX_SYMMETRY_DISCREPANCY = 5f;
	protected LayerManager layerManager;

	public boolean dirty = true;
	protected ComponentMapper<Routable> mRoutable;
	protected ComponentMapper<Persistable> mPersistable;
	protected ComponentMapper<Techpoint> mTechpoint;
	protected ComponentMapper<RenderMask> mRenderMask;

	protected RoutePlotSystem routePlotSystem;

	public TechpointSymmetrySystem() {
		super(Aspect.getAspectForAll(Routable.class, Pos.class, ResourceNode.class));
	}

	@Override
	protected void initialize() {
	}

	@Override
	protected void processEntities(ImmutableBag<Entity> entities) {

		if (dirty) {
			dirty = false;


			for (int i = 0, s = entities.size(); i < s; i++) {
				final Entity e = entities.get(i);
				final Routable routable = mRoutable.get(e);

				plotCloseTechpoints(e, routable);
			}
		}
	}

	private void plotCloseTechpoints(Entity e, Routable routable) {

		Layer layerAliens = layerManager.getLayer("TECHPOINTS_ALIENS", RenderMask.Mask.RT_SYMMETRY_ALIEN);
		Layer layerMarines = layerManager.getLayer("TECHPOINTS_MARINES", RenderMask.Mask.RT_SYMMETRY_MARINE);

		// build a list of all paths, sorted by TRAVEL TIME. which can be different based on the team running the path.
		for (Team team : Team.values()) {
			float closest = -1;
			for (Path path : routable.paths.get(team)) {
				Entity destination = path.destination.get();
				if (mTechpoint.has(destination)) {

					int travelTimeInSeconds = path.team.getTravelTimeInSeconds(path);

					if (closest == -1) closest = travelTimeInSeconds;

					// abort when paths are longer than 10% of the closest techpoint.
					if (travelTimeInSeconds > closest + MAX_SYMMETRY_DISCREPANCY)
						break;

					routePlotSystem.renderPath(path,
							path.team == Team.ALIEN ? layerAliens : layerMarines,
							path.team.getPathColor(),
							new RenderMask(path.team == Team.ALIEN ? RenderMask.Mask.RT_SYMMETRY_ALIEN : RenderMask.Mask.RT_SYMMETRY_MARINE), true);
				}
			}
		}
	}
}

@@ -240,16 +240,56 @@
 bleBag;%0A
+import com.badlogic.gdx.graphics.Color;%0A
 import n
@@ -1963,16 +1963,149 @@
 false;%0A%0A
+%09%09%09layerManager.clearWithMap(getAlienLayer(), Color.WHITE, 0.3f);%0A%09%09%09layerManager.clearWithMap(getMarineLayer(), Color.WHITE, 0.3f);%0A
 %0A%09%09%09for 
@@ -2381,188 +2381,63 @@
 s = 
-layerManager.getLayer(%22TECHPOINTS_ALIENS%22, RenderMask.Mask.RT_SYMMETRY_ALIEN);%0A%09%09Layer layerMarines = layerManager.getLayer(%22TECHPOINTS_MARINES%22, RenderMask.Mask.RT_SYMMETRY_MARINE
+getAlienLayer();%0A%09%09Layer layerMarines = getMarineLayer(
 );%0A%0A
@@ -3303,11 +3303,264 @@
 %7D%0A%09%09%7D%0A%09%7D
+%0A%0A%09private Layer getMarineLayer() %7B%0A%09%09return layerManager.getLayer(%22TECHPOINTS_MARINES%22, RenderMask.Mask.RT_SYMMETRY_MARINE);%0A%09%7D%0A%0A%09private Layer getAlienLayer() %7B%0A%09%09return layerManager.getLayer(%22TECHPOINTS_ALIENS%22, RenderMask.Mask.RT_SYMMETRY_ALIEN);%0A%09%7D
 %0A%7D%0A

Add shadow of map behind the remaining symmetry screens.