jhanink
8/23/2013 - 4:47 AM

A localization service

A localization service

services.factory('MacLocalizationService', ['$http', '$rootScope',function($http, $rootScope)
//-----------------------------------------------------------------
{
    return  {
        _LANGUAGES: {
            '1': 'en_US',
            '36': 'en_AU',
            '44': 'en_GB',
            '250': 'fr_FR',
            '276': 'de_DE'
        },
        _bundle: null, // by language localization
        _properties: null, // by country localization
        currencySymbol: null,
        // activate a pre-loaded bundle
        init: function (messagesBundle, countryProperties) {
            // register the bundle and country properties
            this._bundle = messagesBundle;
            this._properties = countryProperties;
            // add a reference to scope
            $rootScope.mls = this;
            this.currencySymbol = Const.COUNTRY_CURRENCY_CONFIG[gAccountInfo.countryId].CURRENCY_SYM;
        },
        getLang: function(countryId) {
            return this._LANGUAGES[countryId];
        },
        getCurrencySymbol: function() {
            return this.currencySymbol;
        },
        /**
         * key lookup with optional substitution
         * if a substitution array is supplied, substitute the values
         * by position into slots %1, %2, %3, etc.
         * For example, given:
         *   "This is $1 sentence that is $2 words long.",
         * and a substitution array ["an English", "10"]
         * yields
         *   "This is an English sentence that is 10 words long."
         *
         * NOTE: there is an associated directive called 'mls' for language translations
         *       and a directive called 'mlsp' for country properties
         */
        get: function(key /*, [optional,array,of,substitution,values] */) {
            return this._get(key, this._bundle, arguments);
        },
        getProp: function(key /*, [optional,array,of,substitution,values] */) {
            return this._get(key, this._properties, arguments);
        },
        _get:function(key, bundleOrProperties, args) {
            var keyParts = key.split('.');
            var lookupValue = bundleOrProperties;
            try {
                for (var i=0; i<keyParts.length; i++) {
                    lookupValue = lookupValue[keyParts[i].trim()];
                    if (typeof(lookupValue) == "undefined") {
                        return "** bad key ["+key+"] **";
                    }
                }
                // if supplied, attempt substitutions against the lookup value
                if (args && args.length === 2) {
                    var substitutions = args[1];
                    for (var i=0; i<substitutions.length; i++) {
                        var substitutionTarget = "$"+(i+1);
                        var split = lookupValue.split(substitutionTarget);
                        split.splice(1,0,substitutions[i]);
                        lookupValue = split.join('');
                    }
                }
                return lookupValue;
            } catch (e) {
                return "** bad key ["+key+"] **";
            }
        },
        // convenience function mls.getUsingSecondaryKey(mainMessageKey, substKey)
        getUsingSecondaryKey: function(mainMessageKey, substKey) {
            return this.get(mainMessageKey, [this.get(substKey)]);
        },
        // supports scoped objects in dot form, e.g. "obj.prop1.prop2"
        getSubstitutionArray: function(commaSeparatedInputString, /*optional*/scopeActual) {
            var scope = scopeActual;
            var subst = commaSeparatedInputString;
            var substArray = [];
            if (subst) {
                substArray = subst.split(',');
                for (var i=0;i<substArray.length;i++) {
                    var val = substArray[i].trim();
                    var parts = val.split('.');
                    var newVal = scope;
                    for (var p=0;p<parts.length;p++) {
                        newVal = newVal[parts[p]];
                        if (!newVal) {
                            substArray[i] = val;
                            break;
                        }
                    }
                    if (newVal) {
                        substArray[i] = newVal;
                    }
                }
            }
            return substArray;
        },
        loadBundle: function(lang, callback) {
            var URL = 'app/i18n/messages_'+lang+'.js';
            gLog.debug('Localization bundle url', URL);
            var thisObj = this; // binding var for closure
            $http.get( URL)
                .success(
                function(data) {
                    eval(data);
                    gLog.debug('Localization bundle data loaded.');
                    callback();
                }
            ).error(function(data, status) {
                gLog.debug('Localization bundle data NOT loaded.');
            });
        },
        processKey: function(scope, elm, attrs, key, keyType) {
            var isMessageKey = ("mls" == keyType);

            var subst = attrs.mlsSubst;
            var substScope = attrs.mlsSubstScope;
            var secondaryKey = attrs.mlsSubstSec;

            var output;
            if (subst || substScope) {
                // NOTE: scope.mls refers to GlobalCtrl.mls
                var substArray;
                if (substScope) {
                    substArray = scope.mls.getSubstitutionArray(substScope, scope);
                } else {
                    substArray = scope.mls.getSubstitutionArray(subst);
                }
                if (isMessageKey) {
                    output = scope.mls.get(key, substArray);
                } else {
                    output = scope.mls.getProp(key, substArray);
                }
            } else if (secondaryKey) {
                output = scope.mls.getUsingSecondaryKey(key, secondaryKey);
            } else {
                if (isMessageKey) {
                    output = output = scope.mls.get(key);
                } else {
                    output = scope.mls.getProp(key);
                }
            }
            return output;
        }
    };
}]);