package sprites;
import java.awt.Dimension;
import java.awt.DisplayMode;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Window;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLProfile;
import javax.media.opengl.awt.GLCanvas;
import sprites.awt.SpritesIOListenerAWT;
import sprites.base.Clock;
import sprites.base.ConfigurationObserver;
import sprites.base.Renderer;
import sprites.base.SpritesListener;
import sprites.base.SpritesWindow;
import sprites.io.Keyboard;
import sprites.io.Mouse;
import sprites.newt.SpritesIOListenerNEWT;
public class SpritesApplication implements WindowListener, ComponentListener, ConfigurationObserver{
private Configuration config;
// private GLWindow glWindow;
private SpritesWindow window;
private GLCanvas canvas;
private SpritesListener listener;
private SpritesIOListenerAWT ioListener;
// private SpritesIOListenerNEWT ioListener;
private Clock clock;
private GraphicsEnvironment ge;
private GraphicsDevice gd;
private GraphicsConfiguration gc;
static {
// GLProfile.initSingleton();
}
public SpritesApplication(Configuration configuration){
/* System */
System.setProperty("sun.java2d.noddraw", "true");
this.config = configuration;
}
public SpritesApplication(RenderingCallback callback, LogicCallback logic, int windowWidth, int windowHeight, int canvasWidth, int canvasHeight){
this(new Configuration(callback, logic, windowWidth, windowHeight, canvasWidth, canvasHeight));
}
public SpritesApplication(RenderingCallback callback, LogicCallback logic){
this(callback, logic, 1024, 768, 1024, 768);
}
//-Dsun.java2d.noddraw=true
public void start(){
this.config.subscribe(this);
// GLProfile glp = GLProfile.getDefault(GLProfile.getDefaultDevice());
// GLCapabilities caps = new GLCapabilities(glp);
this.listener = new SpritesListener(this.config);
this.ioListener = new SpritesIOListenerAWT(this.config);
/* The following code stays in case NEWT gets the right configuratability that I need
*
* this.glWindow = GLWindow.create(caps);
* this.glWindow.setSize(this.config.getWindowWidth(), this.config.getWindowHeight());
* this.glWindow.setTitle("Sprites Application");
* this.glWindow.addGLEventListener(listener);
* this.glWindow.addMouseListener(ioListener);
* this.glWindow.addKeyListener(ioListener);
* this.glWindow.addWindowListener(this);
* this.glWindow.setVisible(true);
*/
this.ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
this.gd = ge.getDefaultScreenDevice();
this.gc = gd.getDefaultConfiguration();
// this.canvas = new GLCanvas(caps);
this.canvas = new GLCanvas();
this.canvas.addMouseListener(ioListener);
this.canvas.addMouseMotionListener(ioListener);
this.canvas.addMouseWheelListener(ioListener);
this.canvas.addKeyListener(ioListener);
this.canvas.addGLEventListener(listener);
this.window = new SpritesWindow(this.config, this.canvas);
this.window.addWindowListener(this);
this.window.addComponentListener(this);
this.clock = new Clock(this.config.getLogicCallback(), this.window, 60, 20);
System.out.println("Starting Application");
if(this.config.isFullscreen()){
this.enterFullscreen();
} else {
this.window.pack();
this.window.setVisible(true);
}
this.clock.start();
}
public Configuration getConfiguration(){
return this.config;
}
@Override
public void windowActivated(WindowEvent e) {
System.out.println("Window activated ...");
}
@Override
public void windowClosed(WindowEvent e) {
System.out.println("Window closed ...");
}
@Override
public void windowClosing(WindowEvent e) {
System.out.println("Window closing ...");
this.clock.halt();
this.window.dispose();
}
@Override
public void windowDeactivated(WindowEvent e) {
System.out.println("Window deactivated ...");
}
@Override
public void windowDeiconified(WindowEvent e) {
System.out.println("Window deiconified ...");
}
@Override
public void windowIconified(WindowEvent e) {
System.out.println("Window iconified ...");
}
@Override
public void windowOpened(WindowEvent e) {
System.out.println("Window opened ...");
}
@Override
public void componentHidden(ComponentEvent e) {
System.out.println("Component hidden");
}
@Override
public void componentMoved(ComponentEvent e) {
System.out.println("Component moved");
}
@Override
public void componentResized(ComponentEvent e) {
System.out.println("ComponentResized");
int width = this.canvas.getWidth();
int height = this.canvas.getHeight();
// System.out.println("Window Component resized to: ("+width+", "+height+")");
this.config.setWindowSize(width, height);
}
@Override
public void componentShown(ComponentEvent e) {
System.out.println("Component shown");
}
@Override
public void changedWindowSize(int width, int height) {
System.out.println("Changed Window Size: ("+width+", "+height+")");
// this.window.getContentPane().setPreferredSize(new Dimension(this.config.getWindowWidth(), this.config.getWindowHeight()));
if(this.config.isFullscreen()){
this.setDisplayMode(width, height);
} else {
this.canvas.setSize(width, height);
this.window.pack();
}
if(this.config.scaleCanvasOnResize()){
this.config.setCanvasSize(width, height);
}
}
@Override
public void changedCanvasSize(int width, int height) {
}
@Override
public void changedWindowResizable(boolean resizable) {
this.window.setResizable(resizable);
this.window.pack();
}
@Override
public void changedWindowFullscreen(boolean fullscreen) {
if(fullscreen){
this.enterFullscreen();
} else {
this.exitFullscreen();
}
}
@Override
public void changedKeyboard(Keyboard keyboard) {
// TODO Auto-generated method stub
}
@Override
public void changedLogicCallback(LogicCallback logicCallback) {
this.clock.setLogicCallback(logicCallback);
}
@Override
public void changedMouse(Mouse mouse) {
// TODO Auto-generated method stub
}
@Override
public void changedRenderingCallback(RenderingCallback renderingCallback) {
// TODO Auto-generated method stub
}
@Override
public void changedScaleCanvasOnResize(boolean scaleCanvasOnResize) {
// TODO Auto-generated method stub
}
@Override
public void changedWindowUndecorated(boolean undecorated) {
System.out.println(undecorated ? "Undecorated" : "Decorated");
this.setDecoration(undecorated);
}
private void enterFullscreen(){
if(!this.gd.isFullScreenSupported()){
System.err.println("Fullscreen is not supported on this device!");
return;
}
Window current = this.gd.getFullScreenWindow();
if(current != null && current.equals(this.window)){
return;
}
if(this.window.isDisplayable()){
this.window.setVisible(false);
this.window.dispose();
}
this.window.setUndecorated(true);
this.window.pack();
this.gd.setFullScreenWindow(this.window);
this.setDisplayMode(this.config.getWindowWidth(), this.config.getWindowHeight());
}
private void exitFullscreen(){
if(this.gd.getFullScreenWindow().equals(this.window)){
this.gd.setFullScreenWindow(null);
this.setDecoration(this.config.isUndecorated());
this.window.setLocation(this.gc.getBounds().width / 2 - this.config.getWindowWidth() / 2, gc.getBounds().height / 2 - this.config.getWindowHeight() / 2);
}
}
private void setDecoration(boolean undecorated){
if(this.window.isUndecorated() != undecorated){
this.window.setVisible(false);
this.window.dispose();
this.window.setUndecorated(undecorated);
this.window.pack();
this.window.setVisible(true);
}
}
private void setDisplayMode(int width, int height){
DisplayMode mode = new DisplayMode(width, height, 32, 60);
if(this.gd.isDisplayChangeSupported()){
for(DisplayMode supported : this.gd.getDisplayModes()){
if(supported.equals(mode)){
this.gd.setDisplayMode(mode);
return;
}
}
System.err.println("The Display Mode: Width: "+width+", Height: "+height+", Bit Depth: 32, Refresh Rate: 60 is not supported!");
} else {
System.err.println("This device does not support changing the fullscreen DisplayMode");
// TODO What kind of fallback would be feasable here?
}
}
}