package framework.spacial;
import java.io.IOException;
import framework.component.Component;
import framework.component.ParentComponent;
import framework.component.list.SingleTypeComponentList;
import framework.component.util.FloatValueComponent;
import framework.event.EventSender;
import framework.event.EventSystem;
import framework.event.util.ValueChangedEvent;
import framework.io.CustomInputStream;
public class OrientationComponent extends FloatValueComponent{
public OrientationComponent(CustomInputStream in, int baseID,
byte versionNum) throws IOException {
super(in, baseID, versionNum);
}
public OrientationComponent(float value) {
super(value);
}
@Override
public boolean allowSameTypedSiblings() {
return false;
}
@Override
public void setValue(float newValue) {
if(newValue > 180){
while(newValue > 180){
newValue -= 360;
}
}else if(newValue < -180){
while(newValue < -180){
newValue += 360;
}
}
float oldValue = getValue();
super.setValue(newValue);
if(oldValue != newValue){
EventSystem.getInstance().pushEvent(new OrientationChangedEvent(this, oldValue, newValue));
alterDescendents(newValue-oldValue, getSiblingsByType(ParentComponent.class.getName()));
}
}
private void alterDescendents(float deltaTheta, SingleTypeComponentList descendents){
if(descendents != null && shouldUpdateDescendents()){
for(Component d:descendents){
ParentComponent p = (ParentComponent) d;
Component oc = p.getChildByType(getType());
PositionComponent pos = (PositionComponent) p.getChildByType(PositionComponent.class.getName());
if(pos != null){
PositionComponent centrePos = (PositionComponent) getSiblingByType(PositionComponent.class.getName());
if(centrePos != null){
pos.setVector(VectorUtil.rotateAround(pos.getVector(), centrePos.getVector(), deltaTheta));
}
}
if(oc != null){
OrientationComponent o = (OrientationComponent) oc;
if(o.shouldUpdateWithAncestor()){
o.setValue(o.getValue()+deltaTheta);
}
}else{
alterDescendents(deltaTheta, p.getChildrenByType(ParentComponent.class.getName()));
}
}
}
}
public void setRelativeToParent(float newTheta){
ParentComponent p = this.getParent();
if(p != null){
p = p.getParent();
while(p != null && p.getChildByType(getType()) == null){
p = p.getParent();
}
}
OrientationComponent orientationComp = null;
if(p != null){
orientationComp = (OrientationComponent) p.getChildByType(getType());
}
float parentTheta = 0;
if(orientationComp != null){
parentTheta = orientationComp.getValue();
}
setValue(parentTheta + newTheta);
}
private boolean shouldUpdateDescendents() {
return true;
}
private boolean shouldUpdateWithAncestor() {
return true;
}
public static class OrientationChangedEvent extends ValueChangedEvent<Float>{
private final float delta;
public OrientationChangedEvent(EventSender sender, Float from, Float to) {
super(sender, from, to);
delta = to - from;
}
@Override
protected String getEventTypeID() {
return "OrientationChanged";
}
public float getDelta(){
return delta;
}
}
@Override
protected void onAddedToParent(ParentComponent parent) {
super.onAddedToParent(parent);
if(parent != null){
setRelativeToParent(getValue());
}
}
}