// browser sniffing
var isSafari = navigator.userAgent.toLowerCase().indexOf('webkit') > -1;
var isIE = window.ActiveXObject;
var isFireFoxOrOpera = document.implementation && document.implementation.createDocument;

// emulate document.getElementsByClassName
document.getElementsByClassName = function(cssclass) 
{
	var retnode = [];
	var myclass = new RegExp('\\b' + cssclass + '\\b');
	var elem = this.getElementsByTagName('*');
	
	for (var i = 0; i < elem.length; i++)
	{
		var classes = elem[i].className;
		if (myclass.test(classes))
		{
			retnode.push(elem[i]);
		}
	}
	return retnode;
};

// document.createElement alias
function $create(element)
{
	return document.createElement(element);
}

// document.getElementById alias
function $get(stringId)
{
	return document.getElementById(stringId);
}

// create stylesheet on the client
function $stylesheet(file, id)
{
	var stylesheet = document.createElement('link');

	stylesheet.setAttribute('type', 'text/css');
	stylesheet.setAttribute('rel', 'stylesheet');
	stylesheet.setAttribute('href', file);
	stylesheet.setAttribute('id', id);
	
	if($get(id) == null)
	{
		document.getElementsByTagName('head')[0].appendChild(stylesheet);
	}
}

// append element as last child
function $insertLastChild(element, lastchildnodetagname, lastchildnodecontent)
{
	var newlastchild = document.createElement(lastchildnodetagname);

	newlastchild.innerHTML = lastchildnodecontent;
	element.appendChild(newlastchild);
}

// append element as first child
function $insertFirstChild(element, newchildnodetagname, newchildnodecontent)
{
	var newchild = document.createElement(newchildnodetagname);

	newchild.innerHTML = newchildnodecontent;
	element.insertBefore(newchild, element.childNodes[0]);
}

// remove n-th child from an element
function $removeNthChild(element, childindex)
{
	element.removeChild(element.childNodes[childindex - 1]);
}

// attach DOM event
function $attachDomEvent(element, action, handler)
{
	if(window.attachEvent)
	{
		element.attachEvent('on' + action, handler);
	}
	else
	{
		element.addEventListener(action, handler, false);
	}
}

// toggle
function $toggle(elementid, toggleproperty, togglefactor) 
{
	try
	{
		if(toggleproperty == 'display')
		{
			elementid.style.display = (elementid.style.display == togglefactor ) ? "" : togglefactor;
		}
		if(toggleproperty == 'visibility')
		{
			elementid.style.visibility = (elementid.style.visibility == togglefactor ) ? "" : togglefactor;
		}
		else if(toggleproperty != 'display' && toggleproperty != 'visibility')
		{
			alert('Invalid toggleproperty value (' + toggleproperty + '). Choose either "display" or "visibility".');
			return false;
		}
	}
	catch(e)
	{
		alert('Invalid togglefactor value. It should be "block", "none", "visible" or "hidden".');
	}
}

// alias for document.getElementById
function $get(stringId)
{
	return document.getElementById(stringId);
}

// get element style
function $style(element, cssproperty)
{
	if(element.currentStyle)
	{
		var camelcase = cssproperty.replace(/\-(.)/g, function(m, l)
		{
			return l.toUpperCase();
		});

		return element.currentStyle[camelcase];
	}
	else if (window.getComputedStyle)
	{
		var elementStyle = window.getComputedStyle(element, "");
		
		return elementStyle.getPropertyValue(cssproperty);
	}
}

// append CSS class
function $appendCssClass(element, cssclass)
{
	var currentclass = element.className;
	if(!new RegExp(cssclass, "i").test(currentclass))
	{
		element.className = currentclass + ((currentclass.length > 0)? " " : "") + cssclass;
	}
}

// remove css class
function $removeClassName(element, cssclass)
{
	var cssclasstoremove = new RegExp((cssclass + "\s?"), "i");
	
	element.className = element.className.replace(cssclasstoremove, "").replace(/^\s?|\s?$/g, "");
}

// get elements by tag name
function $tag(tagName)
{
	return document.getElementsByTagName(tagName);
}

// create guid
function createguid() 
{
	return (((1 + Math.random()) * 0x10000)|0).toString(16).substring(1);
}