import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.stage.Stage;

/**
 * A GUI for the Game of Fifteen.
 *
 * @author Drue Coles
 */
public class FifteenPlayer extends Application {

    private final Fifteen game = new Fifteen();
    private final Button[][] buttons = new Button[Fifteen.ROWS][Fifteen.COLS];

    @Override
    public void start(Stage primaryStage) {
        Pane root = new Pane();
        Scene scene = new Scene(root);

        // The buttons are arranged in a grid pane.
        GridPane gridPane = new GridPane();
        root.getChildren().add(gridPane);
        gridPane.setStyle("-fx-background-color: BLACK");
        gridPane.setHgap(3);
        gridPane.setVgap(3);

        // Each button displays a tile number. Clicking on a button causes a 
        // move to be made in the game by sliding the corresponding tile. 
        class ButtonHandler implements EventHandler<ActionEvent> {

            @Override
            public void handle(ActionEvent event) {
                Button button = (Button) event.getSource();
                int tile = Integer.parseInt(button.getText());
                game.slide(tile);
                setButtonText();

                if (game.over()) {
                    Alert alert = new Alert(AlertType.INFORMATION);
                    alert.setTitle("GAME OVER");
                    alert.setHeaderText("You have solved the puzzle!");
                    alert.setContentText("Goodbye.");
                    primaryStage.setAlwaysOnTop(false);
                    alert.showAndWait();
                    Platform.exit();
                }
            }
        }
        ButtonHandler buttonHandler = new ButtonHandler();

        // Create the buttons, style them, and register event handlers.
        Font font = Font.font("Monotype", FontWeight.BOLD, 28);
        String buttonStyle = "-fx-border-color: SLATEGRAY; -fx-border-width: 2";
        for (int i = 0; i < buttons.length; i++) {
            for (int j = 0; j < buttons[i].length; j++) {
                buttons[i][j] = new Button();
                buttons[i][j].setFont(font);
                buttons[i][j].setPrefSize(120, 120);
                buttons[i][j].setStyle(buttonStyle);
                buttons[i][j].setOnAction(buttonHandler);
                gridPane.add(buttons[i][j], j, i);
            }
        }
        setButtonText();

        primaryStage.setTitle("Fifteen Puzzle");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * Sets the text on each button to corresponding tile number.
     */
    private void setButtonText() {
        for (int i = 0; i < buttons.length; i++) {
            for (int j = 0; j < buttons[i].length; j++) {
                if (game.tileAt(i, j) == Fifteen.EMPTY_SPACE) {
                    buttons[i][j].setVisible(false);
                } else {
                    buttons[i][j].setVisible(true);
                    buttons[i][j].setText("" + game.tileAt(i, j));
                }
            }
        }
    }

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