package eu.jonahbauer.wizard.client.libgdx;

import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Graphics;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.audio.Music;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.utils.I18NBundle;
import com.badlogic.gdx.utils.viewport.ExtendViewport;
import com.badlogic.gdx.utils.viewport.FitViewport;
import eu.jonahbauer.wizard.client.libgdx.screens.MainMenuScreen;
import lombok.Getter;

import java.util.Locale;

public class WizardGame extends Game {
	public static final boolean DEBUG = false;
	public static final int WIDTH = 1920;
	public static final int HEIGHT = 1080;

	public SpriteBatch batch;
	public I18NBundle messages;
	public Data data;

	private boolean toggle;

	private int oldHeight, oldWidth;
	
	@Getter
	private final Client client = new Client(this);

	@Override
	public void create() {
		batch = new SpriteBatch();
		messages = I18NBundle.createBundle(Gdx.files.internal("i18n/messages"), Locale.getDefault());

		// background music
		Music backgroundMusic = Gdx.audio.newMusic(Gdx.files.internal("background.mp3"));
		backgroundMusic.setLooping(true);
		backgroundMusic.setVolume(0.07f);
		backgroundMusic.play();

		// set cursor
		Pixmap cursor = new Pixmap(Gdx.files.internal("cursor.png"));
		Gdx.graphics.setCursor(Gdx.graphics.newCursor(cursor, 0, 0));
		cursor.dispose();
		
		this.setScreen(new MainMenuScreen(this));
	}

	@Override
	public void render() {
		super.render();

		// alt + enter shortcut for fullscreen
		var enter = Gdx.input.isKeyPressed(Input.Keys.ENTER);
		var alt = (Gdx.input.isKeyPressed(Input.Keys.ALT_LEFT) || Gdx.input.isKeyPressed(Input.Keys.ALT_RIGHT));
		var toggle = enter && alt;

		if (toggle && !this.toggle) {
			this.toggle = true;
			var fullscreen = Gdx.graphics.isFullscreen();
			Graphics.DisplayMode displayMode = Gdx.graphics.getDisplayMode();
			if (fullscreen) {
				Gdx.graphics.setWindowedMode(oldWidth, oldHeight);
			} else {
				oldWidth = Gdx.graphics.getWidth();
				oldHeight = Gdx.graphics.getHeight();
				Gdx.graphics.setFullscreenMode(displayMode);
			}
		} else if (!toggle) {
			this.toggle = false;
		}
	}

	@Override
	public void dispose () {
		batch.dispose();
		client.shutdownNow();
		var socket = client.getSocket();
		if (socket != null) {
			socket.close();
		}
	}
	
	public static class Data {
		public final ExtendViewport extendViewport;
		public final FitViewport fitViewport;
		
		public final Sound buttonClickSound;
		
		public final TextureAtlas uiskinAtlas;
		public final TextureAtlas menuAtlas;
		
		public final TextureRegion title;
		public final TextureRegion background;
		public final TextureRegion[] corners = new TextureRegion[4];
		public final TextureRegion[] symbols = new TextureRegion[4];
		
		public final Skin skin;
		public final Stage stage;
		
		public Data() {
			this.extendViewport = new ExtendViewport(WizardGame.WIDTH, WizardGame.HEIGHT);
			this.fitViewport = new FitViewport(WizardGame.WIDTH, WizardGame.HEIGHT);
			
			this.buttonClickSound = Gdx.audio.newSound(Gdx.files.internal("button_click_s.mp3"));
			
			this.uiskinAtlas = new TextureAtlas(Gdx.files.internal(UiskinAtlas.$PATH));
			this.menuAtlas = new TextureAtlas(Gdx.files.internal(MenuAtlas.$PATH));
			
			this.title = menuAtlas.findRegion(MenuAtlas.TITLE);
			this.background = menuAtlas.findRegion(MenuAtlas.BACKGROUND);
			this.corners[0] = menuAtlas.findRegion(MenuAtlas.ECKE_LO);
			this.corners[1] = menuAtlas.findRegion(MenuAtlas.ECKE_LU);
			this.corners[2] = menuAtlas.findRegion(MenuAtlas.ECKE_RU);
			this.corners[3] = menuAtlas.findRegion(MenuAtlas.ECKE_RO);
			this.symbols[0] = menuAtlas.findRegion(MenuAtlas.SYMBOL0);
			this.symbols[1] = menuAtlas.findRegion(MenuAtlas.SYMBOL1);
			this.symbols[2] = menuAtlas.findRegion(MenuAtlas.SYMBOL2);
			this.symbols[3] = menuAtlas.findRegion(MenuAtlas.SYMBOL3);
			
			this.skin = new Skin(Gdx.files.internal("uiskin.json"), uiskinAtlas);
			this.skin.getAll(BitmapFont.class).forEach(entry ->
					entry.value.getRegion().getTexture().setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear)
			);
			this.stage = new Stage(fitViewport);
			if (WizardGame.DEBUG) {
				stage.setDebugAll(true);
			}
		}
		
		public void reset() {
			stage.clear();
		}
		
		public void dispose() {
			buttonClickSound.dispose();
			uiskinAtlas.dispose();
			menuAtlas.dispose();
			skin.dispose();
			stage.dispose();
		}
	}
}
