/*
 * GDXRoot.java
 *
 * This is the primary class file for running the game.  It is the "static main"
 * of LibGDX. It must extend one of two classes: Game or ApplicationAdapter.
 * We generally prefer to extend Game, though we will use ApplicationAdapter
 * in a later lab for comparison.
 *
 * We prefer to keep this class fairly lightweight.  We want the Scenes (e.g.
 * the player models) to do the hard work. This class should just create the
 * scenes and manager how we switch between them. The ScreenListener interface
 * is how we manage that.
 *
 * Based on original GameX Ship Demo by Rama C. Hoetzlein, 2002
 *
 * @author: Walker M. White
 * @date: 1/10/25
 */
package edu.cornell.cis3152.shipdemo;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Screen;
import edu.cornell.gdiac.graphics.*;
import edu.cornell.gdiac.assets.AssetDirectory;
import edu.cornell.gdiac.util.ScreenListener;
/**
 * Root class for a LibGDX.
 *
 * This class is technically not the ROOT CLASS. Each platform has another
 * class above this (e.g. PC games use DesktopLauncher) which serves as the
 * true root. However, those classes are unique to each platform, while this
 * class is the same across all plaforms. In addition, this functions as the
 * root class all intents and purposes, and you would draw it as a root class
 * in an architecture specification.
 *
 * There are two ways to create a root class. One way is to extend ApplicationAdapter.
 * We have found this class to be problematic, especially when blending 3d assets
 * and 2d sprites. The other way is to implement the Game class which we have
 * done here. The game switches between different screens.
 *
 * Screen switching is where all the magic happens. We have created a method
 * exitScreen (as part of the ScreenListener interface) that allows a screen to
 * tell us that it wishes to switch to another screen. That is how you
 * transition between scenes.
 */
public class GDXRoot extends Game implements ScreenListener {
	/** AssetManager to load game assets (textures, sounds, etc.) */
	AssetDirectory directory;
	/** The 2d Graphics pipeline */
	SpriteBatch batch;

	/** Player mode for the asset loading screen (CONTROLLER CLASS) */
	LoadingScene loading;
	/** Player mode for the game proper (CONTROLLER CLASS) */
	GameScene playing;

	/**
	 * Creates a new game application root
	 */
	public GDXRoot() {}

	/**
	 * Called when the Application is first created.
	 *
     * This is method immediately loads assets for the loading screen, and
     * prepares the asynchronous loader for all other assets.
	 */
	@Override
	public void create () {
        // Start loading with the asset manager
        loading = new LoadingScene("assets.json" ,1);

        // Initialize the loading screen
        batch  = new SpriteBatch();
        loading.setSpriteBatch(batch);
        loading.setScreenListener(this);
        setScreen(loading);
	}

	/**
	 * Called when the Application is destroyed.
	 *
	 * It is your responsibility to dispose of all assets when this happened.
	 * Relying on Java garbage collection is NOT GOOD ENOUGH. If you loaded any
	 * assets, you must unload them.
	 */
	@Override
	public void dispose() {
        // Call dispose on our children
        setScreen(null);
        if (loading != null) {
            loading.dispose();
            loading = null;
        }
        if (playing != null) {
            playing.dispose();
            playing = null;
        }

        batch.dispose();
        batch = null;

        // Unload all the resources
        if (directory != null) {
            directory.unloadAssets();
            directory.dispose();
            directory = null;
        }
        super.dispose();
	}

	/**
	 * Called when the Application is resized.
	 *
	 * This can happen at any point during a non-paused state but will never
	 * happen before a call to create()
	 *
	 * @param width The window width
	 * @param height The window height
	 */
	@Override
	public void resize(int width, int height) {
        if (loading != null) {
            loading.resize(width,height);
        }
        if (playing != null) {
            playing.resize( width, height );
        }
        super.resize(width,height);
	}

    /**
     * The given screen has made a request to exit its player mode.
     *
     * The value exitCode can be used to implement menu options.
     *
     * @param screen   The screen requesting to exit
     * @param exitCode The state of the screen upon exit
     */
    public void exitScreen(Screen screen, int exitCode) {
        if (screen == loading) {
            playing = new GameScene(loading.getAssets(),batch);
            setScreen(playing);
            loading.dispose();
            loading = null;
        } else {
            // We quit the main application
            Gdx.app.exit();
        }
    }
}
