package com.bladecoder.engine;

import com.badlogic.gdx.Files.FileType;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3ApplicationConfiguration;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Graphics;
import com.badlogic.gdx.backends.lwjgl3.Lwjgl3Window;
import com.bladecoder.engine.ui.SceneScreen;
import com.bladecoder.engine.ui.UI.Screens;
import com.bladecoder.engine.util.Config;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.system.Configuration;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

public class DesktopLauncher extends BladeEngine {

	private static final int WINDOW_WIDTH = 1920 / 2;
    private static final int WINDOW_HEIGHT = 1080 / 2;

    private boolean fullscreen = true;
    private Lwjgl3ApplicationConfiguration cfg = new Lwjgl3ApplicationConfiguration();
	
	private float speed = 1.0f;

	DesktopLauncher() {
		Properties p = new Properties();


		try {
			InputStream s = DesktopLauncher.class.getResourceAsStream("/" + Config.PROPERTIES_FILENAME);
			if(s!=null)
				p.load(s);
		} catch (IOException e) {
			System.out.println("Could not load properties file.");
		}
		
        cfg.setTitle(p.getProperty(Config.TITLE_PROP, "Blade Engine Adventure") + " "
                + p.getProperty(Config.VERSION_PROP, ""));

		cfg.setResizable(true);
		cfg.useVsync(true);
        cfg.setOpenGLEmulation(Lwjgl3ApplicationConfiguration.GLEmulation.GL20, 0, 0);
	}

	public void run() {
        List<String> iconList = new ArrayList<>();

        if (DesktopLauncher.class.getResource("/icons/icon128.png") != null)
            iconList.add("icons/icon128.png");

        if (DesktopLauncher.class.getResource("/icons/icon32.png") != null)
            iconList.add("icons/icon32.png");

        if (DesktopLauncher.class.getResource("/icons/icon16.png") != null)
            iconList.add("icons/icon16.png");

        cfg.setWindowIcon(FileType.Internal, iconList.toArray(new String[0]));

        new Lwjgl3Application(this, cfg);
	}

	public void parseParams(String[] args) {
		for (int i = 0; i < args.length; i++) {
			String s = args[i];
			if (s.equals("-t")) {
				if (i + 1 < args.length) {
					i++;
					setTestMode(args[i]);
				}
			} else if (s.equals("-p")) {
				if (i + 1 < args.length) {
					i++;
					setPlayMode(args[i]);
				}
			} else if (s.equals("-s")) {
				if (i + 1 < args.length) {
					i++;
					speed = Float.parseFloat(args[i]);
				}				
			} else if (s.equals("-chapter")) {
				if (i + 1 < args.length) {
					i++;
					setChapter(args[i]);
				}							
			} else if (s.equals("-f")) {
				fullscreen = true;
			} else if (s.equals("-d")) {
				setDebugMode();
			} else if (s.equals("-r")) {
				setRestart();				
			} else if (s.equals("-res")) {
				if (i + 1 < args.length) {
					i++;
					forceResolution(args[i]);
				}
			} else if (s.equals("-aspect")) {
				if (i + 1 < args.length) {
					i++;
					String aspect = args[i];
					
                    if (aspect.equals("16:9")) {
                        cfg.setWindowedMode(WINDOW_WIDTH, WINDOW_WIDTH * 9 / 16);
                    } else if (aspect.equals("4:3")) {
                        cfg.setWindowedMode(WINDOW_WIDTH, WINDOW_WIDTH * 3 / 4);
                    } else if (aspect.equals("16:10") || aspect.equals("8:5")) {
                        cfg.setWindowedMode(WINDOW_WIDTH, WINDOW_WIDTH * 10 / 16);
                    }
				}	
			} else if (s.equals("-w")) {
				fullscreen = false;
			} else if (s.equals("-l")) {
				if (i + 1 < args.length) {
					i++;
					loadGameState(args[i]);
				}
			} else if (s.equals("-h")) {
				usage();
            } else if (s.equals("-opengl")) {
                cfg.setOpenGLEmulation(Lwjgl3ApplicationConfiguration.GLEmulation.GL20, 0, 0);
            } else if (s.equals("-angle")) {
                cfg.setOpenGLEmulation(Lwjgl3ApplicationConfiguration.GLEmulation.ANGLE_GLES20, 0, 0);
            } else {
				if(i == 0 && !s.startsWith("-")) continue; // When embeded JRE the 0 parameter is the app name
				System.out.println("Unrecognized parameter: " + s);
				usage();
			}
		}

        if(!fullscreen)
            cfg.setWindowedMode(WINDOW_WIDTH, WINDOW_HEIGHT);
	}
	
	public void usage() {
		System.out.println("Usage:\n" 
				+ "-chapter chapter\tLoads the selected chapter\n"
				+ "-t scene_name\tStart test mode for the scene\n" 
				+ "-p record_name\tPlay previusly recorded games\n"
				+ "-f\tSet fullscreen mode\n"
				+ "-w\tSet windowed mode\n" 
				+ "-d\tShow debug messages\n"
				+ "-res width\tForce the resolution width\n" 
				+ "-l game_state\tLoad the previusly saved game state\n"
				+ "-r\tRun the game from the begining\n"
				+ "-s speed\tSets the game speed\n"
				+ "-aspect aspect_ratio\tSets the specified screen aspect (16:9, 4:3, 16:10)\n");

		System.exit(0);
	}

	@Override
	public void create() {
		if (fullscreen)
			Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode());
		
		hideCursor();
		
		super.create();
		
		if(getUI().getScreen(Screens.SCENE_SCREEN) instanceof SceneScreen)
			((SceneScreen) getUI().getScreen(Screens.SCENE_SCREEN)).setSpeed(speed);
	}

    private void hideCursor() {
        Lwjgl3Window window = ((Lwjgl3Graphics) Gdx.graphics).getWindow();
        GLFW.glfwSetInputMode(window.getWindowHandle(), GLFW.GLFW_CURSOR, GLFW.GLFW_CURSOR_HIDDEN);
    }

	public static void main(String[] args) {
//        if (SharedLibraryLoader.isMac && !"1".equals(System.getenv("JAVA_STARTED_ON_FIRST_THREAD_" + LibC.getpid()))) {
//            System.out.println("MacOs detected. Running in async mode.");
//            Configuration.GLFW_LIBRARY_NAME.set("glfw_async");
//        }

		DesktopLauncher game = new DesktopLauncher();
		game.parseParams(args);
		game.run();
	}
}
