package eu.jonahbauer.wizard.client.libgdx.screens;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.utils.I18NBundle;
import com.badlogic.gdx.utils.Scaling;
import com.badlogic.gdx.utils.viewport.ExtendViewport;
import com.badlogic.gdx.utils.viewport.Viewport;
import eu.jonahbauer.wizard.client.libgdx.UiskinAtlas;
import eu.jonahbauer.wizard.client.libgdx.WizardGame;
import eu.jonahbauer.wizard.client.libgdx.listeners.AutoFocusListener;
import eu.jonahbauer.wizard.client.libgdx.listeners.ButtonClickListener;
import eu.jonahbauer.wizard.client.libgdx.listeners.ButtonKeyListener;
import eu.jonahbauer.wizard.client.libgdx.util.WizardAssetManager;
import org.jetbrains.annotations.MustBeInvokedByOverriders;

public abstract class WizardScreen implements Screen {
    protected final WizardGame game;
    protected final WizardAssetManager assets;

    protected Skin skin;
    protected I18NBundle messages;

    protected Stage stage;
    protected Viewport viewport;

    private Image background;

    protected float offsetX;
    protected float offsetY;
    protected float worldWidth;
    protected float worldHeight;

    protected WizardScreen(WizardGame game) {
        this.game = game;
        this.assets = game.assets;
    }

    @MustBeInvokedByOverriders
    protected void load() {
        messages = assets.get(WizardAssetManager.MESSAGES);
        skin = assets.get(WizardAssetManager.SKIN);
        skin.getAll(BitmapFont.class).forEach(entry -> {
            entry.value.getRegion().getTexture().setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
        });

        viewport = new ExtendViewport(WizardGame.WIDTH, WizardGame.HEIGHT);

        stage = new Stage(viewport);
        stage.addListener(new ButtonKeyListener());
        stage.addListener(new AutoFocusListener());
        stage.addListener(new ButtonClickListener(game.sounds));
        stage.setDebugAll(WizardGame.DEBUG);

        Gdx.input.setInputProcessor(stage);
    }

    @Override
    @MustBeInvokedByOverriders
    public void show() {
        load();

        background = new Image(skin.getRegion(UiskinAtlas.BACKGROUND));
        background.setScaling(Scaling.fill);
        background.setPosition(0,0);
        stage.addActor(background);
    }

    @Override
    public final void render(float delta) {
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT | (Gdx.graphics.getBufferFormat().coverageSampling?GL20.GL_COVERAGE_BUFFER_BIT_NV:0));

        stage.act(delta);
        stage.draw();
    }

    @Override
    public void resize(int width, int height) {
        viewport.update(width, height, true);

        worldWidth = viewport.getWorldWidth();
        worldHeight = viewport.getWorldHeight();
        offsetX = (worldWidth - WizardGame.WIDTH) / 2;
        offsetY = (worldHeight - WizardGame.HEIGHT) / 2;

        stage.getCamera().position.x -= offsetX;
        stage.getCamera().position.y -= offsetY;
        background.setBounds(-offsetX, -offsetY, worldWidth, worldHeight);
    }

    @Override
    public void pause() {}

    @Override
    public void resume() {}

    @Override
    public void hide() {}

    @Override
    @MustBeInvokedByOverriders
    public void dispose() {
        stage.dispose();
    }
}
