package urban.shapes;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import urban.model.Agent;
import urban.model.Site;
/**
* A node for a rule graph, represents either an agent and its states/unbound states or the binding between two agents for
* binding rules.
* @see BondNode
* @see SiteNode
*/
public class Node {
private String name;
Map<String, String> states = new TreeMap<String, String>();
protected Node(String name){
this.name = name;
}
/**
* Constructs a new node from two nodes that need merged together.
* @param root
* @param root2
*/
public Node(Node root, Node root2) {
name = root.name;
mergeInto(root.states, root2.states);
}
/**
* Constructs a node from an agent
* @param agent
*/
public Node(Agent agent) {
name = agent.getName();
addToMap(agent);
}
protected void addToMap(Agent agent) {
for(Site s : agent.getSites()){
if (!s.getName().equals(getGenerator())){
if (s.getBindingMark() == null){
states.put(s.getName(), s.getState());
}
}
}
}
private void mergeInto(Map<String, String> s, Map<String, String> s2) {
for(Entry<String,String> e : s.entrySet()){
String n = e.getKey();
if (!s2.containsKey(n)){
states.put(n, e.getValue());
} else {
String v = e.getValue();
String v2 = s2.get(n);
if (v == v2 || (v!= null && v.equals(v2))){
states.put(n, v);
} else {
throw new IllegalArgumentException();
}
}
}
for(Entry<String, String> e : s2.entrySet()){
if (!states.containsKey(e.getKey())){
states.put(e.getKey(), e.getValue());
}
}
}
/**
* @return the name of the agent that the node represents
*/
public String getName() {
return name;
}
/**
* @return the sites for agents on the left hand side of the rule
*/
public List<Site> getSitesL(){
ArrayList<Site> l = new ArrayList<Site>();
for(Entry<String,String> e : states.entrySet())
l.add(site(e));
return l;
}
/**
* @return the sites for agents on the right hand side of the rule
*/
public List<Site> getSitesR(){
ArrayList<Site> l = new ArrayList<Site>();
for(Entry<String,String> e : states.entrySet())
l.add(site(e));
return l;
}
private Site site(Entry<String, String> e) {
return new Site(name, e.getKey(), e.getValue(), null);
}
/**
* Queries the node to determine if a site already exists in the node.
* @param site
* @return true if site is present
*/
public boolean contains(String site) {
return states.containsKey(site);
}
public String toString(){
return name + states;
}
protected String getGenerator() {
return null;
}
}