package de.tu_darmstadt.tk.SmartHomeNetworkSim.control;

import java.util.Observer;

import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Model;

/**
 * Controller which allows interaction with the Model and Simulation
 *
 * @author Andreas T. Meyer-Berg
 */
public class Controller {
	/**
	 * {@link Model} which stores the smart home model
	 */
	private Model model;
	
	/**
	 * Controller for Import of user defined java classes
	 */
	private ImportController importController;
	
	/**
	 * Controller which allows configuration of the program e.g. settings
	 */
	private SettingsController settingsController;
	
	/**
	 * NetworkController for manipulation of the network model
	 */
	private NetworkController networkController;
	
	/**
	 * SimulationController which controls the simulation
	 */
	private SimulationController simulationController;
	
	/**
	 * Create a new Controller, which controls the given model and allows
	 * manipulation of this model
	 * 
	 * @param model
	 *            model, that should be controlled
	 */
	public Controller(Model model) {
		this.model = model;
		settingsController = new SettingsController(this.model, this);
		importController = new ImportController(this.model, this);
		simulationController = new SimulationController(this.model, this);
		networkController = new NetworkController(this.model, this);
	}
	
	/**
	 * Returns the main model of the simulation, use with precaution. Calls via the controller are preferred
	 * @return Main Model for full access to the model
	 * @deprecated use the corresponding controller 
	 */
	public Model getModel(){
		return model;
	}
	
	/**
	 * Returns the ImportController, which manages the user imported classes, 
	 * which can be used in the framework
	 * @return {@link ImportController}
	 */
	public ImportController getImportController(){
		return importController;
	}
	
	/**
	 * Returns the controller responsible for configuration of the program, e.g. changing the settings 
	 * @return {@link SettingsController}
	 */
	public SettingsController getSettingsController(){
		return settingsController;
	}
	
	/**
	 * Return the controller, which manages the network Model
	 * @return {@link NetworkController} 
	 */
	public NetworkController getNetworkController(){
		return networkController;
	}
	
	/**
	 * Return the simulation controller, to manage the simulation
	 * @return {@link SimulationController}
	 */
	public SimulationController getSimulationController(){
		return simulationController;
	}
	
	/**
	 * Notifies Observer, which may update their visualization/state
	 */
	public void notifyObservers(){
		model.setChanged();
		model.notifyObservers();
	}
	
	/**
	 * Adds Observer to the model, which will be notified, when the model changes
	 * 
	 * @param observer observer to be to notified on changes
	 */
	public void addObserver(Observer observer){
		model.addObserver(observer);
	}
	
	/**
	 * Removes Observer from the model. The Observer will no longer be notified on changes 
	 * 
	 * @param observer observer to be removed
	 */
	public void removeObserver(Observer observer){
		model.deleteObserver(observer);
	}
}
