package urban.shapes;
import java.util.Iterator;
import java.util.List;
import urban.model.Agent;
import urban.model.Site;
/**
* A node representing a site that changes state
*/
public class SiteNode extends Node {
private final String siteName;
private final String left;
private String right;
/**
* Creates a SiteNode by merging to existing SiteNodes
* @param a
* @param b
*/
public SiteNode(SiteNode a, SiteNode b){
super(a,b);
this.siteName = a.siteName;
this.left = a.left;
this.right = getRightValue(a, b);
if (!this.siteName.equals(b.siteName)
|| (!(
(this.left.equals(b.left) && (b.right == null || this.right.equals(b.right)))
||
(this.right.equals(b.left) && (b.right == null || this.left.equals(b.right)))
))
)
throw new IllegalArgumentException("SiteNodes are not mergeable.");
}
/**
* Creates a SiteNode from an Agent and sitename
* @param agent
* @param siteName
* @param value
*/
public SiteNode(Agent agent, String siteName, String value) {
super(agent.getName());
this.siteName = siteName;
this.left = value;
this.right = null;
addToMap(agent);
}
/**
* Constructs a SiteNode from two agents.
*
* The agents contain both contain the same site with different states.
* @param a1
* @param a2
*/
public SiteNode(Agent a1, Agent a2) {
super(a1.getName());
Iterator<Site> i1 = a1.getSites().iterator();
Iterator<Site> i2 = a2.getSites().iterator();
while (i1.hasNext() && i2.hasNext()) {
Site s1 = i1.next();
Site s2 = i2.next();
if (s1.getState() != null && !s1.getState().equals(s2.getState())){
this.siteName = s1.getName();
this.left = s1.getState();
this.right = s2.getState();
addToMap(a1);
return;
}
}
throw new IllegalArgumentException("Agents should differ by one state");
}
@Override
public List<Site> getSitesL(){
List<Site> l = super.getSitesL();
l.add(getLeft());
return l;
}
/**
* @return the site that with appropriate state for the left hand side of the rule
*/
public Site getLeft() {
return new Site(getName(), siteName, left, null);
}
@Override
public List<Site> getSitesR(){
List<Site> l = super.getSitesR();
l.add(getRight());
return l;
}
/**
* @return the site that with appropriate state for the right hand side of the rule
*/
public Site getRight() {
return new Site(getName(), siteName, right, null);
}
@Override
protected String getGenerator() {
return siteName;
}
private static String getRightValue(SiteNode a, SiteNode b) {
String r = a.right;
if (r == null){
r = b.left.equals(a.left) ? b.right : b.left;
}
return r;
}
}