package de.tud.kom.p2psim.impl.topology.movement.modularosm.transition;

import de.tud.kom.p2psim.api.topology.movement.SimLocationActuator;
import de.tudarmstadt.maki.simonstrator.api.component.sensor.location.IAttractionPoint;

import java.util.*;

/**
 * This {@link IAttractionAssigmentStrategy} works with manual assignments. Initially components will be assigned
 * one of the attraction points, but at any further point, the set list of attraction points doesn't really matter.
 * New target can be assigned by using the {@link #updateTargetAttractionPoint(SimLocationActuator, IAttractionPoint)} method,
 * otherwise the components will stop moving upon reaching their target.
 *
 * @author Clemens Krug
 */
public class ManualAssignmentStrategy extends AbstractAttractionBasedAssignmentStrategy
{
    public ManualAssignmentStrategy() {
		super(0, 0);
	}

	private LinkedHashSet<IAttractionPoint> aPoints = new LinkedHashSet<>();

    private Map<SimLocationActuator, IAttractionPoint> assignments = new HashMap<>();

    private List<AttractionAssignmentListener> listeners = new LinkedList<>();

    public void setAttractionPoints(Collection<IAttractionPoint> attractionPoints) {
        aPoints.addAll(attractionPoints);
    }

    @Override
    public void addComponent(SimLocationActuator ms) {
        if(!assignments.containsKey(ms))
        {
            IAttractionPoint aPoint = aPoints.iterator().next();
            assignments.put(ms, aPoint);
        }
        listeners.forEach(listener -> listener.updatedAttractionAssignment(ms, assignments.get(ms)));
    }

    @Override
    public void reachedAttractionPoint(SimLocationActuator ms, IAttractionPoint attractionPoint) {
        //Nothing to do.
    }

    @Override
    public void updateTargetAttractionPoint(SimLocationActuator comp, IAttractionPoint attractionPoint) {
        assignments.put(comp, attractionPoint);
        listeners.forEach(listener -> listener.updatedAttractionAssignment(comp, attractionPoint));
    }
	
}
