/******************************************************
	Index:
	  
	1) ShortCuts
		1.0) Node Access
		1.1) Pixel Measure Conversion
		
	2) Create Nodes
		2.1) Create Element
		2.2) Create Text
		2.3) Create Div Tag
		2.4) Create Span Tag
		2.5) Create Img Tag
		2.6) Create Table Tag
		2.7) Create Tr Tag
		2.8) Create Td Tag
		2.9) Create Link Tag
		
	3) CSS Access
		3.1) Set CSS Class
		3.2) Unset CSS Class
		3.3) Check Wheter An Element Has A Specific CSS Class
		3.4) Show / Hide Node
		3.5) Toggle Class ON/OFF (exclusive)
		
		.
		.
		.
		
******************************************************/


/* --------------------------------------------------------------------------------------------- */
/* 1) ShortCuts
/* --------------------------------------------------------------------------------------------- */

// 1.0) Node Access
// .......................................................................
function $(n, index, element, specification, state) {
	
	/* Valid State Provided */
	if(typeof(state) == 'string')
		return $(n + '[' + index + ']', element, specification, state);

	// ~~~ ERROR Handling >>
	// *************************************************
	// Unvalid Specification Provided
	// ---------------------------------
	if(typeof(state) != 'string')
		if(typeof(state) != 'undefined') {
			location.href = GLOBAL['js_error']['error_page'] +
				'?errorMessage=' +
				escape('Fehler in Funktion $(): state');
		}
	// *************************************************
	// ~~~ /ERROR Handling <<


	/* Valid Specification Provided */
	if(typeof(specification) == 'string')
		return $(n + '[' + index + ']', element, specification);

	// ~~~ ERROR Handling >>
	// *************************************************
	// Unvalid Specification Provided
	// ---------------------------------
	if(typeof(specification) != 'string')
		if(typeof(specification) != 'undefined') {
			location.href = GLOBAL['js_error']['error_page'] +
				'?errorMessage=' +
				escape('Fehler in Funktion $(): specification');
		}
	// *************************************************
	// ~~~ /ERROR Handling <<


	/* Valid Element Provided */
	if(typeof(element) == 'string')
		return $(n + '[' + index + ']', element);


	// ~~~ ERROR Handling >>
	// *************************************************
	// Unvalid Element Provided
	// ---------------------------------
	if(typeof(element) != 'string')
		if(typeof(element) != 'undefined') {
			location.href = GLOBAL['js_error']['error_page'] +
				'?errorMessage=' +
				escape('Fehler in Funktion $(): element');
		}
	// *************************************************
	// ~~~ /ERROR Handling <<


	/* Only Node Provided */
	if(typeof(index) == 'undefined') {
		if(typeof(n) == 'object')
			return n;
	
		if(typeof(n) != 'string')
			return null;
	
		return document.getElementById(n);
	}


	// ~~~ ERROR Handling >>
	// *************************************************
	// Unvalid Index Provided
	// ---------------------------------
	if(typeof(index) != 'string') {
		location.href = GLOBAL['js_error']['error_page'] +
			'?errorMessage=' +
			escape('Fehler in Funktion $(): index');
	}
	// *************************************************
	// ~~~ /ERROR Handling <<


	/* Valid Index Provided */
	return $(n + '[' + index + ']');
}

function $_REVERSE(node) {
	
	var n = $(node);
	
	
	// ~~~ ERROR Handling >>
	// *************************************************
	// Unvalid Index Provided
	// ---------------------------------
	if(typeof(n.id) == 'undefined') {
		location.href = GLOBAL['js_error']['error_page'] +
			'?errorMessage=' +
			escape('Fehler in Funktion $_REVERSE(): n.id');
	}
	// *************************************************
	// ~~~ /ERROR Handling <<

	
	// Substract Values
	var a = n.id.replace(/]/g, '').split('[');
	
	// Return Value
	var r = {};
	r['n'] = a[0];
	r['index'] = a[1];
	r['element'] = a[2];
	r['specification'] = a[3];
	
	return r;
}

function $_EXIST(n, index, element, specification, state) {
	return $(n, index, element, specification, state) != null;
}


// 1.1) Pixel Measure Conversion
// .......................................................................
function px(number) {
	
	if(isNaN(number))
		return px(0);
	
	if(typeof(number) == 'number')
		return number + 'px';
	
	
	// ~~~ ERROR Handling >>
	// *************************************************
	// Invalid Number
	// ---------------------------------
	location.href = GLOBAL['js_error']['error_page'] +
		'?errorMessage=' +
		escape('Fehler in Funktion px(): No number');
	// *************************************************
	// ~~~ /ERROR Handling <<
}
function int(string) {
	if(string.length == 0)
		return 0;
	
	if(typeof(string) == 'string')
		return parseInt(string);
	
	
	// ~~~ ERROR Handling >>
	// *************************************************
	// Invalid String
	// ---------------------------------
	location.href = GLOBAL['js_error']['error_page'] +
		'?errorMessage=' +
		escape('Fehler in Funktion int(): string');
	// *************************************************
	// ~~~ /ERROR Handling <<
}


/* --------------------------------------------------------------------------------------------- */
/* 2) Create Nodes
/* --------------------------------------------------------------------------------------------- */

// 2.1) Create Element
// .......................................................................
function $Element(n, classname) {
	var e = document.createElement(n);

	if(classname)
		e.className = classname;

	return e;
}

// 2.2) Create Text
// .......................................................................
function $Text(n, style) {
	if(style != undefined) {
		var span = $Span();

		for(s in style)
			span.style[s] = style[s];

		span.appendChild(document.createTextNode(n));

		return span;
	}
	else
		return document.createTextNode(n);
}

// 2.3) Create Div Tag
// .......................................................................
function $Div(classname, width) {
	var e = $Element('div', classname);

	if(width != undefined)
		e.style.width = width + 'px';

	return e;
}

// 2.4) Create Span Tag
// .......................................................................
function $Span(classname, width) {
	var e = $Element('span', classname);

	if(width != undefined)
		e.style.width = width + 'px';

	return e;
}

// 2.5) Create Img Tag
// .......................................................................
function $Img(src, classname, width, height) {
	var e = $Element('img', classname);

	e.src = src;

	if(width)
		e.style.width = width + 'px';

	if(height)
		e.style.height = height + 'px';

	return e;
}

// 2.6) Create Table Tag
// .......................................................................
function $Table(classname) {
	return $Element('table', classname);
}

// 2.7) Create Tr Tag
// .......................................................................
function $Tr(classname) {
	return $Element('tr', classname);
}

// 2.8) Create Td Tag
// .......................................................................
function $Td(classname, colspan, width) {
	var e = $Element('td', classname);

	if(colspan)
		e.colSpan = colspan;

	if(width)
		e.style.width = width + 'px';

	return e;
}

// 2.9) Create Link Tag
// .......................................................................
function $Link(url, content, target, classname) {
	var a = $Element('a', classname);
	a.href = url;

	if(target)
		a.target = target;

	if(typeof(content) == 'object')
		a.appendChild(content);
	else
		a.appendChild($Text(content));

	return a;
}

/* --------------------------------------------------------------------------------------------- */
/* 3) CSS Access
/* --------------------------------------------------------------------------------------------- */


// 3.1) Set CSS Class
// .......................................................................
function setClass(e, classname, exclusive) {
	e = $(e);

	if(!e)
		return;

	exclusive = (exclusive == undefined) ? false : exclusive;

	if(exclusive == true) {
		e.className = classname;

		return;
	}

	var cn = e.className.split(' ');

	if(cn.indexOf(classname) != -1)
		return;

	cn.push(classname);

	e.className = cn.join(' ');
}

// 3.2) Unset CSS Class
// .......................................................................
function unsetClass(e, classname) {
	e = $(e);

	if(!e)
		return;

	var cn = e.className.split(' ');

	var i = cn.indexOf(classname);

	if(i == -1)
		return;

	cn.splice(i, 1);

	e.className = cn.join(' ');
}

// 3.3) Check Wheter An Element Has A Specific CSS Class
// .......................................................................
function hasClass(e, classname) {

	e = $(e);
	
	if(!e)
		return false;
	
	var cns = e.className.split(' ');
	var index = cns.indexOf(classname);
	
	if(index < 0)
		return false;
	else
		return true;
}

// 3.4) Show / Hide Node
// .......................................................................
function show(node, optional_index) {	
	unsetClass($(node, optional_index), 'hide');
}
function hide(node, optional_index) {
	setClass($(node, optional_index), 'hide');	
}
function isHidden(node) {
	return hasClass(node, 'hide');
}

function hideAll(node) {
	var n = $(node);
	for(var i=0; i<n.childNodes.length; i++) {
		if(n.childNodes[i].nodeType == 1)
			hide(n.childNodes[i]);
	}
}


// 3.5) Toggle Class ON/OFF (exclusive)
// .......................................................................
function toggle_class(node, className) {
	
	n = $(node);
	
	if(n.className == className)
		setClass(n, '', true);
	else
		setClass(n, className, true);
}


function display(node, type) {
	var n = $(node);

	if(!n)
		return;

	n.style.display = type;
}

function toggle_display(node, type_on, type_off) {
	var n = $(node);

	if(!n)
		return;

	if(n.style.display == type_on)
		n.style.display = type_off;
	
	else if(n.style.display == type_off)
		n.style.display = type_on;
}

function clear(node) {
	var n = $(node);

	if(!n)
		return;

	while(n.firstChild)
		n.removeChild(n.firstChild)
}

function setText(node, s, _OPTIONAL_style) {
	clear(node);

	if(typeof(s) != 'string')
		return;

	$(node).appendChild($Text(s, _OPTIONAL_style));
}

function resetForm(node) {
	var n = $(node);

	if(!n)
		return;

	n.reset();
}

function getText(node) {
	var n = $(node);

	if(!n)
		return '';

	if(node.innerText)
		return node.innerText;

	if(node.textContent)
		return node.textContent;

	return '';
}

function nextNode(node, name) {
	if(node == null)
		return null;

	var x = node.nextSibling;

	while(x != null) {
		if(x.nodeName.toLowerCase() == name)
			return x;

		x = x.nextSibling;
	}

	return null;
}

function getMaxHeight(node) {
	var n = $(node);
	if(!n)
		return 0;
	
	var posy = n.offsetTop;
	
	while((n = n.offsetParent) != null)
		posy += n.offsetTop;
	
	var innerHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
	
	return (innerHeight - posy);
}

function maximizeElement(name, offset) {
	var height = getMaxHeight(name) + offset;

	$(name).style.height = height + 'px';
}

function swap_visibility(hide, show) {
	display(hide, 'none');
	display(show, '');
}

function swap_img(image) {

	var img = $(image);
	var src = img.src;
	var lowsrc = img.lowsrc;
	
	img.lowsrc = src;
	img.src = lowsrc;
}

function getAbsolutePosition(node) {
	var n = $(node);
	var pos = {x: 0, y: 0};

	pos.x = n.offsetLeft;
	pos.y = n.offsetTop;

	while((n = n.offsetParent) != null) {
		pos.x += n.offsetLeft;
		pos.y += n.offsetTop;
	}

	return pos;
}

function positionAlignBottomLeft(referenceNode, targetNode) {
	
	var upperleft = getAbsolutePosition(referenceNode);

	referenceWasHidden = isHidden(referenceNode);
	
	show(referenceNode);
	
	var x = upperleft.x;
	var y = upperleft.y + referenceNode.offsetHeight;

	if(referenceWasHidden)
		hide(referenceNode);
		
	setPosition(targetNode, x, y);
}


function setPosition(node, x, y) {
	
	var n = $(node);

	n.style.position = 'absolute';
	n.style.zIndex = '100';
	n.style.top = px(y);
	n.style.left = px(x);
}


function getDimension(node) {
	
	var node = $(node);
	var dim = { topleft: {x: 0, y: 0}, bottomright: {x: 0, y: 0}};

	dim.topleft = getAbsolutePosition(node);

	dim.bottomright.x = dim.topleft.x + node.offsetWidth;
	dim.bottomright.y = dim.topleft.y + node.offsetHeight;
	
	return dim;
}

function getRelativePosition(child, parent) {
	var cpos = this.getAbsolutePosition(child);
	var ppos = this.getAbsolutePosition(parent);

	var pos = {x: 0, y: 0};

	pos.x = cpos.x - ppos.x;
	pos.y = cpos.y - ppos.y;

	return pos;
}

function getPageDimension() {
	var dim = {x: 0, y: 0};

	if (document.body.scrollHeight > document.body.offsetHeight) {
		dim.x = document.body.scrollWidth;
		dim.y = document.body.scrollHeight;
	}
	else {
		dim.x = document.body.offsetWidth;
		dim.y = document.body.offsetHeight;
	}

	return dim;
}

function getInnerDimension() {
	var dim = {x: 0, y: 0};

	if (self.innerHeight) {
		dim.x = self.innerWidth;
		dim.y = self.innerHeight;
	}
	else if(document.documentElement && document.documentElement.clientHeight) {
		dim.x = document.documentElement.clientWidth;
		dim.y = document.documentElement.clientHeight;
	}
	else if(document.body) {
		dim.x = document.body.clientWidth;
		dim.y = document.body.clientHeight;
	}

	return dim;
}

function redirect(location) {

	if(typeof(location) == 'string')
		if(location.length > 0)
			document.location.href = location;
}


function url(path) {
	if(typeof(path) == 'string')
		return 'url(' + path + ')';
		
		
	// ~~~ ERROR Handling >>
	// *************************************************
	// Invalid Path
	// ---------------------------------
	location.href = GLOBAL['js_error']['error_page'] +
		'?errorMessage=' +
		escape('Fehler in Funktion url(): path');
	// *************************************************
	// ~~~ /ERROR Handling <<
}

// opacity: [0,100]
function setOpacity(node, opacity) {
	
	// ~~~ ERROR Handling >>
	// *************************************************
	// Invalid Opacity
	// ---------------------------------
	if(typeof(opacity) != 'number') {
		location.href = GLOBAL['js_error']['error_page'] +
			'?errorMessage=' +
			escape('Fehler in Funktion setOpacity(): opacity');
	}
	// *************************************************
	// ~~~ /ERROR Handling <<

	/* Valid Opacity */
	var n = $(node);
	n.style.opacity = opacity / 100;
	n.style.MozOpacity = opacity / 100;
	n.style.filter = 'alpha(opacity = ' + opacity + ')';
}


/* Only Use For SMALL Arrays - Removes ALL Similar Entries */
Array.prototype.remove = function(entryValue) {

	var array = [];
	
	for(var i=0; this[i]; i++)
		if(this[i] != entryValue)
			array.push(this[i]);
							
	return array;
}

function toggle_text(node) {

	var n = $(node);
	var currentText = getText(n);
	var alternativeText = n.getAttribute('alt');
	
	setText(n, alternativeText);
	n.setAttribute('alt', currentText);
}

