public FAState recursiveRenderPositionAlternative(FAState state, GPoint basePoint) {
FAState alternativeEndState = alternativeEndState(state);
// This point is used to position each transition
GPoint point = new GPoint(basePoint);
point.addX(GContext.NODE_WIDTH+GContext.EPSILON_WIDTH);
GDimension firstAlternativeDimension = null;
for(int t=0; t<state.getNumberOfTransitions(); t++) {
FATransition transition = state.transition(t);
GLink link = getNode(state).getLink(transition);
if(t == 0) {
// We remember here the size of the first transition because if we find later
// a "loop" transition, we will have to offset this "loop" by the size of the first
// transition (because the "loop" is always drawed above the first transition).
firstAlternativeDimension = link.branchDim;
}
if(t > 0 && !transition.loop) {
// Offset the current point for each transition (except for a "loop" because it is
// displayed above the first transition)
point.addY(GContext.LINE_SPACE);
point.addY(link.branchDim.up);
}
if(transition.target == alternativeEndState) {
// The transition is simply a single transition (epsilon normally).
if(transition.loop) {
// If this is a "loop", draw it above the first transition
GPoint vp = new GPoint(basePoint);
vp.subY(firstAlternativeDimension.up);
vp.subY(link.branchDim.down);
// The "virtual position" is used by the link to know where to display itself
// when it has to "curve" (because both start and end point are on the same y-axis value)
getNode(state).getLink(transition).setVirtualPosition(vp);
} else {
getNode(state).getLink(transition).setVirtualPosition(point);
point.addY(link.branchDim.down);
}
} else {
// The transition is more than a single transition, continue recursively...
recursiveRenderPositionNode(transition.target, alternativeEndState, new GPoint(point));
point.addY(link.branchDim.down);
}
}
return alternativeEndState;
}