function offsetPos(el)
{
	// Get element's real position
	var parEl = el;
	var top = 0;
	var left = 0;
	while (parEl != null && typeof parEl.offsetLeft != 'undefined')
	{
		left += parEl.offsetLeft;
		top += parEl.offsetTop;
		
		var bdrLft = getStyle(parEl, "border-left-width");
		if (bdrLft.length > 0 && bdrLft != '0px')
			left += bdrLft.substring(0, bdrLft.length - 2) / 1;
		var bdrTop = getStyle(parEl, "border-top-width");
		if (bdrTop.length > 0 && bdrTop != '0px')
			top += bdrTop.substring(0, bdrTop.length - 2) / 1;
		
		parEl = parEl.offsetParent;
	}
	return { X : left, Y : top };
}

// http://robertnyman.com/2006/04/24/get-the-rendered-style-of-an-element/
function getStyle(oElm, strCssRule){
	var strValue = "";
	if(document.defaultView && document.defaultView.getComputedStyle){
		strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
	}
	else if(oElm.currentStyle){
		strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
			return p1.toUpperCase();
		});
		strValue = oElm.currentStyle[strCssRule];
	}
	return strValue;
}

function funcToJsString(func)
{
	// Use function directly
	funcStr = func.toString();
	var match = funcStr.match('^function ([a-zA-Z]*)[(]');
	if (match != null)
	{
		if (match[1].length > 0)
			funcStr = match[1] + '();';
		else
			funcStr = funcStr.substr(13, funcStr.length - 14);
	}
	return 'function() { ' + funcStr + ' };';
}

/** Get all elements that have the given class name */
function getElementsByClassName(classname, node, tagType)
{
	if (!tagType)
		tagType = '*';
	if (!node)
		node = document.getElementsByTagName("body")[0];
	var a = [];
	var re = new RegExp('\\b' + classname + '\\b');
	var els = node.getElementsByTagName(tagType);
	for (var i = 0; i < els.length; ++i)
	{
		if (re.test(els[i].className))
			a.push(els[i]);
	}
	return a;
}

/** Strip all contents of an element and place a single message */
function replaceElementContentWithMessage(el, msg)
{
	if (el == null)
		return;
	while (el.childNodes.length > 0)
		el.removeChild(el.childNodes[0]);
	var waitMsg = document.createElement('p');
	waitMsg.className = 'center';
	waitMsg.innerHTML = msg;
	el.appendChild(waitMsg);
}

/** Gets/sets the % of opacity (0 - 100) */
function getElementOpacity(el)
{
	if (el == null)
		return 100;
	if (el.style.display == 'none')
		return 0;
	if (el.style.MozOpacity != undefined)
		return Math.round((el.style.MozOpacity == '' ? 1.0 : el.style.MozOpacity) * 100);
	if (el.style.opacity != undefined)
		return Math.round((el.style.opacity == '' ? 1.0 : el.style.opacity) * 100);
		
	if (el.style.filter != undefined && el.style.filter.substring(0, 14) == 'alpha(opacity=')
	{
		var opac = el.style.filter.substring(14);
		if (opac.substring(opac.length - 1) == ')')
			opac = opac.substring(0, opac.length - 1);
		return opac / 1;
	}
	
	return 100;
}
function setElementOpacity(el, opac)
{
	if (el == null || opac < 0 || opac > 100)
		return;
	if (el.style.MozOpacity != undefined)
		el.style.MozOpacity = (opac / 100) - 0.0001;
	else if (el.style.opacity != undefined)
		el.style.opacity = (opac / 100) - 0.0001;
	else if (el.style.filter != undefined)
		el.style.filter = 'alpha(opacity=' + opac + ')';
}

/** Allow urlencoding of strings */
function urlencode(str)
{
	return escape(str).replace(/[+]/g, '%2B');
}

function getElValue(el_id, def)
{
	var el = document.getElementById(el_id);
	if (el == null || el.value == undefined)
		return def;
	return el.value;
}
function setElValue(el_id, value)
{
	var el = document.getElementById(el_id);
	if (el == null || el.value == undefined)
		return false;
	el.value = value;
	return true;
}

function checkAll(el_name, check)
{
	var els = document.getElementsByTagName('input');
	for (var i = 0, j = els.length; i < j; ++i)
	{
		if (els[i].type == 'checkbox' && els[i].name.substring(0, el_name.length) == el_name)
			els[i].checked = check;
	}
}

function submitForm(form_id, action)
{
	var el = document.getElementById(form_id);
	if (el == null)
		return false;
	el.action = action;
	return el.submit();
}

function showLoadingOverEl(el)
{
	// Loading position
	var left = el.offsetLeft + (el.offsetWidth / 2);
	var top = el.offsetTop + (el.offsetHeight / 2);
	
	// Show loading
	var loading_el = document.getElementById('dtb_loading_div');
	if (loading_el != null)
	{
		loading_el.style.left = left + 'px';
		loading_el.style.top = top + 'px';
		loading_el.style.display = 'block';
	}
	else
	{
		if (!document.body)
			document.body = document.getElementsByTagName("body")[0];
		document.body.innerHTML += '<div id="dtb_loading_div" style="left: ' + left + 'px; top: ' + top + 'px;"><img src="' + _dtb_loading_img_loc + '" /> Loading...</div>';
	}
}

function htmlFormToPostString(formEl)
{
	var postStr = '';
	
	// Input (text, password, checkbox, radio)
	var els = formEl.getElementsByTagName('input');
	for (var i = 0; i < els.length; ++i)
	{
		if (!els[i].name || els[i].name.length < 1)
			continue;
		alert(els[i].type);
		switch (els[i].type.toUpper())
		{
			case 'CHECKBOX':
			case 'RADIO':
				if (els[i].checked)
					postStr += '&' + urlencode(els[i].name) + '=' + urlencode(els[i].value);
				break;
			case 'PASSWORD':
			case 'TEXT':
				postStr += '&' + urlencode(els[i].name) + '=' + urlencode(els[i].value);
				break;
		}
	}
	
	// Select
	var els = formEl.getElementsByTagName('select');
	for (var i = 0; i < els.length; ++i)
	{
		if (!els[i].name || els[i].name.length < 1)
			continue;
		postStr += '&' + urlencode(els[i].name) + '=' + urlencode(els[i].value);
	}
	
	// Button
	var els = formEl.getElementsByTagName('button');
	for (var i = 0; i < els.length; ++i)
	{
		if (!els[i].name || els[i].name.length < 1)
			continue;
		postStr += '&' + urlencode(els[i].name) + '=' + urlencode(els[i].value);
	}
	
	// Textarea
	var els = formEl.getElementsByTagName('textarea');
	for (var i = 0; i < els.length; ++i)
	{
		if (!els[i].name || els[i].name.length < 1)
			continue;
		postStr += '&' + urlencode(els[i].name) + '=' + urlencode(els[i].value);
	}
	
	return postStr;
}

String.prototype.trim = function() { return this.replace(/^\s+|\s+$/g, ''); }