package framework.rendering;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.geom.Vector2f;
import framework.collision.CollisionComponent;
import framework.component.ComponentSystem;
import framework.component.list.SingleTypeComponentList;
import framework.component.path.ComponentPath;
import framework.event.Event;
import framework.event.EventSender;
import framework.spacial.OrientationComponent;
import framework.spacial.PositionComponent;
public class GraphicsSystem implements EventSender{
private final boolean showCollisionBoxes = false;
private ComponentPath cameraPath = null;
private int width = 0;
private int height = 0;
private static GraphicsSystem singleton = null;
private GraphicsSystem(){
singleton = this;
}
public static GraphicsSystem getInstance(){
if(singleton == null){
singleton = new GraphicsSystem();
}
return singleton;
}
public void render(GameContainer gc, Graphics g){
width = gc.getWidth();
height = gc.getHeight();
List<RenderableComponent> renderableComponents = getAllRenderableComponents();
Collections.sort(renderableComponents, RenderableComparator.getInstance());
for(RenderableComponent renderableComp: renderableComponents){
PositionComponent posComp = (PositionComponent) renderableComp.getSiblingByType(PositionComponent.class.getName());
if(posComp != null){
Vector2f pos = posComp.getVector();
if(pos != null){
int x = Math.round(pos.getX());
int y = Math.round(pos.getY());
if(renderableComp.getOffsetFromOrigin() != null){
pos.add(renderableComp.getOffsetFromOrigin());
x = Math.round(pos.getX());
y = Math.round(pos.getY());
}
transformGraphicsFor(renderableComp, x, y, g);
CameraComponent camera = (CameraComponent) ComponentSystem.getInstance().getComponent(cameraPath);
if(camera != null){
Vector2f cameraPos = camera.getTopLeftPosition();
if(cameraPos != null){
x -= cameraPos.x;
y -= cameraPos.y;
}
if(camera.getWidth() != 0 && camera.getHeight() != 0){
g.scale(width/camera.getWidth(), height/camera.getHeight());
}
}
((Renderable) renderableComp).draw(g, x, y);
g.resetTransform();
}
}
}
}
public void transformGraphicsFor(RenderableComponent renderableComp, int x, int y, Graphics g){
OrientationComponent orientationComp = (OrientationComponent) renderableComp.getSiblingByType(OrientationComponent.class.getName());
if(orientationComp != null){
float theta = orientationComp.getValue();
if(theta != 0){
g.rotate(x, y, theta);
}
}
}
private List<RenderableComponent> getAllRenderableComponents(){
List<RenderableComponent> renderableComponents = new ArrayList<RenderableComponent>();
SingleTypeComponentList spriteComps = ComponentSystem.getInstance().getAllComponents().getComponentsOfType(SpriteComponent.class.getName());
if(spriteComps != null){
renderableComponents.addAll((Collection)spriteComps.getAllComponents());
}
SingleTypeComponentList textComps = ComponentSystem.getInstance().getAllComponents().getComponentsOfType(TextRenderComponent.class.getName());
if(textComps != null){
renderableComponents.addAll((Collection)textComps.getAllComponents());
}
if(showCollisionBoxes){
SingleTypeComponentList collisComps = ComponentSystem.getInstance().getAllComponents().getComponentsOfType(CollisionComponent.class.getName());
if(collisComps != null){
renderableComponents.addAll((Collection)collisComps.getAllComponents());
}
}
return (List<RenderableComponent>) renderableComponents;
}
@Override
public String getType() {
return "GraphicsSystem";
}
@Override
public int getUniqueID() {
return 0;
}
public static class ScreenRenderedEvent extends Event{
public ScreenRenderedEvent(EventSender sender) {
super(sender);
}
@Override
protected String getEventTypeID() {
return "ScreenRendered";
}
}
public ComponentPath getCameraPath() {
return cameraPath;
}
public void setCamera(ComponentPath cameraPath) {
this.cameraPath = cameraPath;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
}