package vilaug.peirce;
import vilaug.peirce.EccentricLayout.EccentricVertexData;
import edu.uci.ics.jung.utils.DefaultUserData;
import edu.uci.ics.jung.visualization.Coordinates;
import jung.ext.utils.Triple;
import jung.ext.utils.BasicUtils;
public class UpdatingData extends DefaultUserData {
private final static UpdatingData ROOT = new UpdatingData();
private Parent parent;
private Center center;
private Fruit fruit;
private Position position;
private Children children;
private Sister sister;
private Brother brother;
private AfterThought afterthought;
private Gender gender;
protected UpdatingData() {
initialize();
}
public void initialize() {
parent = new Parent();
center = new Center(this);
fruit = new Fruit(this);
position = new Position(this);
children = new Children();
sister = new Sister(this);
brother = new Brother(this);
afterthought = new AfterThought();
}
public UpdatingData(Gender gender) {
this(ROOT, gender);
}
public UpdatingData(UpdatingData parent, Gender gender) {
this();
setParent(parent, gender);
}
public void setParent(UpdatingData parent, Gender gender) {
this.gender = gender;
getParentData().setParent(parent);
getSisData().setSister(parent.getAfterThoughtData().getAfterThoughtSis());
parent.getAfterThoughtData().addAfterThought(this, gender);
parent.getChildrenData().addChild(gender);
if (gender == Gender.FEMALE) {
UpdatingData fruit = parent.getFruitData().getFruit();
if ((fruit == null) || (fruit.getFruitData().compareFruit(this))) {
parent.getFruitData().setFruit(this);
}
}
}
public void removeParent() {
if (gender == Gender.FEMALE) {
UpdatingData fruit = getParentData().getParent().getFruitData().getFruit();
if (fruit == this) {
parent.getFruitData().
}
}
}
public boolean needsUpdate() {
return (!getCenterData().isUptodate() ||
!getFruitData().isUptodate());
}
public Coordinates getPosition() {
return getPositionData().getPosition();
}
public Fruit getFruitData() { return fruit; }
public Parent getParentData() { return parent; }
public Center getCenterData() { return center; }
public Sister getSisData() { return sister; }
public Brother getBroData() { return brother; }
public Gender getGenderData() { return gender; }
public AfterThought getAfterThoughtData() { return afterthought; }
public Children getChildrenData() { return children; }
public Position getPositionData() { return position; }
public static class Parent {
private UpdatingData parent;
public UpdatingData getParent() { return parent; }
public void setParent(UpdatingData parent) {
this.parent = parent;
}
}
public static class Children {
private int girls = 0, boys = 0;
public void addGirl() { girls++; }
public void addBoy() { boys++; }
public void delGirl() { girls--; }
public void delBoy() { boys--; }
public int girlCount() { return girls; }
public int boyCount() { return boys; }
public void addChild(Gender gender) {
if (gender == Gender.FEMALE) addGirl();
else if (gender == Gender.MALE) addBoy();
}
public String toString() {
return "[" + girls + "|" + boys + "]";
}
}
public static class Position {
protected final static int RADIUS_RATIO = 100;
private UpdatingData delegate;
private Coordinates position;
public Position(UpdatingData delegate) {
this.delegate = delegate;
update();
}
public void update() {
position = trackPosition();
}
public Coordinates getPosition() {
return position;
}
protected Coordinates trackPosition() {
position.setX(Math.cos(getAngle()) * getRadius() +
delegate.getCenterData().getPosition().getX());
position.setY(Math.sin(getAngle()) * getRadius() +
delegate.getCenterData().getPosition().getY());
return position;
}
public double getRadius() {
return ((delegate.getFruitData().getLevel() + 1)
* Math.cos(getAngleIncrement() / 3))
* getRadiusRatio();
}
protected double getRadiusRatio() {
UpdatingData parent = delegate.getParentData().getParent();
if (parent != null) {
if (delegate.getGenderData() == Gender.FEMALE) {
return RADIUS_RATIO;
} else if (delegate.getGenderData() == Gender.MALE) {
return RADIUS_RATIO / 2;
}
}
return 0;
}
protected double getAngleIncrement() {
UpdatingData parent = delegate.getParentData().getParent();
if (parent != null) {
if (delegate.getGenderData() == Gender.FEMALE) {
return (2 * Math.PI) / parent.getChildrenData().girlCount();
} else if (delegate.getGenderData() == Gender.MALE) {
return (2 * Math.PI) / parent.getChildrenData().boyCount();
}
}
return 0;
}
public double getAngle() {
UpdatingData parent = delegate.getParentData().getParent();
if (parent != null) {
if (delegate.getGenderData() == Gender.FEMALE) {
return (2 * Math.PI * delegate.getSisData().getSisIndex())
/ parent.getChildrenData().girlCount();
} else if (delegate.getGenderData() == Gender.MALE) {
return (2 * Math.PI * delegate.getBroData().getBroIndex())
/ parent.getChildrenData().boyCount();
}
}
return 0;
}
}
/**
* The <code>Center</code> data class is simple. It can be imposed in
* a topdown manner. Its not necessary to iterate childs to calculate
* the center.
*
* @author A.C. van Rossum
*
*/
public static class Center {
private UpdatingData delegate;
private Coordinates position;
public Center(UpdatingData delegate) {
this.delegate = delegate;
update();
}
public Coordinates getPosition() {
return position;
}
public boolean isUptodate() {
return position == trackPosition();
}
public void update() {
position = trackPosition();
}
protected Coordinates trackPosition() {
return delegate.getParentData().getParent().getPosition();
}
}
/**
* The <code>Fruit</code> data class is more difficult. A parent wants
* to know what it childs are to know how many sublevels it does have.
* Programming the other way around involves adding a child with most
* sublevels called <code>Fruit</code> to a parent and updating it when
* appropriate. To know its level a parent only has to iterate the
* fruit list.
* The function <code>compareFruit</code> returns true if the suggest
* fruit is better than the currently existing. The level is calculated
* by
*
* It can be imposed in
* a topdown manner. Its not necessary to iterate childs to calculate
* the center.
*
* @author A.C. van Rossum
*
*/
public static class Fruit {
private UpdatingData delegate;
private UpdatingData fruit;
private int level;
public Fruit(UpdatingData delegate) {
this.delegate = delegate;
this.level = 0;
update();
}
public void setFruit(UpdatingData fruit) {
this.fruit = fruit;
update();
}
public UpdatingData getFruit() {
return fruit;
}
public int getLevel() {
return level;
}
public boolean isUptodate() {
return level == trackLevel();
}
public void update() {
level = trackLevel();
}
protected int trackLevel() {
UpdatingData f = delegate;
int i = 0;
while (f != null) {
f = f.getFruitData().getFruit();
i++;
}
return i;
}
public boolean compareFruit(UpdatingData comp) {
return comp.getFruitData().trackLevel() >
delegate.getFruitData().trackLevel();
}
public void getNewFruit(Sister sister) {
}
}
public static class AfterThought {
private UpdatingData afterthoughtSis;
private UpdatingData afterthoughtBro;
public UpdatingData getAfterThoughtSis() { return afterthoughtSis; }
public UpdatingData getAfterThoughtBro() { return afterthoughtBro; }
public void addAfterThought(UpdatingData afterthought, Gender gender) {
if (gender == Gender.FEMALE) {
addAfterThoughtSis(afterthought);
} else if (gender == Gender.MALE) {
addAfterThoughtBro(afterthought);
}
}
public void addAfterThoughtSis(UpdatingData afterthought) {
//if (afterthoughtSis != null) {
// afterthoughtSis.getSisData().setSister(afterthought);
//}
afterthoughtSis = afterthought;
}
public void addAfterThoughtBro(UpdatingData afterthought) {
//if (afterthoughtBro != null) {
// afterthoughtBro.getBroData().setBrother(afterthought);
//}
afterthoughtBro = afterthought;
}
}
final public static class Gender {
final String gender;
public final static Gender MALE = new Gender("male");
public final static Gender FEMALE = new Gender("female");
private Gender(String gender) {
this.gender = gender;
}
}
public static class Sister {
private UpdatingData delegate;
private UpdatingData sister;
private int index;
public Sister(UpdatingData delegate) {
this.delegate = delegate;
this.index = 0;
update();
}
public void setSister(UpdatingData sister) {
this.sister = sister;
}
public UpdatingData getSister() {
return sister;
}
protected int getSisIndex() {
return index;
}
protected int trackSisIndex() {
UpdatingData f = delegate;
int i = 0;
while (f != null) {
f = f.getSisData().getSister();
i++;
}
return i;
}
public UpdatingData nextSister() {
return sister.getSisData().getSister();
}
public UpdatingData getYoungerSister() {
UpdatingData f = delegate.getParentData().getParent()
.getAfterThoughtData().getAfterThoughtSis();
if (f == null) return null;
if (f == delegate) return null;
while (f != delegate) {
f = f.getSisData().getSister();
}
return f;
}
public void removeSis() {
UpdatingData f = delegate.getParentData().getParent()
.getAfterThoughtData().getAfterThoughtSis();
if (f == delegate) {
delegate.getParentData().getParent().getAfterThoughtData().addAfterThought(
delegate.getSisData().getSister(),
delegate.getSisData().getSister().getGenderData());
} else {
delegate.getSisData().getYoungerSister().getSisData().setSister(
delegate.getSisData().getSister());
}
delegate.getChildrenData().delGirl();
}
public void update() {
index = trackSisIndex();
}
}
public static class Brother {
private UpdatingData delegate;
private UpdatingData brother;
private int index;
public Brother(UpdatingData delegate) {
this.delegate = delegate;
this.index = 0;
update();
}
public UpdatingData getBrother() {
return brother;
}
public void setBrother(UpdatingData brother) {
this.brother = brother;
}
public int getBroIndex() {
return index;
}
protected int trackBroIndex() {
UpdatingData f = delegate;
int i = 0;
while (f != null) {
f = f.getBroData().getBrother();
i++;
}
return i;
}
public UpdatingData getYoungerBrother() {
UpdatingData f = delegate.getAfterThoughtData().getAfterThoughtBro();
if (f == null) return null;
if (f == delegate) return null;
while (f != delegate) {
f = f.getBroData().getBrother();
}
return f;
}
public void update() {
index = trackBroIndex();
}
}
}