package varianti;

import java.util.*;

import _gestioneeventi.Evento;
import _gestioneeventi.Listener;


public class EnvironmentOriginale {
	private HashMap<Listener, LinkedList<Evento>> codeEventiDeiListener;

	public EnvironmentOriginale() {
		codeEventiDeiListener = new HashMap<Listener, LinkedList<Evento>>();
	}

	public void addListener(Listener lr) {
		codeEventiDeiListener.put(lr, new LinkedList<Evento>());
	}

	public void aggiungiEvento(Evento e) { // questo metodo serve per
										   // inizializzare la coda
		Listener lr = e.getDestinatario();
		codeEventiDeiListener.get(lr).add(e);
	}

	private boolean eventiPresenti() {
		Iterator<Listener> it = codeEventiDeiListener.keySet().iterator();
		while (it.hasNext()) {
			Listener lr = it.next();
			if (!codeEventiDeiListener.get(lr).isEmpty())
				return true;
		}
		return false;
	}

	public void eseguiEnvironment() {
		while (eventiPresenti()) { // finche' ci sono eventi da processare nelle code
			// prendi tutti i primi elementi e mandali ai rispettivi Listener
			Iterator<Listener> it = codeEventiDeiListener.keySet().iterator();
			while (it.hasNext()) {
				Listener listener = it.next();
				LinkedList<Evento> coda = codeEventiDeiListener.get(listener);
				if (coda.isEmpty())
					continue;
				Evento e = coda.remove(0);

				Evento ne = listener.fired(e); // chiamata all'esecuzione del Listener
				
				// aggiunge evento ne nella coda del destinatario di ne
				if (ne == null)
					continue;
				Listener destinatario = ne.getDestinatario();
				if (destinatario != null) // il messaggio e' per un destinatario specifico
					codeEventiDeiListener.get(destinatario).add(ne);
				else {// destinatario == null significa che il messaggio e' in broadcasting
					Iterator<Listener> itn = codeEventiDeiListener.keySet()
							.iterator();
					while (itn.hasNext()) {
						Listener lr = itn.next();
						codeEventiDeiListener.get(lr).add(ne);
					}
				}
			}
		}
	}

}
