(function () {

    var dictionaries = {};

    function getUrl(name, culture) {

        var parts = culture.split('-');
        if (parts.length == 2) {
            parts[1] = parts[1].toUpperCase();
            culture = parts.join('-');
        }

        return 'strings/' + name + '/' + culture + '.json';
    }
    function getDictionary(name, culture) {

        return dictionaries[getUrl(name, culture)];
    }

    function loadDictionary(name, culture) {

        var deferred = DeferredBuilder.Deferred();

        if (getDictionary(name, culture)) {
            deferred.resolve();
        } else {

            var url = getUrl(name, culture);

            $.getJSON(url).done(function (dictionary) {

                dictionaries[url] = dictionary;
                deferred.resolve();

            }).fail(function () {

                // If there's no dictionary for that language, grab English
                $.getJSON(getUrl(name, 'en-US')).done(function (dictionary) {

                    dictionaries[url] = dictionary;
                    deferred.resolve();

                });
            });
        }

        return deferred.promise();
    }

    var currentCulture = 'en-US';
    function setCulture(value) {

        Logger.log('Setting culture to ' + value);

        currentCulture = value;

        return $.when(loadDictionary('html', value), loadDictionary('javascript', value));
    }

    function normalizeLocaleName(culture) {

        culture = culture.replace('_', '-');

        // If it's de-DE, convert to just de
        var parts = culture.split('-');
        if (parts.length == 2) {
            if (parts[0].toLowerCase() == parts[1].toLowerCase()) {
                culture = parts[0].toLowerCase();
            }
        }

        return culture;
    }

    function getDeviceCulture() {
        var deferred = DeferredBuilder.Deferred();

        var culture;

        if (navigator.globalization && navigator.globalization.getLocaleName) {

            Logger.log('Calling navigator.globalization.getLocaleName');

            navigator.globalization.getLocaleName(function (locale) {

                culture = normalizeLocaleName(locale.value || '');
                Logger.log('Device culture is ' + culture);
                deferred.resolveWith(null, [culture]);

            }, function () {

                Logger.log('navigator.globalization.getLocaleName failed');

                deferred.resolveWith(null, [null]);
            });

        } else if (AppInfo.supportsUserDisplayLanguageSetting) {

            Logger.log('AppInfo.supportsUserDisplayLanguageSetting is true');

            culture = AppSettings.displayLanguage();
            deferred.resolveWith(null, [culture]);

        } else {

            Logger.log('Getting culture from document');

            culture = document.documentElement.getAttribute('data-culture');
            deferred.resolveWith(null, [culture]);
        }

        return deferred.promise();
    }


    function ensure() {

        Logger.log('Entering Globalize.ensure');

        var deferred = DeferredBuilder.Deferred();

        getDeviceCulture().done(function (culture) {

            if (!culture) {
                culture = 'en-US';
            }

            setCulture(culture).done(function () {
                deferred.resolve();
            });
        });

        return deferred.promise();
    }

    function translateDocument(html, dictionaryName) {

        dictionaryName = dictionaryName || 'html';

        var glossary = getDictionary(dictionaryName, currentCulture) || {};
        return translateHtml(html, glossary);
    }

    function translateHtml(html, dictionary) {

        var startIndex = html.indexOf('${');

        if (startIndex == -1) {
            return html;
        }

        startIndex += 2;
        var endIndex = html.indexOf('}', startIndex);

        if (endIndex == -1) {
            return html;
        }

        var key = html.substring(startIndex, endIndex);
        var val = dictionary[key] || key;

        html = html.replace('${' + key + '}', val);

        return translateHtml(html, dictionary);
    }

    // Mimic Globalize api
    // https://github.com/jquery/globalize
    // Maybe later switch to it

    window.Globalize = {
        translate: function (key) {

            var glossary = getDictionary('javascript', currentCulture) || {};
            var val = glossary[key] || key;

            for (var i = 1; i < arguments.length; i++) {

                val = val.replace('{' + (i - 1) + '}', arguments[i]);

            }

            return val;
        },
        ensure: ensure,
        translateDocument: translateDocument
    };

})();