import { Store } from "../../Logic/UIEventSource"
import {
    DataDrivenPropertyValueSpecification,
    LayerSpecification,
    Map as MlMap,
    SymbolLayerSpecification,
} from "maplibre-gl"
import Locale from "../i18n/Locale"
import { Utils } from "../../Utils"

export class ProtomapsLanguageSupport {
    private _map: Store<MlMap>

    private static expressions: Record<
        string,
        (language: string) => DataDrivenPropertyValueSpecification<string>
    > = {
        places_country: (language) => [
            "format",
            ["coalesce", ["get", "name:" + language], ["get", "name:en"]],
            {},
        ],
        places_region: (language) => [
            "step",
            ["zoom"],
            ["get", "name:short"],
            6,
            [
                "case",
                [
                    "all",
                    ["any", ["has", "name"], ["has", "pgf:name"]],
                    ["!", ["any", ["has", "name2"], ["has", "pgf:name2"]]],
                    ["!", ["any", ["has", "name3"], ["has", "pgf:name3"]]],
                ],
                [
                    "case",
                    ["has", "script"],
                    [
                        "case",
                        ["any", ["is-supported-script", ["get", "name"]], ["has", "pgf:name"]],
                        [
                            "format",
                            ["coalesce", ["get", "name:" + language], ["get", "name:en"]],
                            {},
                            "\n",
                            {},
                            [
                                "case",
                                [
                                    "all",
                                    ["!", ["has", "name:" + language]],
                                    ["has", "name:en"],
                                    ["!", ["has", "script"]],
                                ],
                                "",
                                ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                            ],
                            {
                                "text-font": [
                                    "case",
                                    ["==", ["get", "script"], "Devanagari"],
                                    ["literal", ["Noto Sans Devanagari Regular v1"]],
                                    ["literal", ["Noto Sans Regular"]],
                                ],
                            },
                        ],
                        ["get", "name:en"],
                    ],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name"],
                            ["get", "name"],
                        ],
                        {},
                    ],
                ],
                [
                    "all",
                    ["any", ["has", "name"], ["has", "pgf:name"]],
                    ["any", ["has", "name2"], ["has", "pgf:name2"]],
                    ["!", ["any", ["has", "name3"], ["has", "pgf:name3"]]],
                ],
                [
                    "case",
                    ["all", ["has", "script"], ["has", "script2"]],
                    [
                        "format",
                        ["get", "name:" + language],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script2"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                    [
                        "case",
                        ["has", "script2"],
                        [
                            "format",
                            [
                                "coalesce",
                                ["get", "name:" + language],
                                ["get", "pgf:name"],
                                ["get", "name"],
                            ],
                            {},
                            "\n",
                            {},
                            ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                            {
                                "text-font": [
                                    "case",
                                    ["==", ["get", "script2"], "Devanagari"],
                                    ["literal", ["Noto Sans Devanagari Regular v1"]],
                                    ["literal", ["Noto Sans Regular"]],
                                ],
                            },
                        ],
                        [
                            "format",
                            [
                                "coalesce",
                                ["get", "name:" + language],
                                ["get", "pgf:name2"],
                                ["get", "name2"],
                            ],
                            {},
                            "\n",
                            {},
                            ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                            {
                                "text-font": [
                                    "case",
                                    ["==", ["get", "script"], "Devanagari"],
                                    ["literal", ["Noto Sans Devanagari Regular v1"]],
                                    ["literal", ["Noto Sans Regular"]],
                                ],
                            },
                        ],
                    ],
                ],
                [
                    "case",
                    ["all", ["has", "script"], ["has", "script2"], ["has", "script3"]],
                    [
                        "format",
                        ["get", "name:" + language],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script2"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name3"], ["get", "name3"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script3"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                    [
                        "case",
                        ["!", ["has", "script"]],
                        [
                            "format",
                            [
                                "coalesce",
                                ["get", "name:" + language],
                                ["get", "pgf:name"],
                                ["get", "name"],
                            ],
                            {},
                            "\n",
                            {},
                            ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                            {
                                "text-font": [
                                    "case",
                                    ["==", ["get", "script2"], "Devanagari"],
                                    ["literal", ["Noto Sans Devanagari Regular v1"]],
                                    ["literal", ["Noto Sans Regular"]],
                                ],
                            },
                            "\n",
                            {},
                            ["coalesce", ["get", "pgf:name3"], ["get", "name3"]],
                            {
                                "text-font": [
                                    "case",
                                    ["==", ["get", "script3"], "Devanagari"],
                                    ["literal", ["Noto Sans Devanagari Regular v1"]],
                                    ["literal", ["Noto Sans Regular"]],
                                ],
                            },
                        ],
                        ["!", ["has", "script2"]],
                        [
                            "format",
                            [
                                "coalesce",
                                ["get", "name:" + language],
                                ["get", "pgf:name2"],
                                ["get", "name2"],
                            ],
                            {},
                            "\n",
                            {},
                            ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                            {
                                "text-font": [
                                    "case",
                                    ["==", ["get", "script"], "Devanagari"],
                                    ["literal", ["Noto Sans Devanagari Regular v1"]],
                                    ["literal", ["Noto Sans Regular"]],
                                ],
                            },
                            "\n",
                            {},
                            ["coalesce", ["get", "pgf:name3"], ["get", "name3"]],
                            {
                                "text-font": [
                                    "case",
                                    ["==", ["get", "script3"], "Devanagari"],
                                    ["literal", ["Noto Sans Devanagari Regular v1"]],
                                    ["literal", ["Noto Sans Regular"]],
                                ],
                            },
                        ],
                        [
                            "format",
                            [
                                "coalesce",
                                ["get", "name:" + language],
                                ["get", "pgf:name3"],
                                ["get", "name3"],
                            ],
                            {},
                            "\n",
                            {},
                            ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                            {
                                "text-font": [
                                    "case",
                                    ["==", ["get", "script"], "Devanagari"],
                                    ["literal", ["Noto Sans Devanagari Regular v1"]],
                                    ["literal", ["Noto Sans Regular"]],
                                ],
                            },
                            "\n",
                            {},
                            ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                            {
                                "text-font": [
                                    "case",
                                    ["==", ["get", "script2"], "Devanagari"],
                                    ["literal", ["Noto Sans Devanagari Regular v1"]],
                                    ["literal", ["Noto Sans Regular"]],
                                ],
                            },
                        ],
                    ],
                ],
            ],
        ],
        places_locality: (language) => [
            "case",
            [
                "all",
                ["any", ["has", "name"], ["has", "pgf:name"]],
                ["!", ["any", ["has", "name2"], ["has", "pgf:name2"]]],
                ["!", ["any", ["has", "name3"], ["has", "pgf:name3"]]],
            ],
            [
                "case",
                ["has", "script"],
                [
                    "case",
                    ["any", ["is-supported-script", ["get", "name"]], ["has", "pgf:name"]],
                    [
                        "format",
                        ["coalesce", ["get", "name:" + language], ["get", "name:en"]],
                        {},
                        "\n",
                        {},
                        [
                            "case",
                            [
                                "all",
                                ["!", ["has", "name:" + language]],
                                ["has", "name:en"],
                                ["!", ["has", "script"]],
                            ],
                            "",
                            ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                        ],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                    ["get", "name:en"],
                ],
                [
                    "format",
                    ["coalesce", ["get", "name:" + language], ["get", "pgf:name"], ["get", "name"]],
                    {},
                ],
            ],
            [
                "all",
                ["any", ["has", "name"], ["has", "pgf:name"]],
                ["any", ["has", "name2"], ["has", "pgf:name2"]],
                ["!", ["any", ["has", "name3"], ["has", "pgf:name3"]]],
            ],
            [
                "case",
                ["all", ["has", "script"], ["has", "script2"]],
                [
                    "format",
                    ["get", "name:" + language],
                    {},
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script2"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                ],
                [
                    "case",
                    ["has", "script2"],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name"],
                            ["get", "name"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script2"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name2"],
                            ["get", "name2"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                ],
            ],
            [
                "case",
                ["all", ["has", "script"], ["has", "script2"], ["has", "script3"]],
                [
                    "format",
                    ["get", "name:" + language],
                    {},
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script2"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name3"], ["get", "name3"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script3"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                ],
                [
                    "case",
                    ["!", ["has", "script"]],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name"],
                            ["get", "name"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script2"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name3"], ["get", "name3"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script3"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                    ["!", ["has", "script2"]],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name2"],
                            ["get", "name2"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name3"], ["get", "name3"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script3"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name3"],
                            ["get", "name3"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script2"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                ],
            ],
        ],
        places_subplace: (language) => [
            "case",
            [
                "all",
                ["any", ["has", "name"], ["has", "pgf:name"]],
                ["!", ["any", ["has", "name2"], ["has", "pgf:name2"]]],
                ["!", ["any", ["has", "name3"], ["has", "pgf:name3"]]],
            ],
            [
                "case",
                ["has", "script"],
                [
                    "case",
                    ["any", ["is-supported-script", ["get", "name"]], ["has", "pgf:name"]],
                    [
                        "format",
                        ["coalesce", ["get", "name:" + language], ["get", "name:en"]],
                        {},
                        "\n",
                        {},
                        [
                            "case",
                            [
                                "all",
                                ["!", ["has", "name:" + language]],
                                ["has", "name:en"],
                                ["!", ["has", "script"]],
                            ],
                            "",
                            ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                        ],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                    ["get", "name:en"],
                ],
                [
                    "format",
                    ["coalesce", ["get", "name:" + language], ["get", "pgf:name"], ["get", "name"]],
                    {},
                ],
            ],
            [
                "all",
                ["any", ["has", "name"], ["has", "pgf:name"]],
                ["any", ["has", "name2"], ["has", "pgf:name2"]],
                ["!", ["any", ["has", "name3"], ["has", "pgf:name3"]]],
            ],
            [
                "case",
                ["all", ["has", "script"], ["has", "script2"]],
                [
                    "format",
                    ["get", "name:" + language],
                    {},
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script2"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                ],
                [
                    "case",
                    ["has", "script2"],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name"],
                            ["get", "name"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script2"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name2"],
                            ["get", "name2"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                ],
            ],
            [
                "case",
                ["all", ["has", "script"], ["has", "script2"], ["has", "script3"]],
                [
                    "format",
                    ["get", "name:" + language],
                    {},
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script2"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name3"], ["get", "name3"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script3"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                ],
                [
                    "case",
                    ["!", ["has", "script"]],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name"],
                            ["get", "name"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script2"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name3"], ["get", "name3"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script3"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                    ["!", ["has", "script2"]],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name2"],
                            ["get", "name2"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name3"], ["get", "name3"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script3"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name3"],
                            ["get", "name3"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script2"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                ],
            ],
        ],
        pois: (language) => [
            "case",
            [
                "all",
                ["any", ["has", "name"], ["has", "pgf:name"]],
                ["!", ["any", ["has", "name2"], ["has", "pgf:name2"]]],
                ["!", ["any", ["has", "name3"], ["has", "pgf:name3"]]],
            ],
            [
                "case",
                ["has", "script"],
                [
                    "case",
                    ["any", ["is-supported-script", ["get", "name"]], ["has", "pgf:name"]],
                    [
                        "format",
                        ["coalesce", ["get", "name:" + language], ["get", "name:en"]],
                        {},
                        "\n",
                        {},
                        [
                            "case",
                            [
                                "all",
                                ["!", ["has", "name:" + language]],
                                ["has", "name:en"],
                                ["!", ["has", "script"]],
                            ],
                            "",
                            ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                        ],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                    ["get", "name:en"],
                ],
                [
                    "format",
                    ["coalesce", ["get", "name:" + language], ["get", "pgf:name"], ["get", "name"]],
                    {},
                ],
            ],
            [
                "all",
                ["any", ["has", "name"], ["has", "pgf:name"]],
                ["any", ["has", "name2"], ["has", "pgf:name2"]],
                ["!", ["any", ["has", "name3"], ["has", "pgf:name3"]]],
            ],
            [
                "case",
                ["all", ["has", "script"], ["has", "script2"]],
                [
                    "format",
                    ["get", "name:" + language],
                    {},
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script2"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                ],
                [
                    "case",
                    ["has", "script2"],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name"],
                            ["get", "name"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script2"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name2"],
                            ["get", "name2"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                ],
            ],
            [
                "case",
                ["all", ["has", "script"], ["has", "script2"], ["has", "script3"]],
                [
                    "format",
                    ["get", "name:" + language],
                    {},
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script2"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name3"], ["get", "name3"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script3"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                ],
                [
                    "case",
                    ["!", ["has", "script"]],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name"],
                            ["get", "name"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script2"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name3"], ["get", "name3"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script3"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                    ["!", ["has", "script2"]],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name2"],
                            ["get", "name2"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name3"], ["get", "name3"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script3"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name3"],
                            ["get", "name3"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script2"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                ],
            ],
        ],
        pois_peak: (language) => ProtomapsLanguageSupport.simpleExpression(language),
        water_label_lakes: (language) => ProtomapsLanguageSupport.waterwayExpression(language),
        water_label_ocean: (language) => ProtomapsLanguageSupport.waterwayExpression(language),
        water_waterway_label: (language) => ProtomapsLanguageSupport.waterwayExpression(language),
        roads_labels_minor: (language) => ProtomapsLanguageSupport.roadLabelExpression(language),
        roads_labels_major: (language) => ProtomapsLanguageSupport.roadLabelExpression(language),
    }

    constructor(map: Store<MlMap>) {
        this._map = map
        map.addCallbackAndRunD(async (map) => {
            this.update()
            while (!map.isStyleLoaded()) {
                await Utils.waitFor(250)
            }
            this.update()
            map.on("styledata", () => {
                this.update()
            })
        })
        Locale.language.addCallback(() => this.update())
    }

    private _isUpdating = false

    public update() {
        ProtomapsLanguageSupport._update(this._map?.data, Locale.language.data)
    }

    private static waterwayExpression(
        language: string
    ): DataDrivenPropertyValueSpecification<string> {
        return [
            "case",
            [
                "all",
                ["any", ["has", "name"], ["has", "pgf:name"]],
                ["!", ["any", ["has", "name2"], ["has", "pgf:name2"]]],
                ["!", ["any", ["has", "name3"], ["has", "pgf:name3"]]],
            ],
            [
                "case",
                ["has", "script"],
                [
                    "case",
                    ["any", ["is-supported-script", ["get", "name"]], ["has", "pgf:name"]],
                    [
                        "format",
                        ["coalesce", ["get", "name:" + language], ["get", "name:en"]],
                        {},
                        "\n",
                        {},
                        [
                            "case",
                            [
                                "all",
                                ["!", ["has", "name:" + language]],
                                ["has", "name:en"],
                                ["!", ["has", "script"]],
                            ],
                            "",
                            ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                        ],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                    ["get", "name:en"],
                ],
                [
                    "format",
                    ["coalesce", ["get", "name:" + language], ["get", "pgf:name"], ["get", "name"]],
                    {},
                ],
            ],
            [
                "all",
                ["any", ["has", "name"], ["has", "pgf:name"]],
                ["any", ["has", "name2"], ["has", "pgf:name2"]],
                ["!", ["any", ["has", "name3"], ["has", "pgf:name3"]]],
            ],
            [
                "case",
                ["all", ["has", "script"], ["has", "script2"]],
                [
                    "format",
                    ["get", "name:" + language],
                    {},
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script2"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                ],
                [
                    "case",
                    ["has", "script2"],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name"],
                            ["get", "name"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script2"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name2"],
                            ["get", "name2"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                ],
            ],
            [
                "case",
                ["all", ["has", "script"], ["has", "script2"], ["has", "script3"]],
                [
                    "format",
                    ["get", "name:" + language],
                    {},
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script2"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name3"], ["get", "name3"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script3"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                ],
                [
                    "case",
                    ["!", ["has", "script"]],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name"],
                            ["get", "name"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script2"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name3"], ["get", "name3"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script3"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                    ["!", ["has", "script2"]],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name2"],
                            ["get", "name2"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name3"], ["get", "name3"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script3"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name3"],
                            ["get", "name3"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script2"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                ],
            ],
        ]
    }

    private static simpleExpression(
        language: string
    ): DataDrivenPropertyValueSpecification<string> {
        return ["coalesce", ["get", "name:" + language], ["get", "name"], ["get", "name:en"]]
    }

    private static roadLabelExpression(
        language: string
    ): DataDrivenPropertyValueSpecification<string> {
        return [
            "case",
            [
                "all",
                ["any", ["has", "name"], ["has", "pgf:name"]],
                ["!", ["any", ["has", "name2"], ["has", "pgf:name2"]]],
                ["!", ["any", ["has", "name3"], ["has", "pgf:name3"]]],
            ],
            [
                "case",
                ["has", "script"],
                [
                    "case",
                    ["any", ["is-supported-script", ["get", "name"]], ["has", "pgf:name"]],
                    [
                        "format",
                        ["coalesce", ["get", "name:" + language], ["get", "name:en"]],
                        {},
                        "\n",
                        {},
                        [
                            "case",
                            [
                                "all",
                                ["!", ["has", "name:" + language]],
                                ["has", "name:en"],
                                ["!", ["has", "script"]],
                            ],
                            "",
                            ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                        ],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                    ["get", "name:en"],
                ],
                [
                    "format",
                    ["coalesce", ["get", "name:" + language], ["get", "pgf:name"], ["get", "name"]],
                    {},
                ],
            ],
            [
                "all",
                ["any", ["has", "name"], ["has", "pgf:name"]],
                ["any", ["has", "name2"], ["has", "pgf:name2"]],
                ["!", ["any", ["has", "name3"], ["has", "pgf:name3"]]],
            ],
            [
                "case",
                ["all", ["has", "script"], ["has", "script2"]],
                [
                    "format",
                    ["get", "name:" + language],
                    {},
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script2"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                ],
                [
                    "case",
                    ["has", "script2"],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name"],
                            ["get", "name"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script2"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name2"],
                            ["get", "name2"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                ],
            ],
            [
                "case",
                ["all", ["has", "script"], ["has", "script2"], ["has", "script3"]],
                [
                    "format",
                    ["get", "name:" + language],
                    {},
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script2"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                    "\n",
                    {},
                    ["coalesce", ["get", "pgf:name3"], ["get", "name3"]],
                    {
                        "text-font": [
                            "case",
                            ["==", ["get", "script3"], "Devanagari"],
                            ["literal", ["Noto Sans Devanagari Regular v1"]],
                            ["literal", ["Noto Sans Regular"]],
                        ],
                    },
                ],
                [
                    "case",
                    ["!", ["has", "script"]],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name"],
                            ["get", "name"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script2"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name3"], ["get", "name3"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script3"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                    ["!", ["has", "script2"]],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name2"],
                            ["get", "name2"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name3"], ["get", "name3"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script3"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                    [
                        "format",
                        [
                            "coalesce",
                            ["get", "name:" + language],
                            ["get", "pgf:name3"],
                            ["get", "name3"],
                        ],
                        {},
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name"], ["get", "name"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                        "\n",
                        {},
                        ["coalesce", ["get", "pgf:name2"], ["get", "name2"]],
                        {
                            "text-font": [
                                "case",
                                ["==", ["get", "script2"], "Devanagari"],
                                ["literal", ["Noto Sans Devanagari Regular v1"]],
                                ["literal", ["Noto Sans Regular"]],
                            ],
                        },
                    ],
                ],
            ],
        ]
    }

    private static _update(map: MlMap, language: string) {
        if (!map) {
            return
        }
        if (!map.isStyleLoaded()) {
            map.once("styledata", () => {
                ProtomapsLanguageSupport._update(map, language)
            })
            return
        }
        const style = map.getStyle()
        ;(style.layers ?? []).forEach((layer: LayerSpecification) => {
            if (layer.type !== "symbol") {
                return
            }
            const symbolLayer: SymbolLayerSpecification = layer

            if (symbolLayer.source !== "protomaps") {
                return
            }
            const tf = symbolLayer.layout?.["text-field"]
            if (tf === undefined) {
                return
            }
            const newExpressionF = ProtomapsLanguageSupport.expressions[layer.id]
            if (!newExpressionF) {
                return
            }
            const newExpression = newExpressionF(language)
            if (!newExpression) {
                return
            }
            const oldProperty = map.getLayoutProperty(layer.id, "text-field")
            if (JSON.stringify(oldProperty) === JSON.stringify(newExpression)) {
                return
            }
            map.setLayoutProperty(layer.id, "text-field", newExpression)
        })
    }
}
