package framework.rendering;
import java.io.IOException;
import main.L;
import org.newdawn.slick.geom.Vector2f;
import framework.component.Component;
import framework.component.ParentComponent;
import framework.component.filter.SiblingFilter;
import framework.event.Event;
import framework.event.EventListener;
import framework.event.EventSystem;
import framework.event.filter.EventSenderComponentFilter;
import framework.io.CustomInputStream;
import framework.spacial.PositionComponent;
import framework.spacial.PositionComponent.PositionChangedEvent;
public class CameraComponent extends Component implements EventListener{
private float offsetFromLeft = 0;
private float offsetFromTop = 0;
private int width = 0;
private int height = 0;
private Vector2f topLeftPosition = new Vector2f();
private boolean canMoveVertically = true;
private boolean canMoveHorizontally = true;
public CameraComponent(CustomInputStream in, int baseID, byte versionNum) throws IOException {
super(in, baseID, versionNum);
}
public CameraComponent(float offsetFromLeft, float offsetFromTop, int width, int height, boolean canMoveVertically, boolean canMoveHorizontally) {
super();
this.offsetFromLeft = offsetFromLeft;
this.offsetFromTop = offsetFromTop;
this.width = width;
this.height = height;
this.canMoveVertically = canMoveVertically;
this.canMoveHorizontally = canMoveHorizontally;
SiblingFilter siblingFilter = new SiblingFilter(this, PositionComponent.class);
EventSystem.getInstance().registerEventListener(this, "PositionChanged", new EventSenderComponentFilter(siblingFilter));
}
public CameraComponent(float offsetFromLeft, float offsetFromTop, boolean canMoveVerrically, boolean canMoveHorizontally) {
this(offsetFromLeft, offsetFromTop, GraphicsSystem.getInstance().getWidth(), GraphicsSystem.getInstance().getHeight(), canMoveVerrically, canMoveHorizontally);
}
public CameraComponent(float offsetFromLeft, float offsetFromTop) {
this(offsetFromLeft, offsetFromTop, true, true);
}
public CameraComponent(){
this(0,0);
}
@Override
public void onEvent(Event e) {
if(e != null){
if(e.getType().equals("PositionChanged")){
updateCamera(((PositionChangedEvent) e).getTo());
}
}
}
public void updateCamera(){
PositionComponent p = (PositionComponent) getSiblingByType(PositionComponent.class.getName());
if(p != null){
this.updateCamera(p.getVector());
}
}
public void updateCamera(Vector2f siblingPosition){
if(canMoveHorizontally){
int newX = Math.round(siblingPosition.getX());
topLeftPosition.set(newX - offsetFromLeft, topLeftPosition.y);
}
if(canMoveVertically){
int newY = Math.round(siblingPosition.getY());
topLeftPosition.set(topLeftPosition.x, newY - offsetFromTop);
}
}
@Override
public boolean allowSameTypedSiblings() {
return false;
}
@Override
protected void onAddedToParent(ParentComponent parent) {
super.onAddedToParent(parent);
resetCamera();
}
@Override
public void onSiblingAdded(Component sibling) {
super.onSiblingAdded(sibling);
if(sibling.isType(PositionComponent.class)){
resetCamera();
}
}
private void resetCamera(){
boolean shouldMoveHorizontally = canMoveHorizontally;
boolean shouldMoveVertically = canMoveVertically;
this.canMoveHorizontally = true;
this.canMoveVertically = true;
updateCamera();
this.canMoveHorizontally = shouldMoveHorizontally;
this.canMoveVertically = shouldMoveVertically;
}
@Override
protected byte getDataFormatVersion() {
return 0;
}
public Vector2f getTopLeftPosition(){
updateCamera();
return topLeftPosition;
}
public float getOffsetFromLeft() {
return offsetFromLeft;
}
public void setOffsetFromLeft(float offsetFromLeft) {
this.offsetFromLeft = offsetFromLeft;
}
public float getOffsetFromTop() {
return offsetFromTop;
}
public void setOffsetFromTop(float offsetFromTop) {
this.offsetFromTop = offsetFromTop;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public boolean canMoveVertically() {
return canMoveVertically;
}
public void setCanMoveVertically(boolean canMoveVertically) {
this.canMoveVertically = canMoveVertically;
}
public boolean canMoveHorizontally() {
return canMoveHorizontally;
}
public void setCanMoveHorizontally(boolean canMoveHorizontally) {
this.canMoveHorizontally = canMoveHorizontally;
}
}