package core;

import core.masters.AudioMaster;
import core.masters.EventMaster;
import core.masters.GameMaster;
import core.masters.SceneMaster;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.beans.property.ReadOnlyStringProperty;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.input.KeyEvent;
import javafx.stage.Screen;
import javafx.stage.Stage;

public abstract class Context extends Application {
	// instances from the master classes
	public final AudioMaster audioMaster;
	public final SceneMaster sceneMaster;
	public final EventMaster eventMaster;
	public final GameMaster gameMaster;

	// make the stage acessible
	private Scene scene;
	private boolean newStage = false;
	private int passedTicks = 0;
	private double lastNanoTime = System.nanoTime();
	private double time = 0;
	private ReadOnlyStringWrapper title = new ReadOnlyStringWrapper();
	private Stage stage;
	private AnimationTimer animationTimer;

	public Context(String title) {
		this.title.set(title);

		this.audioMaster = new AudioMaster(this);
		this.sceneMaster = new SceneMaster(this);
		this.eventMaster = new EventMaster(this);
		this.gameMaster = new GameMaster(this);
	}

	public void setScene(Scene scene) {
		newStage = true;
		this.scene = scene;
		stage.setScene(scene);
	}

	public void init() {
	}

	@Override
	public void start(Stage stage) {
		this.stage = stage;
		initStage();
		stage.show();
	}

	@Override
	public void stop() {
		gameMaster.stop();
		save();
	}

	private void initStage() {
		// stage settings
		stage.setTitle(title.get());
		stage.setResizable(false);
		stage.centerOnScreen();

		// event handling
		stage.addEventHandler(KeyEvent.KEY_PRESSED, event -> {
			eventMaster.addKeyCode(event.getCode());
		});

		stage.addEventHandler(KeyEvent.KEY_RELEASED, event -> {
			eventMaster.removeKeyCode(event.getCode());
		});

		System.out.println(Screen.getScreens().size());
		if (Screen.getScreens().size() > 1) {

			Rectangle2D bounds = Screen.getScreens().get(1).getBounds();
			stage.setX(bounds.getMinX());
			stage.setY(bounds.getMinY());
		}
	}

	protected abstract void load();

	protected abstract void save();

	public String getTitle() {
		return title.get();
	}

	public ReadOnlyStringProperty titleProperty() {
		return title.getReadOnlyProperty();
	}

	public AnimationTimer getAnimationTimer() {
		return animationTimer;
	}

	public EventMaster getEventMaster() {
		return eventMaster;
	}

	public AudioMaster getAudioMaster() {
		return audioMaster;
	}

	public SceneMaster getSceneMaster() {
		return sceneMaster;
	}

	public GameMaster getGameMaster() {
		return gameMaster;
	}
}

@@ -721,16 +721,56 @@
 eMaster;
+%0A%09public static Context instance = null;
 %0A%0A%09// ma
@@ -1114,24 +1114,133 @@
 ng title) %7B%0A
+%09%09if (instance != null) %7B%0A%09%09%09throw new RuntimeException(%22Context already existing;%22);%0A%09%09%7D%0A%09%09instance = this;%0A
 %09%09this.title

changed Context to "dirty" Singleton