package framework.component.path;
import java.io.IOException;
import framework.component.Component;
import framework.component.ComponentSystem;
import framework.component.ParentComponent;
import framework.component.list.MultiTypeComponentList;
import framework.io.CustomInputStream;
import framework.io.CustomOutputStream;
public class RelativeComponentPath extends ComponentPath{
private final ComponentPath from;
private final int stepsUpTree;
private final int[] branchesDownTree;
private final String type;
public RelativeComponentPath(String type, ComponentPath from, int stepsUpTree, int[] branchesDownTree) {
this.type = type;
this.from = from;
this.stepsUpTree = stepsUpTree;
this.branchesDownTree = branchesDownTree;
}
public RelativeComponentPath(String type, Component from, int stepsUpTree, int[] branchesDownTree) {
this(type, new AbsoluteComponentPath(from.getType(), from.getUniqueID()), stepsUpTree, branchesDownTree);
}
public RelativeComponentPath(String type, Component from, int[] branchesDownTree) {
this(type, from, 0, branchesDownTree);
}
public RelativeComponentPath(String type, ComponentPath from, int[] branchesDownTree) {
this(type, from, 0, branchesDownTree);
}
public RelativeComponentPath(String type, ComponentPath from, int stepsUpTree) {
this(type, from,stepsUpTree,new int[0]);
}
public RelativeComponentPath(String type, Component from, int stepsUpTree) {
this(type, new AbsoluteComponentPath(from.getType(), from.getUniqueID()), stepsUpTree, new int[0]);
}
public ComponentPath getFrom() {
return from;
}
public int getStepsUpTree() {
return stepsUpTree;
}
public int[] getBranchesDownTree() {
return branchesDownTree;
}
public String getType(){
return type;
}
@Override
public Component getComponentFrom(MultiTypeComponentList components) {
Component fromComponent = ComponentSystem.getInstance().getComponent(from);
if(fromComponent != null){
for(int i = 0;fromComponent != null && i < stepsUpTree; i++){
fromComponent = fromComponent.getParent();
}
if(fromComponent != null){
if(branchesDownTree.length > 0){
ParentComponent p = ((ParentComponent) fromComponent);
for(int i = 1; i < branchesDownTree.length-1; i++){
p = ((ParentComponent) fromComponent);
fromComponent = p.getComponent("ParentComponent", branchesDownTree[i]);
}
fromComponent = p.getComponent(getType(), branchesDownTree[branchesDownTree.length - 1]);
}
}
}
return fromComponent;
}
@Override
public void writeToStream(final CustomOutputStream out) throws IOException {
out.writeByte(ComponentPath.RELATIVE);
out.write(type);
from.writeToStream(out);
out.writeInt(stepsUpTree);
//Write out the integer array:
out.writeInt(branchesDownTree.length);
for(int i = 0; i < branchesDownTree.length; i++){
out.writeInt(branchesDownTree[i]);
}
}
public RelativeComponentPath(final CustomInputStream in, final int baseID) throws IOException{
this.type = in.readString();
this.from = ComponentPath.readPathFromStream(in, baseID);
this.stepsUpTree = in.readInt();
final int numBranches = in.readInt();
this.branchesDownTree = new int[numBranches];
for(int i = 0; i < numBranches; i++){
branchesDownTree[i] = in.readInt();
}
}
}