package huds;

import java.util.Random;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.freetype.FreeTypeFontGenerator;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.ImageButton;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.scenes.scene2d.utils.SpriteDrawable;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.viewport.FitViewport;
import com.ggj2k20.game.GameMain;

import helpers.GameInfo;
import helpers.GameManager;
import scenes.GamePlay;
import scenes.MainMenu;
import waterfall.Waterfall;
import waterfall.WaterfallController;


public class GamePlayButtons
{

    private GameMain gameMain;

    private Stage stage;

    private FitViewport gameViewport;

    Random random = new Random();

    private Array<ImageButton> holes = new Array<ImageButton>();

    private Array<Float> xCoordinates = new Array<Float>();

    private Array<Float> yCoordinates = new Array<Float>();

    private Image gameOverPanel;

    private ImageButton playAgainBtn, quitBtn;

    private WaterfallController waterfallController;

    private Label winnerLabel;

    public GamePlayButtons(GameMain gameMain)
    {
        this.gameMain = gameMain;
        waterfallController = new WaterfallController();

        gameViewport = new FitViewport(GameInfo.W, GameInfo.H, new OrthographicCamera());

        stage = new Stage(gameViewport, gameMain.getBatch());

        // setting who is going to process the buttons touch. Stage is going to register the click
        Gdx.input.setInputProcessor(stage);

        //        positionHole();
    }

    /* THIS IS OLD
    void createAndPositionHoles()
    {
        for (int i = 0; i < 12; i++)
        {
            ImageButton hole = new ImageButton(new SpriteDrawable(new Sprite(new Texture("Hole/Hole.png"))));

            float randomX = randomBetweenNumbers(0, GameInfo.W - 30f);
            float randomY = randomBetweenNumbers(120f, GameInfo.H - 150f);

            while (!canDrawHole(randomX, randomY))
            {
                randomX = randomBetweenNumbers(0, GameInfo.W - 30f);
                randomY = randomBetweenNumbers(120f, GameInfo.H - 150f);
            }

            xCoordinates.add(randomX);
            yCoordinates.add(randomY);

            hole.setPosition(randomX, randomY);
            holes.add(hole);
            stage.addActor(holes.get(i));
        }

    }*/

    boolean canDrawHole(float randX, float randY)
    {
        for (Float x : xCoordinates)
        {
            if (randX + 30 < x || randX > x + 30)
            {
                //FIXME
            }
            else
            {
                for (Float y : yCoordinates)
                {
                    if (randY + 30 < y || randY > y + 30)
                    {
                        //FIXME
                    }
                    else
                    {
                        return false;
                    }
                }
            }
        }

        return true;
    }

    void positionHole()
    {
        ImageButton hole = new ImageButton(new SpriteDrawable(new Sprite(new Texture("Hole/Hole.png"))));
        float randomX = randomBetweenNumbers(0, GameInfo.W - 30f);
        float randomY = randomBetweenNumbers(120f, GameInfo.H - 150f);

        xCoordinates.add(randomX);
        yCoordinates.add(randomY);

        hole.setPosition(randomX, randomY);
        holes.add(hole);
        stage.addActor(hole);
        addListener(hole);

    }

    public void addHole()
    {
        ImageButton hole = new ImageButton(new SpriteDrawable(new Sprite(new Texture("Hole/Hole.png"))));
        float randomX = randomBetweenNumbers(0, GameInfo.W - 30f);
        float randomY = randomBetweenNumbers(120f, GameInfo.H - 150f);

        while (!canDrawHole(randomX, randomY))
        {
            randomX = randomBetweenNumbers(0, GameInfo.W - 30f);
            randomY = randomBetweenNumbers(120f, GameInfo.H - 150f);
        }

        //        Waterfall waterfall = new Waterfall(world, randomX, randomY);
        Waterfall waterfall = new Waterfall(randomX, randomY);
        waterfallController.addWaterfall(waterfall);

        xCoordinates.add(randomX);
        yCoordinates.add(randomY);

        hole.setPosition(randomX, randomY);

        hole.setName(String.valueOf(GameManager.getInstance().player));
        GameManager.getInstance().player = GameManager.getInstance().player == 1 ? 2 : 1;

        holes.add(hole);
        stage.addActor(hole);

        GameManager.getInstance().drawNext = false;
        addListener(hole);
    }

    void addListener(ImageButton hole)
    {
        hole.addListener(new ClickListener()
        {
            @Override
            public boolean touchDown(InputEvent event, float x, float y, int pointer, int button)
            {
                event.getListenerActor().remove();
                waterfallController.removeWaterfall();
                GameManager.getInstance().drawNext = true;
                // TODO: si rompe se aggiungi questa linea -> event.getListenerActor().getStage().dispose();
                return true;
            }

            @Override
            public void touchUp(InputEvent event, float x, float y, int pointer, int button)
            {
                String playerLost = event.getListenerActor().getName();
                String playerWin = playerLost.equals("1") ? "2" : "1";

                System.out.println("Player " + playerWin + " has won!");

                // gameMain.setScreen(new MainMenu(gameMain)); TODO: UNCOMMENT
                if (!GameManager.getInstance().isPaused)
                {
                    GameManager.getInstance().isPaused = true;
                    createGameOverPanel();
                }
            }
        });
    }

    public Stage getStage()
    {
        return stage;
    }

    private float randomBetweenNumbers(float min, float max)
    {
        return random.nextFloat() * (max - min) + min;
    }

    public void createGameOverPanel()
    {
        gameOverPanel = new Image(new Texture("Pause Panel And Buttons/Pause Panel.png"));
        playAgainBtn = new ImageButton(new SpriteDrawable(new Sprite(new Texture("Pause Panel And Buttons/Restart.png"))));
        quitBtn = new ImageButton(new SpriteDrawable(new Sprite(new Texture("Pause Panel And Buttons/Quit.png"))));

        gameOverPanel.setPosition(GameInfo.W / 2f, GameInfo.H / 2f, Align.center);
        playAgainBtn.setPosition(GameInfo.W / 2f, GameInfo.H / 2f + 10f, Align.center);
        quitBtn.setPosition(GameInfo.W / 2f, GameInfo.H / 2f - 100f, Align.center);

        createLabel();

        Table table = new Table();

        table.row();
        table.top();
        table.setFillParent(true);

        table.row();
        table.add(winnerLabel).padTop(270f);
        stage.addActor(table);

        playAgainBtn.addListener(new ChangeListener()
        {
            @Override
            public void changed(ChangeEvent event, Actor actor)
            {

                gameMain.setScreen(new GamePlay(gameMain));
                GameManager.getInstance().isPaused = false;
                GameManager.getInstance().drawNext = true;
            }
        });

        quitBtn.addListener(new ChangeListener()
        {
            @Override
            public void changed(ChangeEvent event, Actor actor)
            {

                gameMain.setScreen(new MainMenu(gameMain));
                GameManager.getInstance().isPaused = false;
                GameManager.getInstance().drawNext = true;

            }
        });

        stage.addActor(gameOverPanel);
        stage.addActor(playAgainBtn);
        stage.addActor(quitBtn);
    }

    void createLabel()
    {
        FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("Fonts/dirty-old-town.regular.ttf"));
        FreeTypeFontGenerator.FreeTypeFontParameter parameter = new FreeTypeFontGenerator.FreeTypeFontParameter();

        parameter.size = 55;

        BitmapFont font = generator.generateFont(parameter);

        winnerLabel = new Label("The winner is player " + GameManager.getInstance().player, new Label.LabelStyle(font, Color.BLACK));

    }

    public WaterfallController getWaterfallController()
    {
        return waterfallController;
    }
}
