/*
 * Helper functions
 */
function stripStr(str) {
	return str.replace(/^\s*/, "").replace(/\s*$/, "");
}

// Multiline strip
function stripStrML(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(" "));
}

// This code is in the public domain. Feel free to link back to http://jan.moesen.nu/
function sprintf() {
	if (!arguments || arguments.length < 1 || !RegExp) {
		return;
	}
	
	var str = arguments[0];
	var re = /([^%]*)%('.|0|\x20)?(-)?(\d+)?(\.\d+)?(%|b|c|d|u|f|o|s|x|X)(.*)/;
	var a = b = [], numSubstitutions = 0, numMatches = 0;
	while (a = re.exec(str)) {
		var leftpart = a[1], pPad = a[2], pJustify = a[3], pMinLength = a[4];
		var pPrecision = a[5], pType = a[6], rightPart = a[7];
				
		//alert(a + '\n' + [a[0], leftpart, pPad, pJustify, pMinLength, pPrecision);

		numMatches++;
		if (pType == '%') {
			subst = '%';
		}
		else {
			numSubstitutions++;
			if (numSubstitutions >= arguments.length) {
				alert('Error! Not enough function arguments (' + (arguments.length - 1) + ', excluding the string)\nfor the number of substitution parameters in string (' + numSubstitutions + ' so far).');
			}
			var param = arguments[numSubstitutions];
			var pad = '';
			if (pPad && pPad.substr(0,1) == "'") pad = leftpart.substr(1,1);
			else if (pPad) pad = pPad;
			var justifyRight = true;
			if (pJustify && pJustify === "-") justifyRight = false;
			var minLength = -1;
			if (pMinLength) minLength = parseInt(pMinLength);
			var precision = -1;
			if (pPrecision && pType == 'f') precision = parseInt(pPrecision.substring(1));
			var subst = param;
			if (pType == 'b') subst = parseInt(param).toString(2);
			else if (pType == 'c') subst = String.fromCharCode(parseInt(param));
			else if (pType == 'd') subst = parseInt(param) ? parseInt(param) : 0;
			else if (pType == 'u') subst = Math.abs(param);
			else if (pType == 'f') subst = (precision > -1) ? Math.round(parseFloat(param) * Math.pow(10, precision)) / Math.pow(10, precision): parseFloat(param);
			else if (pType == 'o') subst = parseInt(param).toString(8);
			else if (pType == 's') subst = param;
			else if (pType == 'x') subst = ('' + parseInt(param).toString(16)).toLowerCase();
			else if (pType == 'X') subst = ('' + parseInt(param).toString(16)).toUpperCase();
		}
		str = leftpart + subst + rightPart;
	}
	return str;
}

/*
 * i18n
 */
function i18n(i18n_dict) {
	this.i18nd = i18n_dict;
	console.info(i18n_dict);
	// Change to entity representation non-ASCII characters
	this.toEntity = function (str) {
		var newstr = "";
		for (var i=0;i<str.length; i++) {
			if (str.charCodeAt(i) > 128)
				newstr += "&#"+str.charCodeAt(i)+";";
			else
				newstr += str.charAt(i);
		}
		return newstr;
	}

	// Return translation, if translation dictionary exists and has a translation.
	this.translate = function (str, params) {
		var transl = str;
		if (this.i18nd && this.i18nd[str])
			transl = this.i18nd[str];
		return sprintf(transl, params);
	}

	this.translateNodes = function () {
		var nodes = document.getElementsByTagName("*");
		for (var i=0;i<nodes.length;i++)
			if (nodes[i].className.match("i18n")) {
				var orig = stripStrML(nodes[i].innerHTML);
				var transl = this.translate(orig);

				// If translation not found, try again with
				// entity representation
				if (transl == orig) transl = this.translate(this.toEntity(orig));
				nodes[i].innerHTML = transl;
			}
	}
}

if (typeof console=="undefined") {
	var console = new Object();
	console.info = function(){};
	console.log = function() {};
}

var Wethink = {};

Wethink.Registry = {
	
	_data: {}
	
	, write: function(key, value) {
			this._data[key] = value;
	}
	
	, read: function(key) {
			return this._data[key] || null;
	}
	 
}

Wethink.baseUrl = function() {
	if(document && document.getElementsByTagName){
		var scripts = document.getElementsByTagName("script");
		var rePkg = /js\/wethink\/wethink\.js([\?\.]|$)/i;
		for(var i = 0; i < scripts.length; i++){
			var src = scripts[i].getAttribute("src");
			if(!src){ continue; }
			var m = src.match(rePkg);
			if(m){
				// find out where we came from
				if(!Wethink.Registry.read('baseUrl')){
					Wethink.Registry.write('baseUrl', src.substring(0, m.index));
				}
				break;
			}
		}
	}
	return Wethink.Registry.read('baseUrl') || '/';
}();

Wethink.I18n = function() {
	var translator, __;
	return {
		init: function(dict) {
			translator = new i18n(dict);
			__ = function (str, params) { return translator.translate(str, params); }
		},
		get: function() {
			return __;
		}
	}
}();


Wethink.Pages = {};


String.prototype.ellipse = function(maxLength){
    if(this.length > maxLength){
        return this.substr(0, maxLength-3) + '...';
    }
    return this;
};
