/*
 * noVNC: HTML5 VNC client
 * Copyright (C) 2012 Joel Martin
 * Licensed under MPL 2.0 (see LICENSE.txt)
 *
 * See README.md for usage and integration instructions.
 */

/*
 * Localization Utilities
 */

export function Localizer() {
    // Currently configured language
    this.language = 'en';

    // Current dictionary of translations
    this.dictionary = undefined;
}

Localizer.prototype = {
    // Configure suitable language based on user preferences
    setup: function (supportedLanguages) {
        var userLanguages;

        this.language = 'en'; // Default: US English

        /*
         * Navigator.languages only available in Chrome (32+) and FireFox (32+)
         * Fall back to navigator.language for other browsers
         */
        if (typeof window.navigator.languages == 'object') {
            userLanguages = window.navigator.languages;
        } else {
            userLanguages = [navigator.language || navigator.userLanguage];
        }

        for (var i = 0;i < userLanguages.length;i++) {
            var userLang = userLanguages[i];
            userLang = userLang.toLowerCase();
            userLang = userLang.replace("_", "-");
            userLang = userLang.split("-");

            // Built-in default?
            if ((userLang[0] === 'en') &&
                ((userLang[1] === undefined) || (userLang[1] === 'us'))) {
                return;
            }

            // First pass: perfect match
            for (var j = 0;j < supportedLanguages.length;j++) {
                var supLang = supportedLanguages[j];
                supLang = supLang.toLowerCase();
                supLang = supLang.replace("_", "-");
                supLang = supLang.split("-");

                if (userLang[0] !== supLang[0])
                    continue;
                if (userLang[1] !== supLang[1])
                    continue;

                this.language = supportedLanguages[j];
                return;
            }

            // Second pass: fallback
            for (var j = 0;j < supportedLanguages.length;j++) {
                supLang = supportedLanguages[j];
                supLang = supLang.toLowerCase();
                supLang = supLang.replace("_", "-");
                supLang = supLang.split("-");

                if (userLang[0] !== supLang[0])
                    continue;
                if (supLang[1] !== undefined)
                    continue;

                this.language = supportedLanguages[j];
                return;
            }
        }
    },

    // Retrieve localised text
    get: function (id) {
        if (typeof this.dictionary !== 'undefined' && this.dictionary[id]) {
            return this.dictionary[id];
        } else {
            return id;
        }
    },

    // Traverses the DOM and translates relevant fields
    // See https://html.spec.whatwg.org/multipage/dom.html#attr-translate
    translateDOM: function () {
        var self = this;
        function process(elem, enabled) {
            function isAnyOf(searchElement, items) {
                return items.indexOf(searchElement) !== -1;
            }

            function translateAttribute(elem, attr) {
                var str = elem.getAttribute(attr);
                str = self.get(str);
                elem.setAttribute(attr, str);
            }

            function translateTextNode(node) {
                var str = node.data.trim();
                str = self.get(str);
                node.data = str;
            }

            if (elem.hasAttribute("translate")) {
                if (isAnyOf(elem.getAttribute("translate"), ["", "yes"])) {
                    enabled = true;
                } else if (isAnyOf(elem.getAttribute("translate"), ["no"])) {
                    enabled = false;
                }
            }

            if (enabled) {
                if (elem.hasAttribute("abbr") &&
                    elem.tagName === "TH") {
                    translateAttribute(elem, "abbr");
                }
                if (elem.hasAttribute("alt") &&
                    isAnyOf(elem.tagName, ["AREA", "IMG", "INPUT"])) {
                    translateAttribute(elem, "alt");
                }
                if (elem.hasAttribute("download") &&
                    isAnyOf(elem.tagName, ["A", "AREA"])) {
                    translateAttribute(elem, "download");
                }
                if (elem.hasAttribute("label") &&
                    isAnyOf(elem.tagName, ["MENUITEM", "MENU", "OPTGROUP",
                                   "OPTION", "TRACK"])) {
                    translateAttribute(elem, "label");
                }
                // FIXME: Should update "lang"
                if (elem.hasAttribute("placeholder") &&
                    isAnyOf(elem.tagName, ["INPUT", "TEXTAREA"])) {
                    translateAttribute(elem, "placeholder");
                }
                if (elem.hasAttribute("title")) {
                    translateAttribute(elem, "title");
                }
                if (elem.hasAttribute("value") &&
                    elem.tagName === "INPUT" &&
                    isAnyOf(elem.getAttribute("type"), ["reset", "button", "submit"])) {
                    translateAttribute(elem, "value");
                }
            }

            for (var i = 0;i < elem.childNodes.length;i++) {
                var node = elem.childNodes[i];
                if (node.nodeType === node.ELEMENT_NODE) {
                    process(node, enabled);
                } else if (node.nodeType === node.TEXT_NODE && enabled) {
                    translateTextNode(node);
                }
            }
        }

        process(document.body, true);
    },
};

export var l10n = new Localizer();
export default l10n.get.bind(l10n);
