// package org.openjfx;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.layout.HBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebEvent;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;

public class Main extends Application {

    private Bridge bridge = new Bridge();
    private static final String BRIDGE_NAME = "JavaBridge";

    private static final String HTML =
            " <script>try{"
                    + BRIDGE_NAME + ".log('On content load');" // try to log a message on content load
                    + "} catch(err) {alert(err.message);}" // alert message if bridge is not yet defined
                    + "</script>"
                    + "<button onclick=\"" + BRIDGE_NAME + ".log('Button clicked')\">Log Click</button>";

    @Override
    public void start(Stage stage) {
        // Setup the Webview
        WebView webView = new WebView();
        webView.setPrefSize(100,100);
        WebEngine webEngine = webView.getEngine();
        webEngine.setOnAlert(Main::showAlert);

        // Setup the bridge
        webEngine.getLoadWorker().stateProperty().addListener((observable, oldState, newState) -> {
            JSObject window = (JSObject) webEngine.executeScript("window");
            window.setMember(BRIDGE_NAME, bridge);
        });

        // Load button, press twice or more to see the bug
        Button button = new Button("Load content");
        button.setOnAction(actionEvent -> {
            webEngine.loadContent(HTML);
        });

        // Setup stage and scene
        HBox hbox = new HBox(button, webView);
        Scene scene = new Scene(hbox);
        stage.setScene(scene);
        stage.show();
    }

    // The Java bridge. Has a "log" method.
    public static class Bridge {
        public void log(String msg) {
            System.out.println("Invoked from JavaScript: " + msg);
        }
    }

    // Shows the alert, used in JS catch statement
    private static void showAlert(WebEvent<String> event) {
        javafx.scene.control.Dialog<ButtonType> alert = new javafx.scene.control.Dialog<>();
        alert.getDialogPane().setContentText(event.getData());
        alert.getDialogPane().getButtonTypes().add(ButtonType.OK);
        alert.showAndWait();
    }

    public static void main(String[] args) {
        launch(args);
    }

}