/*
 * Created on 15-mag-2004
 */
package jaCop.protocol;

import jaCop.nodeStatus.*;
import jaCop.heartbeat.*;
import jaCop.domain.*;

/**
 * @author Lompa
 */
public class StatusManager {
	
	private StatusStore statusStore = null;
	private Monitor monitor = null;
	private ProtocolTrigger trigger = null;
	
	/**
	 * @param statusStore
	 * @param monitor
	 * @param trigger
	 */
	public StatusManager(StatusStore statusStore, Monitor monitor) {
		this.statusStore = statusStore;
		this.monitor = monitor;
	}
	
	/**
	 * @param community
	 * @param calc
	 */
	public void addCommunity(String community, ILoadFactorCalculator calc, int connectionRank) {
		if (!statusStore.existsCommunity(community)){
			statusStore.addCommunity(community, calc, connectionRank);
			monitor.startControl(community);
		}
	}
	/**
	 * @param community
	 * @param node
	 * @param isJoined
	 * @param isStructure
	 */
	public void addNeighbor(String community, COPNode node, boolean isJoined, boolean isStructure) {
		if (!statusStore.isNeighbor(community, node)){
			statusStore.addNeighbor(community, node, isJoined, isStructure);
			monitor.startControl(node, community);
		}
	}
	/**
	 * @param community
	 * @return
	 */
	public boolean existsCommunity(String community) {
		return statusStore.existsCommunity(community);
	}
	/**
	 * @param community
	 * @return
	 */
	public COPNode[] getNeighbors(String community) {
		return statusStore.getNeighbors(community);
	}
	/**
	 * @param community
	 * @return
	 */
	public COPNode[] getStructureNeighbors(String community) {
		return statusStore.getStructureNeighbors(community);
	}
	/**
	 * @param community
	 * @return
	 */
	public COPNode[] getJoinedNeighbors(String community) {
		return statusStore.getJoinedNeighbors(community);
	}
	/**
	 * @return
	 */
	public String[] getCommunities() {
		return statusStore.getCommunities();
	}
	/**
	 * @param community
	 * @return
	 */
	public float getCurrentLoadFactor(String community) {
		return statusStore.getCurrentLoadFactor(community);
	}
	/**
	 * @param community
	 * @return
	 */
	public COPNode getCurrentNode(String community) {
		return statusStore.getCurrentNode(community);
	}
	/**
	 * @param community
	 * @return
	 */
	public COPNode getJuncturePoint(String community) {
		return statusStore.getJuncturePoint(community);
	}
	/**
	 * @param community
	 * @return
	 */
	public ILoadFactorCalculator getLoadFactorCalculator(String community) {
		return statusStore.getLoadFactorCalculator(community);
	}
	/**
	 * @param community
	 * @param node
	 * @return
	 */
	public boolean isJoined(String community, COPNode node) {
		return statusStore.isJoined(community, node);
	}
	/**
	 * @param community
	 * @param node
	 * @return
	 */
	public boolean isNeighbor(String community, COPNode node) {
		return statusStore.isNeighbor(community, node);
	}
	/**
	 * @param community
	 * @param node
	 * @return
	 */
	public boolean isStructure(String community, COPNode node) {
		return statusStore.isStructure(community, node);
	}
	/**
	 * @param community
	 */
	public void removeCommunity(String community) {
		if (statusStore.existsCommunity(community)){
			monitor.stopControl(community);
			statusStore.removeCommunity(community);
		}
	}
	/**
	 * @param community
	 * @param node
	 */
	public void removeNeighbor(String community, COPNode node) {
		removeNeighbor(community, node, true);
	}
	/**
	 * @param community
	 * @param node
	 */
	public void removeNeighbor(String community, COPNode node, boolean useTrigger) {
		if (statusStore.isNeighbor(community, node)){
			monitor.stopControl(node, community);
			/* ottengo un descrittore locale */
			COPNode localNodeDescriptor = statusStore.getNeighbor(community, node);
			/* rimuovo il nodo */
			statusStore.removeNeighbor(community, node);
			/* se richiesto faccio scattare il trigger */
			if (trigger != null && useTrigger)
				trigger.neighborLostTrigger(community, localNodeDescriptor);
		}
	}
	public boolean hasCompleteStructure(String community){
		return statusStore.hasCompleteStructure(community);
	}
	/**
	 * @param community
	 * @param node
	 * @param joined
	 */
	public void setJoined(String community, COPNode node, boolean joined) {
		statusStore.setJoined(community, node, joined);
	}
	/**
	 * @param community
	 * @param node
	 */
	public void setJuncturePoint(String community, COPNode node) {
		statusStore.setJuncturePoint(community, node);
	}
	/**
	 * @param community
	 * @param node
	 * @param loadFactor
	 */
	public void setLoadFactor(String community, COPNode node, float loadFactor) {
		statusStore.setLoadFactor(community, node, loadFactor);
	}
	/**
	 * @param community
	 * @param node
	 * @param structure
	 */
	public void setStructure(String community, COPNode node, boolean value) {
		statusStore.setStructure(community, node, value);
	}
	/**
	 * @return Returns the trigger.
	 */
	public ProtocolTrigger getTrigger() {
		return trigger;
	}
	/**
	 * @param trigger The trigger to set.
	 */
	public void setTrigger(ProtocolTrigger trigger) {
		this.trigger = trigger;
	}
	
	/**
	 * @param community
	 * @param node
	 * @param newNode
	 */
	//public void addStructureNeighbor(String community, COPNode node,
	//		COPNode newNode) {
	//	statusStore.addStructureNeighbor(community, node, newNode);
	//}
	/**
	 * @param community
	 * @param node
	 * @return
	 */
	public COPNode[] getStructureNeighbors(String community, COPNode node) {
		return statusStore.getStructureNeighbors(community, node);
	}
	/**
	 * @param community
	 * @param node
	 * @param oldNode
	 */
	//public void removeStructureNeighbor(String community, COPNode node,
	//		COPNode oldNode) {
	//	statusStore.removeStructureNeighbor(community, node, oldNode);
	//}
	/**
	 * @param community
	 */
	public void breakStructure(String community) {
		//jaCop.Debug.print("struttura spezzata");
		statusStore.breakStructure(community);
	}	
	/**
	 * @param community
	 */
	public void repairStructure(String community, int breaks) {
		//jaCop.Debug.print("struttura riparata");
		statusStore.repairStructure(community, breaks);
	}
	/**
	 * @param community
	 * @return
	 */
	public int getStructureBreaksNumber(String community){
		return statusStore.getStructureBreaksNumber(community);
	}
	/**
	 * @param community
	 * @return
	 */
	public int getConnectionRank(String community) {
		return statusStore.getConnectionRank(community);
	}
	/**
	 * @param community
	 * @param node
	 * @param nodes
	 */
	public void setStructureNeighbors(String community, COPNode node,
			COPNode[] nodes) {
		statusStore.setStructureNeighbors(community, node, nodes);
	}
	
	public boolean isCoreNode(String community){
		return statusStore.isCoreNode(community);
	}
}
