if(typeof(ss) == 'undefined') ss = {};

/*
 * Lightweight clientside i18n implementation.
 * Caution: Only available after DOM loaded because we need to detect the language
 * 
 * For non-i18n stub implementation, see sapphire/javascript/i18nx.js
 * 
 * Based on jQuery i18n plugin: 1.0.0  Feb-10-2008
 * 
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * Based on 'javascript i18n that almost doesn't suck' by markos
 * http://markos.gaivo.net/blog/?p=100
 */
ss.i18n = {
	
	currentLocale: null,
	
	defaultLocale: 'en_US',
	
	lang: {},
	
	init: function() {
		this.currentLocale = this.detectLocale();
	},
	
	/**
	 * set_locale()
	 * Set locale in long format, e.g. "de_AT" for Austrian German.
	 * @param string locale
	 */
	setLocale: function(locale) {
		this.currentLocale = locale;
	},
	
	/**
	 * getLocale()
	 * Get locale in long format. Falls back to i18n.defaut_locale.
	 * @return string
	 */
	getLocale: function() {
		return (this.currentLocale) ? this.currentLocale : this.defaultLocale;
	},
	
	/**
	 * _()
	 * The actual translation function. Looks the given string up in the 
	 * dictionary and returns the translation if one exists. If a translation 
	 * is not found, returns the original word
	 *
	 * @param string entity A "long" locale format, e.g. "de_DE" (Required)
	 * @param string fallbackString (Required)
	 * @param int priority (not used)
	 * @param string context Give translators context for the string
	 * @return string : Translated word
	 *
	 */
		_t: function (entity, fallbackString, priority, context) {
			if (this.lang && this.lang[this.getLocale()] && this.lang[this.getLocale()][entity]) {
				return this.lang[this.getLocale()][entity];
			} else if (this.lang && this.lang[this.defaultLocale] && this.lang[this.defaultLocale][entity]) {
				return this.lang[this.defaultLocale][entity];
			} else if(fallbackString) {
				return fallbackString;
			} else {
				return '';
			}
		},
		
		/**
		 * Add entities to a dictionary. If a dictionary doesn't
		 * exist for this locale, its automatically created.
		 * Existing entities are overwritten.
		 * 
		 * @param string locale
		 * @param Object dict
		 */
		addDictionary: function(locale, dict) {
			if(!this.lang[locale]) this.lang[locale] = {};
			for(entity in dict) {
				this.lang[locale][entity] = dict[entity];
			}
		},
		
		/**
		 * Get dictionary for a specific locale.
		 * 
		 * @param string locale
		 */
		getDictionary: function(locale) {
			return this.lang[locale];
		},
	
	/**
	 * stripStr()
	 *
	 * @param string str : The string to strip
	 * @return string result : Stripped string
	 *
	 */
	 	stripStr: function(str) {
			return str.replace(/^\s*/, "").replace(/\s*$/, "");
		},
	
	/**
	 * stripStrML()
	 *
	 * @param string str : The multi-line string to strip
	 * @return string result : Stripped string
	 *
	 */
		stripStrML: function(str) {
			// Split because m flag doesn't exist before JS1.5 and we need to
			// strip newlines anyway
			var parts = str.split('\n');
			for (var i=0; i<parts.length; i++)
				parts[i] = stripStr(parts[i]);
	
			// Don't join with empty strings, because it "concats" words
			// And strip again
			return stripStr(parts.join(" "));
		},

	/*
	 * printf()
	 * C-printf like function, which substitutes %s with parameters
	 * given in list. %%s is used to escape %s.
	 *
	 * Doesn't work in IE5.0 (splice)
	 *
	 * @param string S : string to perform printf on.
	 * @param string L : Array of arguments for printf()
	 */
		sprintf: function(S) {
			if (arguments.length == 1) return S;

			var nS = "";
			var tS = S.split("%s");
			
			var args = [];
			for (var i=1, len = arguments.length; i <len; ++i) {
				args.push(arguments[i]);
			};

			for(var i=0; i<args.length; i++) {
				if (tS[i].lastIndexOf('%') == tS[i].length-1 && i != args.length-1)
					tS[i] += "s"+tS.splice(i+1,1)[0];
				nS += tS[i] + args[i];
			}
			return nS + tS[tS.length-1];
		},
		
		/**
		 * Detect document language settings by looking at <meta> tags.
		 * If no match is found, returns this.defaultLocale.
		 * 
		 * @todo get by <html lang=''> - needs modification of SSViewer
		 * 
		 * @return string Locale in mixed lowercase/uppercase format suitable
		 * for usage in ss.i18n.lang arrays (e.g. 'en_US').
		 */
		detectLocale: function() {
			var rawLocale;
			var detectedLocale;
		
			// get by meta
			var metas = document.getElementsByTagName('meta');
			for(var i=0; i<metas.length; i++) {
				if(metas[i].attributes['http-equiv'] && metas[i].attributes['http-equiv'].nodeValue.toLowerCase() == 'content-language') {
					rawLocale = metas[i].attributes['content'].nodeValue;
				}
			}

			// fallback to default locale
			if(!rawLocale) rawLocale = this.defaultLocale;
			
			var rawLocaleParts = rawLocale.match(/([^-|_]*)[-|_](.*)/);
			// get locale (e.g. 'en_US') from common name (e.g. 'en')
			// by looking at ss.i18n.lang tables
			if(rawLocale.length == 2) {
				for(compareLocale in ss.i18n.lang) {
					if(compareLocale.substr(0,2).toLowerCase() == rawLocale.toLowerCase()) {
						detectedLocale = compareLocale;
						break;
					}
				}
			} else if(rawLocaleParts) {
				detectedLocale = rawLocaleParts[1].toLowerCase() + '_' + rawLocaleParts[2].toUpperCase();
			}
			
			return detectedLocale;
		},
		
		/**
		 * Attach an event listener to the given object.
		 * Modeled after behaviour.js, but externalized
		 * to keep the i18n library standalone for now.
		 */
		addEvent: function(obj, evType, fn, useCapture){
			if (obj.addEventListener){
				obj.addEventListener(evType, fn, useCapture);
				return true;
			} else if (obj.attachEvent){
				var r = obj.attachEvent("on"+evType, fn);
				return r;
			} else {
				alert("Handler could not be attached");
			}
		}
};



ss.i18n.addEvent(window, "load", function() {
	ss.i18n.init();
});