package com.company.game;

import com.company.graphics.Display;
import com.company.eventHandlers.KeyboardInput;
import com.company.eventHandlers.MouseInput;
import com.company.screenStates.*;

import java.awt.*;
import java.awt.image.BufferStrategy;

public class Game implements Runnable {

    private Display display;
    private boolean isRunning = false;
    private MouseInput mouseInput;
    private Thread thread;
    private KeyboardInput keyboardInput;
    private BufferStrategy bs;
    private Graphics g;
    private State gameState;
    private State menuState;
    private State gameOverState;
    private State highScoreState;
    private State chooseSideState;

    private void init() {
        this.display = new Display("Nozdormu Battle", 800, 600);
        this.keyboardInput = new KeyboardInput(this, this.display);
        this.mouseInput =new MouseInput(this.display);
        gameState = new GameState();
        menuState = new MainMenuState();
        gameOverState = new GameOverState();
        highScoreState = new HighScoresState();
        chooseSideState = new ChooseSideState();
        StateManager.setCurrentState(this.menuState);
    }

    public void displayFrame() {
        //Display the current frame using the display frame;
        this.bs = this.display.getCanvas().getBufferStrategy();

        if (bs == null) {
            this.display.getCanvas().createBufferStrategy(2);
            return;
        }

        this.g = bs.getDrawGraphics();
        /////////DRAW HERE /////////////////

        g.clearRect(0, 0, 800, 600);

        if(StateManager.getCurrentState() != null) {
            StateManager.getCurrentState().display(g);
        }

        ////////////// TO HERE////////////
        g.dispose();
        bs.show();
    }

    public void update() {
        if(StateManager.getCurrentState() != null) {
            StateManager.getCurrentState().update();
        }
    }

    public synchronized void start() {
        if (isRunning) {
            return;
        }

        isRunning = true;
        thread = new Thread(this);
        thread.start();
    }

    public synchronized void stop() {
        if (!isRunning) {
            return;
        }

        isRunning = false;

        try {
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    @Override
    public void run() {

        init();
        int fps = 30;
        double timePerTick = 1_000_000_000.0 / fps;
        double delta = 0;
        long now;
        long lastTime = System.nanoTime();
        long timer = 0;
        int ticks = 0;

        while (this.isRunning) {
            now = System.nanoTime();
            delta += (now-lastTime) / timePerTick;
            timer += now - lastTime;
            lastTime = now;

            if (delta >= 1) {
                this.update();
                this.displayFrame();
                ticks++;
                delta--;
            }

            if (timer >= 1_000_000_000) {
                ticks = 0;
                timer = 0;
            }
        }

        stop();
    }
}
@@ -20,16 +20,58 @@
 .game;%0A%0A
+import com.company.Settings.GameSettings;%0A
 import c
@@ -723,94 +723,346 @@
    p
-rivate void init() %7B%0A        this.display = new Display(%22Nozdormu Battle%22, 800, 600
+ublic boolean isRunning() %7B%0A        return this.isRunning;%0A    %7D%0A%0A    public void setRunning(boolean running) %7B%0A        this.isRunning = running;%0A    %7D%0A%0A    private void init() %7B%0A        this.display = new Display(%0A                GameSettings.GAME_NAME,%0A                GameSettings.GAME_WIDTH,%0A                GameSettings.GAME_HIGH
 );%0A
+%0A
     
@@ -1184,24 +1184,29 @@
 y);%0A        
+this.
 gameState = 
@@ -1230,16 +1230,21 @@
         
+this.
 menuStat
@@ -1276,16 +1276,21 @@
         
+this.
 gameOver
@@ -1326,16 +1326,21 @@
         
+this.
 highScor
@@ -1379,16 +1379,21 @@
         
+this.
 chooseSi
@@ -2297,16 +2297,21 @@
     if (
+this.
 isRunnin
@@ -2346,32 +2346,37 @@
      %7D%0A%0A        
+this.
 isRunning = true
@@ -2381,24 +2381,29 @@
 ue;%0A        
+this.
 thread = new
@@ -2421,24 +2421,29 @@
 s);%0A        
+this.
 thread.start
@@ -2556,16 +2556,21 @@
         
+this.
 isRunnin
@@ -2607,16 +2607,21 @@
         
+this.
 thread.j
@@ -2822,17 +2822,17 @@
  fps = 3
-0
+6
 ;%0A      

create getter and setter for isRunning; using GameSetting class; using "this"; change fps to 36 - for better effects