

function exLeft(str, len, pad) {
	var pads = len - str.length; 
	if (pads <= 0) return str; 
	return str + exRepeat(pad, pads); 
}

function exRight(str, len, pad) {
	var pads = len - str.length; 
	if (pads <= 0) return str; 
	return exRepeat(pad, pads) + str; 
}

function exCenter(str, len, pad) {
	var pads = len - str.length; 
	var padLeft = pads / 2; 
	var padRight = pads - padLeft; 
	if (pads <= 0) return str; 
	return exRepeat(pad, padLeft) + str + exRepeat(pad, padRight); 
}

function exTrim(str) {
	if (typeof(str) != "string") return str; 
	return str.replace(/^\s*(.*?)\s*$/, "$1");
}

function exIsInRange(num, n_min, n_max) {
	if (isNaN(num)) return false; 
	if (isNaN(n_max)) n_max = n_min; 
	return (num >= n_min) && (num <= n_max); 
}

function exToNumber(obj) {
	if (typeof(obj) == "number") return obj; 
	if (obj == null) return 0; 
	if (obj == undefined) return 0; 
	if (obj == "") return 0; 
	return obj*1; 
}

function exIsControl(obj) {
	if (obj == null) return false; 
	if (typeof(obj) != "object") return false; 
	if (obj.value == undefined) return false; 
	return true; 
}

function exContainField(obj, field) {
	for (var f in obj) {
		if (f == field)
			return true; 
	}
	return false; 
}

function exObjectFields(obj) {
	var f, fs = 0; 
	for (f in obj) fs++; 
	return fs; 
}

function exObjectInfo(obj, indent, level) {
	var info = "", indents = ""; 
	var f, i; 

	if (typeof(indent) != "number") indent = 0; 
	if (typeof(level) != "number") level = 1; 
	for (i = 0; i < indent; i++)
		indents += "    "; 

	var fields = new Array(); 
	for (f in obj) fields.push(f); 
	fields.sort(); 
	
	for (i = 0; i < fields.length; i++) {
		f = fields[i]; 
		var ft = typeof(obj[f]); 
		if (ft == 'function') continue; 
		
		info += indents + f + " = "; 
		
		if (obj[f] == obj) {
			info += "this\n"; 
		} else if (indent < level && ft == "object") {
			var objinfo = exObjectInfo(obj[f], indent+1, level); 
			if (objinfo.length == 0)
				info += "object {}\n"; 
			else
				info += "object {\n" + objinfo + indents + "}\n"; 
		} else if (ft == "string") {
			var str; 
			if (obj[f].length > 100)
				str = obj[f].substring(0, 100); 
			else
				str = obj[f]; 
			
			str = str.replace(/\n/g, "\\n")
					.replace(/\r/g, "\\r")
					.replace(/\t/g, "\\t")
					.replace(/&/g, "&amp;")
					.replace(/</g, "&lt;")
					.replace(/\"/g, "\\\""); 
			
			str = "\"" + str + "\"" 
				+ (obj[f].length>100 ? "(...)" : "") + "\n"; 
			info += str; 
		} else if (obj[f] == null) {
			info += "null\n"; 
		} else {
			info += ft + "(" + obj[f] + ")\n"; 
		}
	}
	return info; 
}

function exTypeName(obj) {
	if (obj != null) {
		var oh = obj.outerHTML; 
		if (oh != null) {
			var len = oh.indexOf(" "); 
			if (len > 0)
				oh = oh.substring(1, len); 
			else
				oh = oh.substring(1); 
			oh = exTrim(oh).toUpperCase(); 
			if (oh.length > 0) return "HTML:"+oh; 
		}
	}
	return typeof(obj); 
}

function exIsArray(obj) {
	if (obj == null) return false; 
	if (obj.length == null) return false; 
	if (obj instanceof Array) return true; 
	if (obj.length != null) {
		// Test if control-array
		if (exTypeName(obj) == "HTML:SELECT")
			return false; 
		else
			return true; 
	}
	return false; 
}

function exArraySize(obj) {
	if (exIsArray(obj)) return obj.length;
	return 1;
}

function exElementAt(obj, index) {
	if (exIsArray(obj)) {
    	if (index < 0 || index >= obj.length) return null;
		return obj[index];
	} else {
		if (index != 0) return null; 
		return obj; 
	}
}

function exToArray(obj) {
	if (exIsArray(obj)) return obj; 
	return Array(obj); 
}

function exIsEmpty(obj) {
	if (obj == null) return true; 
	if (obj.length == 0) return true; 
	if (obj.value != null)
		if (obj.value.length == 0) return true; 
	return false; 
}

function exIsEmptyEvery(obj) {
	if(exIsArray(obj)) {
		var i; 
		for (i = 0; i < exArraySize(obj); i++) {
			if (!exIsEmpty(obj[i])) return false; 
		}
		return true; 
	}
	return exIsEmpty(obj); 
}

function exIsEmptyAny(obj) {
	if (exIsArray(obj)) {
		var i; 
		for (i = 0; i < exArraySize(obj); i++) {
			if (exIsEmpty(obj[i])) return true; 
		}
		return false; 
	}
	return exIsEmpty(obj); 
}

function exNull(obj, def) {
	if (obj == null) return def; 
	return obj; 
}

function exEmpty(obj, def) {
	if (exIsEmpty(obj)) return def; 
	return obj; 
}

function exRepeat(str, n) {
	var i, sum; 
	if (str == null) str = ""; 
	sum = ""; 
	for (i = 0; i < n; i++) {
		sum += str; 
	}
	return sum; 
}

function exStrJoin(obj, delim) {
	if (obj == null) return ""; 
	var a = exToArray(obj); 
	var i; 
	var result = ""; 
	for (i = 0; i < a.length; i++) {
		if (i != 0) result += delim; 
		result += a[i]; 
	}
	return result; 
}

function exValueJoin(obj, delim) {
	if (obj == null) return ""; 
	var a = exToArray(obj); 
	var i; 
	var result = ""; 
	for (i = 0; i < a.length; i++) {
		if (i != 0) result += delim; 
		result += a[i].value; 
	}
	return result; 
}

function exTries(f, interval, maxtimes, context) {
    if (interval == null) interval = 0; 
    if (maxtimes == null) maxtimes = 3;
    var laste;
    while (maxtimes--) {
        try {
            return f(context);
        } catch (e) {
            laste = e;
            // Sleep interval?
        }
    }
    throw e;
}
