content: /*
   * Copyright 2010 Aalto University, ComNet
   * Released under GPLv3. See LICENSE.txt for details.
   */
  package movement;
  
  import java.util.HashMap;
  import java.util.List;
  import java.util.Random;
  
  import core.Coord;
  import core.DTNSim;
  
  /**
   * This class controls the group mobility of the people meeting their friends in
   * the evening
   *
   * @author Frans Ekman
   */
  public class EveningActivityControlSystem {
  
  	private HashMap<Integer, EveningActivityMovement> eveningActivityNodes;
  	private List<Coord> meetingSpots;
  	private EveningTrip[] nextTrips;
  
  	private Random rng;
  
  	private static HashMap<Integer, EveningActivityControlSystem>
  		controlSystems;
  
  	static {
  		DTNSim.registerForReset(EveningActivityControlSystem.class.
  				getCanonicalName());
  		reset();
  	}
  
  	/**
  	 * Creates a new instance of EveningActivityControlSystem without any nodes
  	 * or meeting spots, with the ID given as parameter
  	 * @param id
  	 */
  	private EveningActivityControlSystem(int id) {
  		eveningActivityNodes = new HashMap<Integer, EveningActivityMovement>();
  	}
  
  	public static void reset() {
  		controlSystems = new HashMap<Integer, EveningActivityControlSystem>();
  	}
  
  	/**
  	 * Register a evening activity node with the system
  	 * @param eveningMovement activity movement
  	 */
  	public void addEveningActivityNode(EveningActivityMovement eveningMovement) {
  		eveningActivityNodes.put(new Integer(eveningMovement.getID()),
  				eveningMovement);
  	}
  
  	/**
  	 * Sets the meeting locations the nodes can choose among
  	 * @param meetingSpots
  	 */
  	public void setMeetingSpots(List<Coord> meetingSpots) {
  		this.meetingSpots = meetingSpots;
  		this.nextTrips = new EveningTrip[meetingSpots.size()];
  	}
  
  	/**
  	 * This method gets the instruction for a node, i.e. When/where and with
  	 * whom to go.
  	 * @param eveningActivityNodeID unique ID of the node
  	 * @return Instructions object
  	 */
  	public EveningTrip getEveningInstructions(int eveningActivityNodeID) {
  		EveningActivityMovement eveningMovement = eveningActivityNodes.get(
  				new Integer(eveningActivityNodeID));
  		if (eveningMovement != null) {
  			int index = eveningActivityNodeID % meetingSpots.size();
  			if (nextTrips[index] == null) {
  				int nrOfEveningMovementNodes = (int)(eveningMovement.
  						getMinGroupSize() +
  						(double)(eveningMovement.getMaxGroupSize() -
  								eveningMovement.getMinGroupSize()) *
  								rng.nextDouble());
  				Coord loc = meetingSpots.get(index).clone();
  				nextTrips[index] = new EveningTrip(nrOfEveningMovementNodes,
  						loc);
  			}
  			nextTrips[index].addNode(eveningMovement);
  			if (nextTrips[index].isFull()) {
  				EveningTrip temp = nextTrips[index];
  				nextTrips[index] = null;
  				return temp;
  			} else {
  				return nextTrips[index];
  			}
  		}
  		return null;
  	}
  
  	/**
  	 * Get the meeting spot for the node
  	 * @param id
  	 * @return Coordinates of the spot
  	 */
  	public Coord getMeetingSpotForID(int id) {
  		int index = id % meetingSpots.size();
  		Coord loc = meetingSpots.get(index).clone();
  		return loc;
  	}
  
  
  	/**
  	 * Sets the random number generator to be used
  	 * @param rand
  	 */
  	public void setRandomNumberGenerator(Random rand) {
  		this.rng = rand;
  	}
  
  	/**
  	 * Returns a reference to a EveningActivityControlSystem with ID provided as
  	 * parameter. If a system does not already exist with the requested ID, a
  	 * new one is created.
  	 * @param id unique ID of the EveningActivityControlSystem
  	 * @return The EveningActivityControlSystem with the provided ID
  	 */
  	public static EveningActivityControlSystem getEveningActivityControlSystem(
  			int id) {
  		if (controlSystems.containsKey(new Integer(id))) {
  			return controlSystems.get(new Integer(id));
  		} else {
  			EveningActivityControlSystem scs =
  				new EveningActivityControlSystem(id);
  			controlSystems.put(new Integer(id), scs);
  			return scs;
  		}
  	}
  
  }
  