package com.example.happy_bird;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.*;
import javafx.scene.text.TextAlignment;
import javafx.stage.Stage;

public class HappyBirdMain extends Application {

    MariaDB datenbank = new MariaDB();

    /*Panes erstellen und zuweisen*/
    private final Pane pane = new Pane();
    private final Pane pause = new Pane();

    /*Scene erstellen und zuweisen*/
    private final Scene scene = new Scene(pane, 800, 700);

    /*Labels erstellen und zuweisen*/
    private final Label nameLabel = new Label("NAME");
    private final Label acronymLabel = new Label("KÜRZEL");
    private final Label headline = new Label("HAPPY BIRD");
    private final Label soundLabel = new Label("SOUND");
    private final Label currentScoreLabel = new Label("SCORE");
    private final Label highscoreLabel = new Label("HIGHSCORE");
    private final Label pauseMenuLabel = new Label("PAUSE");
    private final Label soundLabelPause = new Label("SOUND");

    /*Labels in Arrays speichern*/
    private final Label[] labels = {nameLabel, acronymLabel, soundLabel, currentScoreLabel, highscoreLabel};
    private final Label[] headlineLabels = {headline};

    /*Buttons erstellen und zuweisen*/
    private final Button startButton = new Button("START");
    private final Button highscoresButton = new Button("HIGHSCORES");
    private final Button settingsButton = new Button("EINSTELLUNGEN");
    private final Button startGameButton = new Button("SPIEL STARTEN");
    private final Button menuButton = new Button("ZURÜCK");
    private final Button pauseButton = new Button("PAUSE");
    private final Button continueButton = new Button("WEITERSPIELEN");
    private final Button settingsButtonPause = new Button("EINSTELLUNGEN");
    private final Button menuButtonPause = new Button("HAUPTMENÜ");
    private final Button backButtonPause = new Button("ZURÜCK");

    /*Buttons in Arrays speichern*/
    private final Button[] buttons = {startButton, highscoresButton, settingsButton, startGameButton, menuButton, pauseButton, continueButton, settingsButtonPause, menuButtonPause, backButtonPause};
    private final Button[] pauseButtons = {continueButton, settingsButtonPause, menuButtonPause, backButtonPause};

    /*Textfelder erstellen und zuweisen*/
    private final TextField name = new TextField();
    private final TextField acronym = new TextField();

    /*Textfelder in Arrays speichern*/
    private final TextField[] inputFields = {name, acronym};

    /*Slider erstellen und zuweisen*/
    private final Slider soundSlider = new Slider();
    private final Slider soundSliderPause = new Slider();

    /*Bilder*/
    private final Image bird = new Image("file:src/main/resources/com/example/happy_bird/pics/bird.png", 50, 35, false, false);

    private final Image upperPipe = new Image("file:src/main/resources/com/example/happy_bird/pics/PipeOben.png", 86, 300, false, false);
    private final Image lowerPipe = new Image("file:src/main/resources/com/example/happy_bird/pics/PipeUnten.png", 86, 300, false, false);

    /*Variablen für den Spielverlauf*/
    //menuScreenRunning: das Hauptmenü ist aufgerufen
    private boolean menuScreenRunning;
    //gameRunning: das Spiel läuft/ GameScreen ist aufgerufen
    private boolean gameRunning;



    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage stage) {

        stage.setTitle("Happy Bird");
        stage.setScene(scene);

        generateMenueScene();

        /*ClickEvents:*/
        startButton.setOnAction(event -> startButtonClick());

        settingsButton.setOnAction(event -> settingsButtonClick());

        highscoresButton.setOnAction(event -> highscoresButtonClick());

        menuButton.setOnAction(event -> menuButtonClick());

        startGameButton.setOnAction(event ->  {
            gameRunning = true;
            startGameButtonClick();
        });

        stage.show();
    }


    public void generateMenueScene() {
        menuScreenRunning = true;

        /*Bild für Hintergrund erstellen:*/
        Image image = new Image("file:src/main/resources/com/example/happy_bird/pics/Background.png");

        /*Hintergrund erstellen:*/
        BackgroundImage backgroundImage = new BackgroundImage(
                image,
                BackgroundRepeat.NO_REPEAT,
                BackgroundRepeat.NO_REPEAT,
                BackgroundPosition.DEFAULT,
                BackgroundSize.DEFAULT
        );

        /*Hintergrund zu Pane hinzufügen:*/
        Background background = new Background(backgroundImage);
        pane.setBackground(background);

        /*Labels formatieren:*/
        labelsFormating(labels, pane);
        headlineFormating(headlineLabels, pane);

        /*Überschrift umbenennen, falls aus anderem Screen*/
        headline.setText("HAPPY BIRD");

        /*alle labels an ihre Stelle:*/
        int yPositionLabels = 225;
        for (Label label : labels) {
            label.setLayoutX(275);
            label.setLayoutY(yPositionLabels);
            yPositionLabels += 150;
        }

        /*headline an ihre Stelle:*/
        headline.setLayoutX(250);
        headline.setLayoutY(100);
        headline.setVisible(true);

        /*soundLabel an seine Stelle:*/
        soundLabel.setLayoutY(225);

        /*Buttons formatieren:*/
        buttonsFormating(buttons, pane);

        /*alle Buttons an ihre Stelle:*/
        int yPositionButtons = 225;
        for (Button button : buttons) {
            button.setLayoutX(300);
            button.setLayoutY(yPositionButtons);
            yPositionButtons += 100;
            button.setVisible(true);
        }

        /*menuButton an seine Stelle und vorerst ausblenden:*/
        menuButton.setLayoutX(575);
        menuButton.setLayoutY(625);
        menuButton.setVisible(false);

        /*startGameButton unsichtbar*/
        startGameButton.setVisible(false);

        /*continueButton unsichtbar*/
        continueButton.setVisible(false);

        /*settingsButtonPause unsichtbar*/
        settingsButtonPause.setVisible(false);

        /*Textfelder formatieren:*/
        textfieldsFormating(inputFields, pane);

        /*Textfelder an ihre Position:*/
        int yPositionInputFields = 290;
        for (TextField feld : inputFields) {
            feld.setLayoutX(275);
            feld.setLayoutY(yPositionInputFields);
            yPositionInputFields += 150;
        }

        /*SoundSlicer anpassen:*/
        soundSliderFormating(soundSlider, pane);
    }

    /**
     * Generiert den GameScreen durch Ausblenden und
     * Sichtbarmachen der richtigen Buttons, Labels, ...
     */
    public void generateGameScreen() {
        menuScreenRunning = false;

        /*Headline-Label umbenennen*/
        nameLabel.setText("KÜRZEL: " + acronym.getText());

        /*Textfelder ausblenden*/
        for(TextField feld : inputFields) {
            feld.setVisible(false);
        }

        /*Labels ausblenden*/
        for (Label label : labels ) {
            label.setVisible(false);
        }
        headline.setVisible(false);

        /*nameLabel positionieren und sichtbar machen*/
        nameLabel.setLayoutX(10);
        nameLabel.setLayoutY(10);
        nameLabel.setVisible(true);

        /*currentScoreLabel positionieren und sichtbar machen*/
        currentScoreLabel.setLayoutX(540);
        currentScoreLabel.setLayoutY(10);
        currentScoreLabel.setVisible(true);

        /*highscoreLabel positionieren und sichtbar machen*/
        highscoreLabel.setLayoutX(540);
        highscoreLabel.setLayoutY(70);
        highscoreLabel.setVisible(true);

        /*Pause-Button positionieren und sichtbar machen*/
        pauseButton.setLayoutX(575);
        pauseButton.setLayoutY(625);
        pauseButton.setVisible(true);

        /*übrige Buttons ausblenden*/
        startGameButton.setVisible(false);
        menuButton.setVisible(false);

        /*Vogel hinzufügen, bisher nur als Bild*/
        ImageView birdView = new ImageView(bird);
        pane.getChildren().add(birdView);
        birdView.setLayoutY(325);
        birdView.setLayoutX(50);

        /*Pipes oben, unten hinzufügen, bisher nur als Bild*/
        ImageView upperPipeView = new ImageView(upperPipe);
        pane.getChildren().add(upperPipeView);
        upperPipeView.setLayoutX(400);
        upperPipeView.setLayoutY(0);

        ImageView lowerPipeView = new ImageView(lowerPipe);
        pane.getChildren().add(lowerPipeView);
        lowerPipeView.setLayoutX(400);
        lowerPipeView.setLayoutY(430);
    }

    /***
     * Formatiert alle Buttons und fügt sie der Pane hinzu
     * @param buttons   ButtonArray mit allen Arrays
     * @param pane      Pane, auf der die Buttons angezeigt werden
     */
    public void buttonsFormating(Button[] buttons, Pane pane) {
        for (Button button : buttons) {
            button.setPrefSize(200, 50);

            button.setStyle("-fx-background-color: #e86000; " +
                    "-fx-text-fill: #FFFFFF; " +
                    "-fx-font-size: 20px; " +
                    "-fx-border-width: 5px;" +
                    "-fx-border-color: #FFFFFF;" +
                    "-fx-font-weight: bold;" +
                    "-fx-border-radius: 15px;" +
                    "-fx-background-radius: 20px;");

            pane.getChildren().add(button);
        }
    }

    /***
     * Formatiert alle kleinen Labels (keine Überschrift) und fügt sie der Pane hinzu
     * @param labels    LabelArray mit allen Labels
     * @param pane      Pane, auf der die Labels angezeigt werden
     */
    public void labelsFormating(Label[] labels, Pane pane) {
        for (Label label : labels) {
            label.setPrefSize(250, 50);

            label.setStyle("-fx-background-color: #DED894; " +
                    "-fx-text-fill: #000000; " +
                    "-fx-font-size: 20px; " +
                    "-fx-border-width: 5px;" +
                    "-fx-border-color: #543847;" +
                    "-fx-font-weight: bold;" +
                    "-fx-alignment: center;" +
                    "-fx-background-radius: 20px;" +
                    "-fx-border-radius: 15px;");

            pane.getChildren().add(label);

            label.setVisible(false);
        }
    }

    /***
     * Formatiert alle Überschriften-Labels und fügt sie der Pane hinzu
     * @param labels    LabelArray mit Überschriften-Labels
     * @param pane      Pane, auf der die Labels angezeigt werden
     */
    public void headlineFormating(Label[] labels, Pane pane) {
        for (Label label : labels) {
            label.setPrefSize(300, 75);
            label.setTextAlignment(TextAlignment.CENTER);

            label.setStyle("-fx-background-color: #DED894; " +
                    "-fx-text-fill: #000000; " +
                    "-fx-font-size: 35px; " +
                    "-fx-border-width: 5px;" +
                    "-fx-border-color: #543847;" +
                    "-fx-font-weight: bold;" +
                    "-fx-alignment: center;" +
                    "-fx-background-radius: 20px;" +
                    "-fx-border-radius: 15px;");

            pane.getChildren().add(label);
        }
    }

    /***
     * Formatiert alle Textfelder und fügt sie der Pane hinzu
     * @param textfields    TextFieldArray mit allen Textfeldern
     * @param pane          Pane, auf der die Textfelder angezeigt werden
     */
    public void textfieldsFormating(TextField[] textfields, Pane pane) {
        for (TextField field : textfields) {
            field.setPrefSize(250, 50);
            field.setStyle("-fx-font-size: 20px;" +
                    "-fx-font-weight: bold;");

            pane.getChildren().add(field);

            field.setVisible(false);
        }
    }

    /***
     * Formatiert den soundSlider und fügt ihn der Pane hinzu
     * @param slider    SoundSlider
     * @param pane      Pane, auf der der Slider angezeigt wird
     */
    public void soundSliderFormating(Slider slider, Pane pane) {
        slider.setPrefSize(200, 5);
        slider.setLayoutX(300);
        slider.setLayoutY(295);

        pane.getChildren().add(slider);

        slider.setVisible(false);
    }

    /***
     * Formatiert den PauseScreen
     */
    public void pauseScreenFormating() {
        /*pause-Pane formatieren*/
        pause.setPrefSize(400, 400);
        pause.setLayoutX(200);
        pause.setLayoutY(150);
        pause.setStyle("-fx-background-color: #DED894; " +
                "-fx-border-width: 5px;" +
                "-fx-border-color: #543847;" +
                "-fx-border-radius: 15px;" +
                "-fx-background-radius: 20px;");

        /*pauseMenuLabel formatieren*/
        pauseMenuLabel.setPrefSize(300,50);
        pauseMenuLabel.setLayoutX(50);
        pauseMenuLabel.setLayoutY(10);
        pauseMenuLabel.setStyle("-fx-background-color: #DED894; " +
                "-fx-text-fill: #000000; " +
                "-fx-font-size: 35px; " +
                "-fx-font-weight: bold;" +
                "-fx-alignment: center;");

        /*soundLabelPause formatieren*/
        soundLabelPause.setPrefSize(100, 50);
        soundLabelPause.setLayoutX(150);
        soundLabelPause.setLayoutY(100);
        soundLabelPause.setStyle("-fx-background-color: #DED894; " +
                "-fx-text-fill: #000000; " +
                "-fx-font-size: 20px; " +
                "-fx-font-weight: bold;" +
                "-fx-alignment: center;");
    }

    /***
     * Hauptmenü wird ausgeblendet, Nameneingabe folgt
     */
    public void startButtonClick() {
        /*Überschrift umbenennen*/
        headline.setText("START");

        /*alle Buttons ausblenden*/
        for(Button button : buttons) {
            button.setVisible(false);
        }

        /*gebrauchte Buttons einblenden, ggf. anpassen*/
        menuButton.setVisible(true);
        startGameButton.setVisible(true);
        startGameButton.setLayoutY(520);

        /*Textfelder einblenden*/
        for(TextField feld : inputFields) {
            feld.setVisible(true);
        }

        /*Labels einblenden*/
        for (Label label : labels ) {
            label.setVisible(true);
        }

        /*nicht verwendete Labels ausblenden*/
        highscoreLabel.setVisible(false);
        currentScoreLabel.setVisible(false);
        soundLabel.setVisible(false);

        /*Click-Events*/
        startGameButton.setOnAction(event -> startGameButtonClick());
    }


    /***
     * Hauptmenü wird ausgeblendet, Einstellungen folgen
     */
    public void settingsButtonClick() {
        /*Überschrift umbenennen*/
        headline.setText("EINSTELLUNGEN");

        /*nicht verwendete Buttons/ Labels ausblenden, gebrauchte einblenden*/
        startButton.setVisible(false);
        highscoresButton.setVisible(false);
        settingsButton.setVisible(false);
        menuButton.setVisible(true);
        soundSlider.setVisible(true);
        soundLabel.setVisible(true);
    }

    /***
     * Hauptmenü wird ausgeblendet, Einstellungen folgen
     */
    public void settingsButtonPauseClick() {
        /*Überschrift umbenennen*/
        pauseMenuLabel.setText("EINSTELLUNGEN");

        /*alle Buttons ausblenden*/
        for(Button button : pauseButtons) {
            button.setVisible(false);
        }

        /*gebrauchte Buttons einblenden und anpassen*/
        backButtonPause.setVisible(true);
        backButtonPause.setLayoutY(300);

        /*soundSliderPause anpassen und einblenden*/
        soundSliderPause.setPrefSize(200, 5);
        soundSliderPause.setLayoutX(100);
        soundSliderPause.setLayoutY(150);
        soundSliderPause.setVisible(true);

        /*soundLabelPause einblenden*/
        soundLabelPause.setVisible(true);

        /*Click-Events*/
        backButtonPause.setOnAction(event -> {
            /*Überschrift umbenennen*/
            pauseMenuLabel.setText("PAUSE");

            /*alle Buttons einblenden*/
            for(Button button : pauseButtons) {
                button.setVisible(true);
            }

            /*nicht verwendete Buttons ausblenden*/
            backButtonPause.setVisible(false);
            soundSliderPause.setVisible(false);
            soundLabelPause.setVisible(false);
        });
    }

    /***
     * Hauptmenü wird ausgeblendet, Highscores folgen
     */
    public void highscoresButtonClick() {
        /*Überschrift umbenennen*/
        headline.setText("HIGHSCORES");

        /*nicht verwendete Buttons ausblenden, verwendete einblenden*/
        startButton.setVisible(false);
        highscoresButton.setVisible(false);
        settingsButton.setVisible(false);
        menuButton.setVisible(true);
    }

    /***
     * Nameneingabe, Einstellungen und Highscores werden ausgeblendet
     * Erneutes Anzeigen des Hauptmenüs
     */
    public void menuButtonClick() {
        /*Überschrift umbenennen*/
        headline.setText("HAPPY BIRD");

        /*nicht verwendete Buttons ausblenden, verwendete einblenden*/
        startButton.setVisible(true);
        highscoresButton.setVisible(true);
        settingsButton.setVisible(true);
        menuButton.setVisible(false);
        startGameButton.setVisible(false);

        /*soundSlider ausblenden*/
        soundSlider.setVisible(false);

        /*soundLabel ausblenden*/
        //soundLabel.setVisible(false);

        /*Textfelder ausblenden*/
        for(TextField feld : inputFields) {
            feld.setVisible(false);
        }

        /*alle Labels ausblenden*/
        for (Label label : labels ) {
            label.setVisible(false);
        }
    }

    /***
     * Startet Spiel nach Namenseingabe
     */
    public void startGameButtonClick() {
        generateGameScreen();

        /*Klick auf den Pause-Button, um das Pause-Menü aufzurufen*/
        pauseButton.setOnAction(event -> {
            if(!menuScreenRunning) {
                pauseButtonClick(gameRunning);
                gameRunning = !gameRunning;
            }
        });

        /*ESC-Tast drücken, um das Pause-Menü aufzurufen*/
        scene.setOnKeyPressed(e -> {
            if(e.getCode() == KeyCode.ESCAPE && !menuScreenRunning) {
                pauseButtonClick(gameRunning);
                gameRunning = !gameRunning;
            }
        });
    }

    /***
     * Zurück zum Spiel aus dem PauseScreen heraus
     */
    public void continueButtonClick() {
        /*pauseButton einblenden*/
        pauseButton.setVisible(true);

        /*PauseScreen ausblenden*/
        pause.setVisible(false);

        /*Vom PauseScreen entfernen*/
        pause.getChildren().clear();
        pane.getChildren().remove(pause);

        /*gameRunning auf false setzen, da sonst 2x Click auf Pause-Button bzw. ESC*/
        gameRunning = false;
    }

    /***
     * alles vom pane entfernen, da als nächstes zum Hauptmenü
     */
    private void menuButtonPauseClick() {
        /*alles vom pauseScreen entfernen*/
        pause.getChildren().clear();

        /*pause von pane entfernen*/
        pane.getChildren().clear();

        /*gameRunning auf false, da zurück zum Hauptmenü*/
        gameRunning = false;
    }

    /***
     * Ruft das Pause-Menü im Spiel auf oder blendet es wieder aus
     */
    public void pauseButtonClick(Boolean gameRuns) {
        pauseScreenFormating();

        /*PauseScreen aufrufen, wenn das Spiel läuft, sonst wieder ausblenden*/
        if(!gameRuns) {
            pauseButton.setVisible(false);

            /*PauseScreen einblenden*/
            pause.setVisible(true);

            /*Buttons anpassen, zum pauseScreen hinzufügen und einblenden*/
            int yPosition = 100;
            for(Button button : pauseButtons) {
                button.setLayoutX(100);
                button.setLayoutY(yPosition);
                yPosition += 100;
                pause.getChildren().add(button);
                button.setVisible(true);
            }

            /*backButtonPause vorerst ausblenden und zu pause hinzufügen*/
            backButtonPause.setVisible(false);
            pause.getChildren().add(pauseMenuLabel);

            /*soundSliderPause vorerst ausblenden und zu pause hinzufügen*/
            soundSliderPause.setVisible(false);
            pause.getChildren().add(soundSliderPause);

            /*soundLabelPause vorerst ausblenden und zu pause hinzufügen*/
            soundLabelPause.setVisible(false);
            pause.getChildren().add(soundLabelPause);

            /*pause zu pane hinzufügen*/
            pane.getChildren().add(pause);

            /*ClickEvents*/
            continueButton.setOnAction(event -> continueButtonClick());

            menuButtonPause.setOnAction(event -> {
                menuButtonPauseClick();
                generateMenueScene();
            });

            settingsButtonPause.setOnAction(event -> settingsButtonPauseClick());
        } else {
            /*pauseButton einblenden*/
            pauseButton.setVisible(true);

            /*PauseScreen ausblenden*/
            pause.setVisible(false);

            /*alles vom PauseScreen entfernen*/
            pause.getChildren().clear();

            /*pause von pane entfernen*/
            pane.getChildren().remove(pause);
        }
    }
}