/*
 * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package goryachev.apps;

import java.awt.EventQueue;

import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import javafx.application.Application;
import javafx.application.Platform;
import javafx.embed.swing.SwingNode;
import javafx.geometry.Orientation;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.SplitPane;
import javafx.scene.control.TextArea;
import javafx.scene.control.ToolBar;
import javafx.scene.layout.BorderPane;
import javafx.scene.text.Font;
import javafx.stage.Stage;

/**
 * Many different Unicode scripts in TextArea/JTextArea.
 */
public class UnicodeFailAll extends Application {
    protected TextArea textField;
    protected JTextArea jtextArea;
    
    public static void main(String[] args) {
        Application.launch(UnicodeFailAll.class, args);
    }

    @Override
    public void start(Stage stage) throws Exception {
        String text = generateText();
        
        textField = new TextArea(text);
//        textField.setStyle("-fx-font-size:150%;");
        
        BorderPane rightPane = new BorderPane();

        SwingNode swingNode = new SwingNode();
        EventQueue.invokeLater(() -> {
            jtextArea = new JTextArea(text);
            swingNode.setContent(new JScrollPane(jtextArea));
            
            Platform.runLater(() -> {
                rightPane.setCenter(swingNode);
            });
        });

        SplitPane split = new SplitPane(textField, rightPane);
        split.setOrientation(Orientation.HORIZONTAL);
        
        ComboBox<String> fontField = new ComboBox<>();
        fontField.getSelectionModel().selectedItemProperty().addListener((s,p,font) -> {
           setFont(font); 
        });
        Platform.runLater(() -> {
            populateFonts(fontField);
        });
        
        ToolBar tb = new ToolBar(
                fontField
        );

        BorderPane bp = new BorderPane();
        bp.setTop(tb);
        bp.setCenter(split);
        
        Scene scene = new Scene(bp);
        
        stage.setScene(scene);
        stage.setTitle("Unicode Failure 2 " + System.getProperty("java.version"));
        stage.setWidth(1200);
        stage.setHeight(1200);
        stage.show();
    }
    
    private void populateFonts(ComboBox c) {
        // https://docs.oracle.com/javase/8/javafx/api/javafx/scene/doc-files/cssref.html#fontprops
        c.getItems().setAll(
            "system", // not in CSS reference
            "serif",
            "sans-serif",
            "cursive",
            "fantasy",
            "monospace"
        );
        c.getItems().addAll(Font.getFontNames());
    }

    private void setFont(String fontFamily) {
        Font f = new Font(fontFamily, 12);
        textField.setFont(f);
        
        String name = f.getName();
        int size = (int)f.getSize();

        EventQueue.invokeLater(() -> {
            java.awt.Font ff = new java.awt.Font(name, java.awt.Font.PLAIN, size);
            jtextArea.setFont(ff);
        });
    }

    private String generateText() {
        // better list https://en.wikipedia.org/wiki/List_of_writing_systems
        StringBuilder sb = new StringBuilder();
        t(sb, "Arabic", "\u0627\u0644\u0639\u0631\u0628\u064a\u0629");
        t(sb, "Akkadian", "\ud808\udc1d\ud808\udd57\ud808\udc7a\ud808\udf11");
        t(sb, "Armenian", "\u0570\u0561\u0575\u0565\u0580\u0567\u0576/\u0570\u0561\u0575\u0565\u0580\u0565\u0576");
        t(sb, "Assamese", "\u0985\u09b8\u09ae\u09c0\u09af\u09bc\u09be");
        t(sb, "Awadhi", "\u0905\u0935\u0927\u0940/\u0914\u0927\u0940");
        t(sb, "Bagheli", "\u092c\u0918\u0947\u0932\u0940");
        t(sb, "Bagri", "\u092c\u093e\u0917\u0921\u093c\u0940, \u0628\u0627\u06af\u0691\u06cc");
        t(sb, "Bengali", "\u09ac\u09be\u0982\u09b2\u09be");
        t(sb, "Bhojpuri", "\ud804\udca6\ud804\udcb7\ud804\udc94\ud804\udca3\ud804\udcb3\ud804\udca9\ud804\udcb2");
        t(sb, "Braille", "\u2803\u2817\u2807");
        t(sb, "Bundeli", "\u092c\u0941\u0928\u094d\u0926\u0947\u0932\u0940");
        t(sb, "Burmese", "\u1019\u103c\u1014\u103a\u1019\u102c");
        t(sb, "Cherokee", "\u13e3\u13b3\u13a9 \u13a6\u13ec\u13c2\u13af\u13cd\u13d7");
        t(sb, "Chhattisgarhi", "\u091b\u0924\u094d\u0924\u0940\u0938\u0917\u0922\u093c\u0940, \u0b1b\u0b24\u0b3f\u0b36\u0b17\u0b21\u0b3c\u0b3f, \u0b32\u0b30\u0b3f\u0b06");
        t(sb, "Chinese", "\u4e2d\u6587");
        t(sb, "Czech", "\u010ce\u0161tina");
        t(sb, "Devanagari", "\u0926\u0947\u0935\u0928\u093e\u0917\u0930\u0940");
        t(sb, "Dhundhari", "\u0922\u0942\u0923\u094d\u0922\u093e\u0921\u093c\u0940/\u0aa2\u0ac2\u0aa3\u0acd\u0aa2\u0abe\u0aa1\u0abc\u0ac0");
        t(sb, "Farsi", "\u0641\u0627\u0631\u0633\u06cc");
        t(sb, "Garhwali", "\u0917\u0922\u093c\u0935\u0933\u093f");
        t(sb, "Ge\u02bdez", "\u130d\u12d5\u12dd");
        t(sb, "Greek", "\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac");
        t(sb, "Georgian", "\u10e5\u10d0\u10e0\u10d7\u10e3\u10da\u10d8");
        t(sb, "Gujarati", "\u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0");
        t(sb, "Harauti", "\u0939\u093e\u0921\u093c\u094c\u0924\u0940, \u0939\u093e\u0921\u093c\u094b\u0924\u0940");
        t(sb, "Haryanvi", "\u0939\u0930\u092f\u093e\u0923\u0935\u0940");
        t(sb, "Hebrew", "\u05e2\u05d1\u05e8\u05d9\u05ea");
        t(sb, "Hindi", "\u0939\u093f\u0928\u094d\u0926\u0940");
        t(sb, "Inuktitut", "\u1403\u14c4\u1483\u144e\u1450\u1466");
        t(sb, "Japanese", "\u65e5\u672c\u8a9e \u304b\u306a \u30ab\u30ca");
        t(sb, "Kangri", "\u0915\u093e\u0902\u0917\u0921\u093c\u0940");
        t(sb, "Kannada", "\u0c95\u0ca8\u0ccd\u0ca8\u0ca1");
        t(sb, "Khmer", "\u1781\u17d2\u1798\u17c2\u179a");
        t(sb, "Khortha", "\u0916\u094b\u0930\u0920\u093e");
        t(sb, "Korean", "\ud55c\uad6d\uc5b4");
        t(sb, "Kumaoni", "\u0915\u0941\u092e\u093e\u090a\u0901\u0928\u0940");
        t(sb, "Magahi", "\ud804\udca7\ud804\udc8f\ud804\udcaf\ud804\udcb2/\ud804\udca7\ud804\udc8f\ud804\udca1\ud804\udcb2");
        t(sb, "Maithili", "\u092e\u0948\u0925\u093f\u0932\u0940");
        t(sb, "Malayalam", "\u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02");
        t(sb, "Malvi", "\u092e\u093e\u0933\u0935\u0940 \u092d\u093e\u0937\u093e / \u0aae\u0abe\u0ab3\u0ab5\u0ac0 \u0aad\u0abe\u0ab7\u0abe");
        t(sb, "Marathi", "\u092e\u0930\u093e\u0920\u0940");
        t(sb, "Marwari,", "\u092e\u093e\u0930\u0935\u093e\u0921\u093c\u0940");
        t(sb, "Meitei", "\uabc3\uabe9\uabc7\uabe9\uabc2\uabe3\uabdf");
        t(sb, "Mewari", "\u092e\u0947\u0935\u093e\u0921\u093c\u0940/\u0aae\u0ac7\u0ab5\u0abc\u0abe\u0aa1\u0abc\u0ac0");
        t(sb, "Mongolian", "\u1828\u1822\u1837\u1824\u182d\u1824");
        t(sb, "Nimadi", "\u0928\u093f\u092e\u093e\u0921\u093c\u0940");
        t(sb, "Odia", "\u0b13\u0b21\u0b3c\u0b3f\u0b06");
        t(sb, "Punjabi", "\u0a2a\u0a70\u0a1c\u0a3e\u0a2c\u0a40\u067e\u0646\u0658\u062c\u0627\u0628\u06cc");
        t(sb, "Pahari", "\u092a\u0939\u093e\u0921\u093c\u0940 \u067e\u06c1\u0627\u0691\u06cc ");
        t(sb, "Rajasthani", "\u0930\u093e\u091c\u0938\u094d\u0925\u093e\u0928\u0940");
        t(sb, "Russian", "\u0420\u0443\u0441\u0441\u043a\u0438\u0439");
        t(sb, "Sanskrit", "\u0938\u0902\u0938\u094d\u0915\u0943\u0924-, \u0938\u0902\u0938\u094d\u0915\u0943\u0924\u092e\u094d");
        t(sb, "Santali", "\u1c65\u1c5f\u1c71\u1c5b\u1c5f\u1c72\u1c64");
        t(sb, "Suret", "\u0723\u0718\u072a\u071d\u072c");
        t(sb, "Surgujia", "\u0938\u0930\u0917\u0941\u091c\u093f\u092f\u093e");
        t(sb, "Surjapuri", "\u0938\u0941\u0930\u091c\u093e\u092a\u0941\u0930\u0940, \u09b8\u09c1\u09b0\u099c\u09be\u09aa\u09c1\u09b0\u09c0");
        t(sb, "Tamil", "Tami\u1e3b");
        t(sb, "Telugu", "\u0c24\u0c46\u0c32\u0c41\u0c17\u0c41");
        t(sb, "Thaana", "\u078b\u07a8\u0788\u07ac\u0780\u07a8");
        t(sb, "Thai", "\u0e44\u0e17\u0e22");
        t(sb, "Tibetan", "\u0f56\u0f7c\u0f51\u0f0b");
        t(sb, "Tulu", "\u0ca4\u0cc1\u0cb3\u0cc1, \u0d24\u200d\u0d41\u0d33\u200d\u0d41");
        t(sb, "Turoyo", "\u071b\u0718\u072a\u071d\u0710");
        t(sb, "Ukrainian", "\u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430");
        t(sb, "Urdu", "\u0627\u0631\u062f\u0648");
        t(sb, "Vietnamese", "Ti\u1ebfng Vi\u1ec7t");
        return sb.toString();
    }

    private void t(StringBuilder sb, String name, String text) {
        sb.append(name);
        sb.append(": ");
        sb.append(text);
        sb.append(" (");
        native2ascii(sb, text);
        sb.append(") \n");
    }

    protected static void native2ascii(StringBuilder sb, String text) {
        for (char c : text.toCharArray()) {
            if (c < 0x20) {
                escape(sb, c);
            } else if (c > 0x7f) {
                escape(sb, c);
            } else {
                sb.append(c);
            }
        }
    }

    protected static void escape(StringBuilder sb, char c) {
        sb.append("\\u");
        sb.append(h(c >> 12));
        sb.append(h(c >> 8));
        sb.append(h(c >> 4));
        sb.append(h(c));
    }

    protected static char h(int d) {
        return "0123456789abcdef".charAt(d & 0x000f);
    }
}
