/////////////////////////////////////////////////////////////////////////////
//
// Gladiator Components
//
// http://www.gladiatorweb.com
//
// (c) 2006 by Edward H. Trager .  All Rights Reserved
//
// NAME: gladiatorLocale.js
//
// DESCRIPTION: Implements a locale class for localization.
//
// AUTHOR: Edward H. Trager
//
// LAST UPDATE: 2006.03.08
//
// NOTE: SEE "LICENSE" FILE FOR LICENSING TERMS
//
//////////////////////////////////////////////////////////////////////////////

//
// DEFINE:
//
var GLADIATOR_LOCALE_INCLUDED=true;

////////////////////////////////////////////
//
// LOCALE DATA AND LOCALE CLASS
//
////////////////////////////////////////////
function Locale(locale,direction,preferArabicIndicDigits){
	
	var _locale;
	if(locale) _locale=locale;
	else       _locale="en";   // Yes, English is the default ...
	
	var _direction;
	if(direction)                         _direction=direction;
	else if(locale=="ar" || locale=="he") _direction="rtl";
	else                                  _direction="ltr";
	
	var _languageCode;
	
	var _regionCode;
	
	//
	// It is possible to prefer Arabic-Indic digits over
	// traditional digits for those locales (like AR and TH)
	// that have traditional local digits:
	//
	var _preferArabicIndicDigits = preferArabicIndicDigits;
	
	//
	// Conventional mySelf variable is available to inner functions:
	//
	var mySelf=this;
	
	//
	// NOTE BENE:
	//
	// The following locale data are in the UTF-8 encoding:
	//
	
	//
	// Month names:
	//
	var _month = new Array();
	_month["ar"] = new Array("يناير","فبراير","مارس","أبريل","مايو","يونيو","يوليو","أغسطس","سبتمبر","أكتوبر","نوفمبر","ديسمبر");
	_month["de"] = new Array("Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember");
	_month["el"] = new Array("Ιανουάριος","Φεβρουάριος","Μάρτιος","Απρίλιος","Μάϊος","Ιούνιος","Ιούλιος","Αύγουστος","Σεπτέμβριος","Οκτώβριος","Νοέμβριος","Δεκέμβριος");
	_month["en"] = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
	_month["es"] = new Array("enero","febrero","marzo","abril","mayo","junio","julio","agosto","septiembre","octubre","noviembre","diciembre");
	_month["fr"] = new Array("janvier","février","mars","avril","mai","juin","juillet","août","septembre","octobre","novembre","décembre");
	_month["it"] = new Array("gennaio","febbraio","marzo","aprile","maggio","giugno","luglio","agosto","settembre","ottobre","novembre","dicembre");
	_month["ja"] = new Array("1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月");
	_month["pt"] = new Array("Janeiro","Fevereiro","Março","Abril","Maio","Junho","Julho","Agosto","Setembro","Outubro","Novembro","Dezembro");
	_month["ru"] = new Array("Январь","Февраль","Март","Апрель","Май","Июнь","Июль","Август","Сентябрь","Октябрь","Ноябрь","Декабрь");
	_month["th"] = new Array("มกราคม","กุมภาพันธ์","มีนาคม","เมษายน","พฤษภาคม","มิถุนายน","กรกฏาคม","สิงหาคม","กันยายน","ตุลาคม","พฤศจิกายน","ธันวาคม");
	_month["zh"] = new Array("1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月");
	
	//
	// Day abbreviations:
	//
	var _dayAbbr = new Array();
	_dayAbbr["ar"] = new Array( "ح","ن","ث","ر","خ","ج","س");
	_dayAbbr["de"] = new Array("So","Mo","Di","Mi","Do","Fr","Sa");
	_dayAbbr["el"] = new Array("Κυρ","Δευ","Τρι","Τετ","Πεμ","Παρ","Σαβ");
	_dayAbbr["en"] = new Array("Sun","Mon","Tue","Wed","Thu","Fri","Sat");
	_dayAbbr["es"] = new Array("dom","lun","mar","mié","jue","vie","sáb");
	_dayAbbr["fr"] = new Array("dim.","lun.","mar.","mer.","jeu.","ven.","sam.");
	_dayAbbr["it"] = new Array("dom","lun","mar","mer","gio","ven","sab");
	_dayAbbr["ja"] = new Array( "日","月","火","水","木","金","土" );
	_dayAbbr["pt"] = new Array("Dom","Seg","Ter","Qua","Qui","Sex","Sáb");
	_dayAbbr["ru"] = new Array("Вс","Пн","Вт","Ср","Чт","Пт","Сб");
	_dayAbbr["th"] = new Array("อ.","จ.","อ.","พ.","พฤ","ศ.","ส.");
	_dayAbbr["zh"] = new Array("日","一","二","三","四","五","六");
	
	//
	// Digits
	//
	var _digits = new Array();
	//
	// Many locales just use the Arabic-Indic digits:
	//
	var _ArabicIndicDigits = new Array("0","1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31");
	var _RomanNumerals     = new Array("0","I","II","III","IV","V","VI","VII","VIII","IX","X","XI","XII","XIII","XIV","XV","XVI","XVII","XVIII","XIX","XX","XXI","XXII","XXIII","XXIV","XXV","XXVI","XXVII","XXVIII","XXIX","XXX","XXXI");
	//
	// However, we set up an array as was done for Months and Days 
	// in order to fully support Arabic, Thai and other locales:
	//
	_digits["ar"] = new Array("٠","١","٢","٣","٤","٥","٦","٧","٨","٩","١٠","١١","١٢","١٣","١٤","١٥","١٦","١٧","١٨","١٩","٢٠","٢١","٢٢","٢٣","٢٤","٢٥","٢٦","٢٧","٢٨","٢٩","٣٠","٣١");
	_digits["de"] = _ArabicIndicDigits;
	_digits["el"] = _ArabicIndicDigits;
	_digits["en"] = _ArabicIndicDigits;
	_digits["es"] = _ArabicIndicDigits;
	_digits["fr"] = _ArabicIndicDigits;
	_digits["it"] = _ArabicIndicDigits;
	_digits["ja"] = _ArabicIndicDigits;
	_digits["pt"] = _ArabicIndicDigits;
	_digits["ru"] = _ArabicIndicDigits;
	_digits["th"] = new Array("๐","๑","๒","๓","๔","๕","๖","๗","๘","๙","๑๐","๑๑","๑๒","๑๓","๑๔","๑๕","๑๖","๑๗","๑๘","๑๙","๒๐","๒๑","๒๒","๒๓","๒๔","๒๕","๒๖","๒๗","๒๘","๒๙","๓๐","๓๑");
	_digits["zh"] = _ArabicIndicDigits;
	
	var _beforeCommonEra = new Array();
	_beforeCommonEra["ar"] = "ق.م";
	_beforeCommonEra["de"] = "v.Chr";
	_beforeCommonEra["el"] = "π.Χ.";
	_beforeCommonEra["en"] = "BCE";
	_beforeCommonEra["es"] = "a.C.";
	_beforeCommonEra["fr"] = "av. J.-C.";
	//_beforeCommonEra["hi"] = "ईसापूर्व";
	_beforeCommonEra["it"] = "aC";
	_beforeCommonEra["ja"] = "紀元前";
	//_beforeCommonEra["ko"] = "기원전";
	_beforeCommonEra["pt"] = "a.C.";
	_beforeCommonEra["ru"] = "до н.э.";
	_beforeCommonEra["th"] = "ปีก่อนคริสต์กาล";
	_beforeCommonEra["zh"] = "公元前";
	
	var _commonEra = new Array();
	_commonEra["ar"] = "م";
	_commonEra["de"] = "n. Chr.";
	_commonEra["el"] = "μ.Χ.";
	_commonEra["en"] = "CE";
	_commonEra["es"] = "d.C.";
	_commonEra["fr"] = "apr. J.-C.";
	//_commonEra["hi"] = "सन";
	_commonEra["it"] = "dC";
	_commonEra["ja"] = "西暦";
	//_commonEra["ko"] = "서기";
	_commonEra["pt"] = "d.C.";
	_commonEra["ru"] = "н.э.";
	_commonEra["th"] = "ค.ศ.";
	_commonEra["zh"] = "公元";
	
	
	//
	// setLanguageAndRegionCodes()
	//
	function setLanguageAndRegionCodes(){
		
		var a = _locale.split("_");
		_languageCode = a[0]?a[0]:"";
		_regionCode   = a[1]?a[1]:"";
		
	}
	
	/////////////////////////////
	//
	// PUBLIC METHODS ...
	//
	/////////////////////////////
	
	//
	// setLocale()
	//
	this.setLocale = function(localeString){
		_locale=localeString;
		if(_locale=="ar" || _locale=="he") _direction="rtl";
		else                               _direction="ltr";
		setLanguageAndRegionCodes();
		
	}
	
	//
	// setDirection()
	//
	this.setDirection = function(directionString){
		_direction = directionString;
		
	}
	
	//
	// returns month name
	//
	this.month = function(n){
		if(n<1 || n>12) return "--error--";
		return _month[_locale][n-1];
	}
	
	//
	// returns Day of week abbreviation
	//
	this.dayAbbr = function(n){
		if(n<1 || n>7) return "err";
		return _dayAbbr[_locale][n-1];
	}
	
	//
	// Returns Common Era abbreviation
	//
	this.CE = function(){
		return _commonEra[_locale];
	}
	
	//
	// BCE() : Returns Before Common Era abbreviation
	//
	this.BCE = function(){
		return _beforeCommonEra[_locale];
	}
	
	//
	// dayOfMonth(): convert number to string, possibly in localized digits
	//
	this.dayOfMonth = function(n){
		if(n<0 || n>31) return "err";
		return _digits[_locale][n];
	}
	
	//
	// setPreferArabicIndicDigits
	//
	this.setPreferArabicIndicDigits = function(){
		_preferArabicIndicDigits=true;
	}
	
	//
	// this.localizeDigits(): Convert a string containing numbers to 
	// a string with localized digits. Non-digits remain as in the
	// original.
	// 
	// Argument can also be a number
	// instead of a string.
	//
	this.localizeDigits = function( s ){
		
		if( _preferArabicIndicDigits ) return s;
		
		var _s;
		var o="";
		if(isNumber(s)){
			_s=s.toString();
		}else{
			_s=s;
		}
		for(var i=0;i<_s.length;i++){
			var c=_s.charCodeAt(i);
			// "0" is ASCII code 48, "9" is code 57:
			if (c>=48 && c<=57){
				o+= _digits[_locale][(c-48)];
			}else{
				o+= _s.charAt(i);
			}
		}
		return o;
	}
	
	//
	// romanNumeral()
	//
	this.romanNumeral = function( n ){
		if(n<0 || n> _RomanNumerals.length) return n.toString();
		return _RomanNumerals[n];
	}
	
	//
	// getLocale(): get the Locale string
	//
	this.getLocale = function(){
		return _locale;
	}

	//
	// getDirection() : Get text direction (ltr or rtl):
	//
	this.getDirection = function(){
		return _direction;
	}
	
	//
	// this.getLanguageCode
	//
	this.getLanguageCode = function(){
		
		return _languageCode;
		
	}
	
	//
	// this.getRegionCode
	//
	this.getRegionCode = function(){
		
		return _regionCode;
		
	}
	
	//
	// Constructor stuff:
	//
	setLanguageAndRegionCodes();

}

//
// L : L10N localization method : takes a key (English)
//     and returns a translated message string
//
function L(key){
	
	try{
		//////////////////////////
		//
		// 0. IF GMC global message catalog is unavailable:
		//
		//////////////////////////
		if( typeof GMC == "undefined") return key;
		
		//////////////////////////
		//
		// I. If GMC is available, try full locale first:
		//
		//////////////////////////
		var locale = LC.getLocale();
		if(GMC[locale]) return GMC[locale][key];
		
		//////////////////////////
		//
		// II. Next, try region variants, if known and available:
		//
		//////////////////////////
		var lang = LC.getLanguageCode();
		var region = LC.getRegionCode();
		switch(lang){
		case "zh":
			if(region=="CN") region="SI";
			if(region=="SG") region="SI";
			if(region=="TW") region="TR";
			if(region=="HK") region="TR";
			locale = lang+"_"+region;
			if( typeof GMC[locale]) return GMC[locale][key];
			break;
		}
		
		//////////////////////////
		//
		// III. Next try lang only without region variant:
		//
		//////////////////////////
		var locale = lang;
		if(GMC[locale]) return GMC[locale][key];
		
		//////////////////////////
		//
		// IV. Give up and return key:
		//
		//////////////////////////
		return key;
		
	}catch(ex){
		
		return key;
		
	}
}


//////////////////////////////
//
// Global LOCALE Object:
//
//////////////////////////////

//
// Global LC (LOCALE) object:
//
var LC = new Locale();


