package srsim.controller;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import srsim.actuators.MusicActuator;
import srsim.domain.AbstractController;
import srsim.domain.IActuator;
import srsim.domain.ISensor;
import srsim.simulator.SimulationConfigurationException;
import srsim.simulator.SimulationContextException;
/**
* Simple music controller selecting a music genre using majority vote.
*
* @author phil
*
*/
public class MusicController extends AbstractController {
private List<IActuator> actuators;
private String selectedGenre;
private int volume;
public MusicController() {
actuators = new LinkedList<IActuator>();
selectedGenre = "pop";
volume = 0;
}
@Override
public void attachSensor(ISensor sensor)
throws SimulationConfigurationException {
throw new SimulationConfigurationException(
"Sensors not supported by this controller.");
}
@Override
public void attachActuator(IActuator actuator)
throws SimulationConfigurationException {
if (actuator instanceof MusicActuator) {
actuators.add(actuator);
} else {
throw new SimulationConfigurationException(
"Trying to attach incompatible actuator.");
}
}
@Override
public void step() throws SimulationContextException {
selectMusicGenre();
adjustVolume();
}
/**
* Adjusts the volume to the average of all preferred values
*
* @throws SimulationContextException
*/
private void adjustVolume() throws SimulationContextException {
int newVolume = 0;
List<String> volumePreference = context.getPreference("musicVolume");
if (volumePreference != null) {
if (!volumePreference.isEmpty()) {
for (String v : volumePreference) {
newVolume += Integer.parseInt(v);
}
newVolume /= volumePreference.size();
}
}
if (newVolume != volume) {
volume = newVolume;
for (IActuator actuator : actuators) {
((MusicActuator) actuator).setVolume(volume);
}
}
}
/**
* Obtains music genre preferences and selects a genre according to majority
* vote
*
* @throws SimulationContextException
*/
private void selectMusicGenre() throws SimulationContextException {
List<String> preferredMusic = context.getPreference("preferredMusic");
if (preferredMusic != null) {
Map<String, Integer> votes = new HashMap<String, Integer>();
int highestCount = 0;
String previousGenre = selectedGenre;
for (String genre : preferredMusic) {
String key = genre.toLowerCase();
if (votes.containsKey(key)) {
int count = votes.get(key) + 1;
votes.put(key, count);
if (count > highestCount) {
highestCount = count;
selectedGenre = key;
}
} else {
votes.put(key, 1);
if (highestCount < 1) {
highestCount = 1;
selectedGenre = key;
}
}
}
if (!selectedGenre.equals(previousGenre)) {
for (IActuator actuator : actuators) {
((MusicActuator) actuator).setGenre(selectedGenre);
}
}
}
}
@Override
public List<ISensor> getAttachedSensors() {
return null;
}
@Override
public List<IActuator> getAttachedActuators() {
return actuators;
}
}