/*
 * Created on 26-apr-2004
 */
package jaCop.domain;

import java.net.InetAddress;

import convFramework.domain.*;
import convFramework.exceptions.BadInvocationArgumentException;
import java.util.*;

/**
 * Classe che modella un nodo per il protocollo COP
 * @author Lompa
 */
public class COPNode extends UDPNode {
	
	/* campi */
	private float loadFactor = Float.MAX_VALUE;
	private boolean structure = false;
	
	/**
	 * Costruisca una istanza di COPNode
	 * @param address l'indirizzo del nodo
	 * @param port la porta su cui è attivo il servizio COP
	 * @param loadFactor il fattore di carico del nodo
	 * @throws BadInvocationArgumentException se il valore della porta non è corretto
	 */
	public COPNode(InetAddress address, int port, float loadFactor, boolean structure)
			throws BadInvocationArgumentException {
		super(address, port);
		this.loadFactor = loadFactor;
		this.structure = structure;
	}
	
	/**
	 * @return il fattore di carico
	 */
	public float getLoadFactor(){
		return this.loadFactor;
	}
	/**
	 * @return
	 */
	public boolean isStructure() {
		return structure;
	}
	
	
	
	
	/* metodi statici di utilità ***********************************************************************/
	public static COPNode[] sort(COPNode[] nodes){
		boolean sorted = false;
		COPNode[] tempNodes = (COPNode[]) nodes.clone();
		while(!sorted){
			sorted = true;
			for(int i = 1; i < tempNodes.length; i++){
				if (tempNodes[i-1].getLoadFactor() > tempNodes[i].getLoadFactor()){
					COPNode temp = tempNodes[i];
					tempNodes[i] = tempNodes[i-1];
					tempNodes[i-1] = temp;
					sorted = false;
				}
			}
		}
		return tempNodes;
	}
	
	public static COPNode[] slice(COPNode[] nodes, int start, int number){
		COPNode[] res = new COPNode[number];
		for(int i = start; i < Math.min(nodes.length, start + number); i++){
			res[i-start] = nodes[i];
		}
		return res;
	}
	
	public static COPNode[] difference(COPNode[] nodes1, COPNode[] nodes2){
		Vector buff = new Vector();
		for (int i = 0; i < nodes1.length; i++){
			if (!contains(nodes2, nodes1[i]))
				buff.add(nodes1[i]);
		}
		return (COPNode[]) buff.toArray(new COPNode[buff.size()]);
	}
	
	public static COPNode[] intersection(COPNode[] nodes1, COPNode[] nodes2){
		Vector buff = new Vector();
		for(int i = 0; i < nodes1.length; i++){
			if (contains(nodes2, nodes1[i]))
				buff.add(nodes1[i]);
		}
		
		return (COPNode[]) buff.toArray(new COPNode[buff.size()]);
	}
	
	public static boolean areEquals(COPNode[] nodes1, COPNode[] nodes2){
		if (nodes1.length != nodes2.length) return false;

		for(int i = 0; i < nodes1.length; i++){
			if (!contains(nodes2, nodes1[i]))
				return false;
		}
		
		return true;
		
	}
	
	public static boolean contains(COPNode[] nodes, COPNode node){
		for(int i = 0; i< nodes.length; i++)
			if (nodes[i].isSame(node))
				return true;
		
		return false;
	}
	
	public static COPNode getFrom(Node node, COPNode[] nodes){
		for(int i = 0; i< nodes.length; i++)
			if (nodes[i].isSame(node))
				return nodes[i];
		
		return null;
	}
	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	//public boolean equals(COPNode node) {
	//	return super.isSame(node);
	//}
}
