/**
 * EJSL
 * Java Skript Biliothek für Ephisa CMS
 *
 * Klassen:
 * - Drag
 * - Drop
 * - DragDrop
 * - Ajax
 * +-- XPath
 * +-- XSL
 * +-- Loader
 *
 * - Helper
 * - Element
 * - CSS
 * - Effects
 * - Effect
 *
 * Erweiterungen
 * - Array
 * - Number
 * - Function
 * - Object
 *
 * Interfaces
 * - CEnum
 *
 * Copyright 2007 by Philipp Serrer
 * All rights reserved
 *
 */
 
var ve=false;
var to=false;
var path = "";

function setPath(s)
{
	path=s;
}

function StatusMenuReset()
{
	if (to!=false) {
		clearTimeout(to);
	}
}

function StatusMenuHide()
{
	if (ve!==false) {
		$('uf_'+ve).style.display="none";
		ve=false;
		document.onclick=function() { }
	}
	StatusMenuReset();
}

function StatusMenuShow(i)
{
	StatusMenuHide();
	ve=i;
	$('uf_'+i).style.display="inline";
	
	startHideMenu();
}

function startHideMenu(n)
{
	if (n) {
		StatusMenuReset();
		document.onclick=function() { to=setTimeout("StatusMenuHide();",100); }
	}
	else
	{
		
		document.onclick=function() {};
		to=setTimeout("startHideMenu(1);",200);
		
	}
}

function toggleHidden(elm)
{
	if (typeof elm == "string") {
		elm=$(elm);
	}
	else if (elm.each)
	{
		elm.each(function(obj) { toggleHidden(obj); });
		return false;
	}
	
	elm.style.display = elm.style.display == "none" ? "" : "none";
}

function toggleMenuImage(elm,i1,i2)
{
	if (typeof elm == "string") {
		elm=$(elm);
	}
	
	if (!i1)
		i1="open.jpg";
	if (!i2)
		i2="close.jpg";
	
	if (baseName(elm.src)==i2) {
		elm.src = basePath(elm.src)+i1;
	}
	else
	{
		elm.src = basePath(elm.src)+i2;
	}
}

function basePath(path)
{
	return path.lastIndexOf("/") == -1 ? "" : path.substr(0, path.lastIndexOf("/")+1);
}

function baseName(path)
{
	return path.lastIndexOf("/") == -1 ? path : path.substr(path.lastIndexOf("/")+1);
}


//Prototypen
var SystemHandlers=new Array();

Object.addElements = function(object, elements)
{
  for (element in elements) {
    object[element] = elements[element];
  }
	
  return object;
}

if (!window.Event) {
  var Event = new Object();
}
if (!window.Element) {
  var Element = new Object();
}

var Switcher = new Object();

Object.addElements(Switcher, {
	
	data: false,
	
	s: function(elm,n) {
		
		if (!n) {
			n = "_main";
		}
		
		if (!this.data) {
			this.data = new Object;
		}
		
		if (this.data[n] == elm)
			return;
		
		if (this.data[n]) {
			var h = this.data[n];
			Effects._(h,true).hide({duration: 100, after: function()
			{
				Effects._(elm,true).hide({from: 0, to:1, duration: 200});
				Element.setStyle(h, "display", "none");
				Element.setStyle(elm, "display", "");
			}});
		}
		else
		{
			Element.setStyle(elm, "display", "");			
		}
		
		this.data[n] = elm;
	}
	
});

var Menu = new Object(function() { });

Object.addElements(Menu.prototype, {
	
	hi: false,
	menu: false,
	init: false,
	enter: false,
	
	onhide: false,
	
	show: function(elm,display)
	{
		var mnu = this;
		if (!this.init) {
			this.init = true;
			Event.addHandler("click", document, function (event) { mnu.hide(event); }.bindEvent(this));
			Event.addHandler("mousemove", document, function (event) { mnu.hide(event,1500); }.bindEvent(this));
		}
		
		if (typeof elm == "string") {
			elm = $(elm);
		}
		
		if (this.menu && this.menu != elm) {
			this.menu.style.display = "none";
		}
		
		if (display)
			elm.style.display=display;
		else
			elm.style.display="";
		
		elm.style.zIndex = "1000000000";
		
		this.enter = false;
		this.menu = elm;
	},
	
	hide: function(e,timeout)
	{
		var mnu = this;
		if (!this.menu) {
			return false;
		}
		
		if (e) {
			if (Element.hitTest(this.menu, Event.x(e), Event.y(e))) {
				window.clearTimeout(this.hi);
				this.enter = true;
				this.hi = false;
				return false;
			}
		}
		
		if (!this.enter)
		{
			return false;
		}
		
		if (timeout) {
			if (!this.hi) {
				this.hi = window.setTimeout(function() { mnu.hide(); },timeout);
			}
			return true;
		}
		else
		{
			this.menu.style.display = "none";
		}
		
		this.menu = false;
		this.enter = false;
		
		if (this.onhide) {
			this.onhide(this);
		}
	}
	
});


var Drag = new Object();
var Drop = new Object();
var DragDrop = new Object();

Object.addElements(DragDrop,
	{
		Draggabels: new Array(),
		Droppabels: new Array(),
		ActiveElement: false,
		pos: false,
		lastPos: false,
		
		init: function()
		{
			Event.addHandler("mousemove",document,this.onmousemove.bindEvent(this));
			Event.addHandler("mouseup",document,this.onmouseup.bindEvent(this));
		},
		
		onmousemove: function(event)
		{
			if (!this.ActiveElement || Helper.equals(Event.position(event), this.lastPos))
				return false;
				
			var opts = this.ActiveElement;
			var elm = opts.elm;
			var p = this.pos;
			
			
			this.lastPos = Event.position(event);
			
			if (!p) {
				p = Element.absPosition(elm);
				p = [Math.abs(p[0] - Event.x(event)) , Math.abs(p[1] - Event.y(event))];
				
				this.pos=p;
			}
			
			
			if (opts.ghost && elm._clone) {
				elm = elm._clone;
			}
			
			elm.style.top=(Event.y(event)-p[1])+"px";
			elm.style.left=(Event.x(event)-p[0])+"px";
			
			return false;
		},
		
		onmouseup: function(event)
		{
			if (Drop.ActiveElement && Drop.ActiveElement.ondrop) {
				Drop.ActiveElement.ondrop(event, this.ActiveElement);
			}
			if (Drag.ActiveElement && Drag.ActiveElement.ondrop) {
				Drag.ActiveElement.ondrop(event, this.ActiveElement);
			}
			
			if (this.ActiveElement.ghost) {
				Element.remove(this.ActiveElement.elm._clone);
				this.ActiveElement.elm._clone=null;
			}
			
			this.ActiveElement = Drop.ActiveElement = Drag.ActiveElement = false;
			this.pos=false;
			
			return;
		},
		
		draggingElement: function()
		{
			return (this.ActiveElement ? (this.ActiveElement.ghost ? this.ActiveElement.elm._clone : this.ActiveElement.elm) : alert(false));
		}
	}
);

Object.addElements(Drag,
	{

		addElement: function(id)
		{
			var elm;
			var opts = {
				ghost: true,
				dragging: true,
				ondrag: false,
				ondrop: false,
				snap: false
			}

			if (!id)
				return false;
			else if (typeof id == "string")
				elm = $(id)
			else
				elm = id;
			
			Object.addElements(opts, arguments[1] || {} );
			opts.elm = elm;
			
			DragDrop.Draggabels.push(opts);
			DragDrop.init();
			//elm.style.position="absolute";
			elm.style.zindex=1000;
			
			var cb = function(event) { Drag.onmousedown(event,opts); return false; }.bindEvent(this);
			
			elm.onmousedown = cb;
			//Event.addHandler("mousedown",elm, cb);
			
			Event.addHandler("click",elm, function(event) { return false; }.bindEvent(this));
		},
		
		onmousedown: function(event,opts)
		{
			var elm = opts.elm;
			var _clone = false;
			
			DragDrop.ActiveElement = opts;
			
			if (opts.dragging) {
				if (opts.ghost) {
					_clone = elm.cloneNode(true);
					Element.setOpacity(_clone, 0.7);
					
					elm._clone = _clone;
					elm.parentNode.insertBefore(_clone,elm);
					if (!elm.style.width) {
						_clone.style.width = (elm.offsetWidth - parseInt(elm.style.paddingLeft) - parseInt(elm.style.paddingRight)) + "px";
					}
				}
				else
				{
					_clone = elm;
					elm._oldPosition = elm.style.position;
				}
				
				_clone.style.position = "absolute";
				_clone.style.zIndex = 1000000;
				
				if (opts.ondrag)
					opts.ondrag(event, opts);
			}
			
			return false;
		}
		
	}
);

Object.addElements(Drop,
	{
		ActiveElement: false,
		refElm: false,
		
		addElement: function(elm)
		{
			if (typeof elm == "string")
				elm = $(elm);
			
			if (!elm)
				return false;
			
			var opts = {
				ondrop: false,
				highlight: true
			};
			
			Object.addElements(opts, arguments[1] || {} );
			opts.elm = elm;
				
			DragDrop.Droppabels.push(opts);
			
			Event.addHandler("mousemove", document, function(event) { Drop.onmousemove(event,elm) }.bindEvent(this));
		},
		
		onmousemove: function(event, elm)
		{
			var found = false;
			
			if (!DragDrop.ActiveElement)
				return;
				
			DragDrop.Droppabels.each(function(opts,idx)
			{
				var elm = opts.elm;
				
				if (Element.hitTest(elm, Event.x(event), Event.y(event))) {
					
					if (Drop.ActiveElement.elm != elm) {
						if (opts.highlight)
							Effects._(elm).blink({swap: true});
						
						Drop.ActiveElement = opts;
						
						if (opts.onmove) {
							opts.onmove(elm, opts);
						}
						
						if (DragDrop.ActiveElement.snap)
							elm.appendChild(DragDrop.draggingElement());
					}
					
					if (DragDrop.ActiveElement.snap) {
						this.refElm = Element.insertRelative(DragDrop.draggingElement(), elm, Event.x(event), Event.y(event), this.refElm);
						DragDrop.draggingElement().style.position = "";
					}
					
					found = true;
				}
			});
			
			if (!found) {
				this.ActiveElement = false;
				DragDrop.draggingElement().style.position = "absolute";
			}
		}
		
	}
);

var AJAX = new Object(function() { });
AJAX.XPath = new Object(function(xmldoc) { this.xdoc = xmldoc; });
AJAX.XSL = new Object(function() { });
AJAX.Loader = new Object(function(elm,gfx) { this.init(elm,gfx); });

Object.addElements(AJAX.prototype, 
	{
		xml: false,
		callbacks: new Array(),
		
		_error: function()
		{
			//Wenn der Status nicht 200 ist(also Fehler) eine Fehlermeldung ausgeben
			//404 ist "Seite nicht gefunden"
			if (this.xml.status==404) {
				var text="404: Seite nicht vorhanden";
			}
			else
			{
				var text="Fehler " + this.xml.status + ": " + this.xml.statusText;
			}
			
			alert("Fehler beim Empfangen:\n\n"+text);	//Fehlermeldung ausgeben
		},
		
		init: function()
		{
			this.xml=this.loadXML();
			
			if (this.xml.overrideMimeType)
			{
				this.xml.overrideMimeType('text/xml');	//Mime Type überschreiben mit XML
			}
			
			this.xml.onreadystatechange = this._response.bind(this);
			
		},
		
		addAction: function(action, callback)
		{
			if (!this.callbacks) {
				this.callbacks = new Array();
			}
			
			this.callbacks[action] = callback;
		},
		
		handleEvent: function(action, callback)
		{
			this.addAction(action, callback);
		},
		
		_response: function()
		{
			//this.xml=AJAX.xml;
			//this.callbacks=AJAX.callbacks;
			
			if (this.xml.readyState == 4) {
				if (this.xml.status==200) {
					var xmldoc = this.xml.responseXML.documentElement;
					var xpath = new AJAX.XPath(xmldoc);
					var action = xpath.selectNode("/data/action");				
					
					if (action.length==0 && this.callbacks[0]) {
						this.callbacks[0](xmldoc,this.xml);
					}
					else if (action.length != 0 && action)
					{
						action = action.nodeValue;

						if (this.callbacks[action]) {
							this.callbacks[action](xmldoc,this.xml);
						}
					}
					
				}
				else
				{
					AJAX._error();
				}
			}
		},
		
		loadXML: function()
		{
			tmp=false;
	
			try {
				if (window.ActiveXObject)
				{	
					try
					{
						tmp = new ActiveXObject("Msxml2.XMLHTTP");
					}
					catch (e)
					{
						tmp = new ActiveXObject("Microsoft.XMLHTTP");
					}
				}
				else if (window.XMLHttpRequest)
				{
					tmp = new XMLHttpRequest();
				}
				else
				{
					alert("Ajax wird nicht unterstützt");
					var tmp=false;
				}
			}
			catch (e)
			{
				alert("Ajax konnte nicht geladen werden");
				var tmp=false;
			}
			
			return tmp;
		},
		
		createParamList: function(data)
		{
			var tmp="";
			
			if (!data)
				return tmp;
			
			for (obj in data) {
				//Nur Strings
				if (typeof data[obj] == "string") {
					if (tmp != "") {
						tmp += "&";
					}
					
					tmp += obj+"="+encodeURIComponent(data[obj]);
				}
			}
			
			return tmp;
		},
		
		post: function(uri,data)
		{
			var tmp=this.createParamList(data);
			
			this.init();
			this.xml.open('POST', uri, true);
			
			this.xml.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
			this.xml.setRequestHeader("Content-length", tmp.length);
			
			//Daten senden
			this.xml.send(tmp);
			
			return true;
		},
		
		get: function(uri,data)
		{
			if (data)
				uri+="?"+this.createParamList(data);

			this.init();
			this.xml.open('GET', uri, true);
			this.xml.send(null);
		}
	}
);


Object.addElements(AJAX.XSL.prototype, {
	
	xsl: false,
	
	load: function(file)
	{
		var xsl;
		
		try {
			
			if (window.ActiveXObject) {
				xsl = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
			}
			else if (window.XSLTProcessor)
			{
				xsl = document.implementation.createDocument("","",null);
			}
			
			xsl.async = false;
			xsl.load(file);
			
			this.xsl = xsl;
			
			return this;
		}
		catch (e)
		{
			return false;
		}
	},
	
	transform: function(xmldoc, append)
	{
		var processor;
		var i;
		var elm;
		var tmp;
		
		if (!this.xsl) {
			return false;
		}
		
		try {
			
			if (window.ActiveXObject) {
				var elm;
				var tpl = new ActiveXObject("Msxml2.XSLTemplate");
				tpl.stylesheet = this.xsl;
				
				processor = tpl.createProcessor();
				processor.input = xmldoc;
				
				processor.transform();
				
				if (append) {
					tmp = processor.output;
					
					//Hack, für den Fall, das ein <tr>..</tr> Tag eingefügt werden soll...
					if (tmp.substr(0,3) == "<tr") {
						tmp = "<table>" + tmp + "</table>";
						elm = Element.newElement("div");
						elm.innerHTML = tmp;
						
						for (i=0; i < elm.firstChild.childNodes.length; i++) {
							append.appendChild(elm.firstChild.childNodes.item(i));
						}
					}
					else
					{
						append.innerHTML += processor.output;
					}
					
					
					return true;
				}
				else
				{
					return Element.newElement("div", { innerHTML: processor.output });
				}
			}
			else if (window.XSLTProcessor)
			{
				xsl = document.implementation.createDocument("","",null);
				
				processor = new XSLTProcessor();
				processor.importStylesheet(this.xsl);
				
				if (append) {
					append.appendChild(processor.transformToFragment(xmldoc, document));
					return true;
				}
				else
				{
					return processor.transformToFragment(xmldoc, document);
				}
			}
			
		}
		catch (e)
		{
			return false;
		}
	}
	
});



Object.addElements(AJAX.XPath.prototype, {
	
	xdoc: false,
	
	selectNodes: function(n,d)
	{
		var ret = new Array();
		var xeval;
		var res;
		var doc = this.xdoc;
		
		if (!doc && !d) {
			return false;
		}
		else if (d)
		{
			doc = d;
		}
		
		try {
			if (window.ActiveXObject) {
				ret = doc.selectNodes(n);
			}
			else if(window.XPathEvaluator)
			{
				
				xeval = new XPathEvaluator();
				res = xeval.evaluate(n, doc, null, XPathResult.ORDER_NODE_ITERATOR_TYPE, null);

				ret = $A(res);
			}
			
			return ret;
		}
		catch (e)
		{
			return ret;
		}
		
	},
	
	selectNode: function(n,d)
	{
		var ret = new Array();
		var xeval;
		var res;
		var doc = this.xdoc;
		
		if (!doc && !d) {
			return false;
		}
		else if (d)
		{
			doc = d;
		}
		
		try {
			if (window.ActiveXObject) {
				ret = doc.selectSingleNode(n);
			}
			else if(window.XPathEvaluator)
			{
				
				xeval = new XPathEvaluator();
				res = xeval.evaluate(n, doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);

				ret = res.singleNodeValue;
			}
			
			if (ret) {
				return ret.firstChild;
			}
			else
			{
				return false;
			}
		}
		catch (e)
		{
			return ret;
		}
		
	},
	
	selectNodeValue: function(n,d)
	{
		var value = this.selectNode(n,d);
		
		return value ? value.nodeValue : "";
	}
	
});

Object.addElements(AJAX.Loader.prototype, {
	
	gfx: "../images/round.gif",
	img: false,
	shadow: false,
	elm: false,
	
	init: function(elm, gfx)
	{
		if (!elm) {
			this.elm = false
		}
		else
		{
			this.elm = elm;
		}
		
		if (!gfx) {
			this.gfx = "../images/round.gif";
		}
		else
		{
			this.gfx = gfx;
		}
		
		Event.addHandler("resize", window, function(e,l) {
			if (l.bshow == true) {
				l.show();
			}
		}.bindEvent(this,this));
		
		this.img = Element.newElement("img",{ src: this.gfx}, { border:"0", position: "absolute", display: "none" });
		this.shadow = Element.newElement("div",false, { backgroundColor:"#000", opacity: .55, position: "absolute", display:"none" });
	},
	
	getShadow: function()
	{
		return this.shadow;
	},
	
	show: function(elm)
	{		
		if (!elm) {
			if (this.elm) {
				elm = this.elm;
			}
			else
			{
				return false;
			}
		}
		
		var p = Element.absPosition(elm);
		
		if (this.shadow) {
			document.body.appendChild(this.shadow);
			
			
			Element.setStyle(this.shadow, {
				display: "block",
				
				width: elm.offsetWidth + "px",
				height: elm.offsetHeight + "px",
				
				left: p[0] + "px",
				top: p[1] + "px"
				});
		}

		if (this.img) {
			document.body.appendChild(this.img);
			
			Element.setStyle(this.img, {
				display: "",
				
				left: (p[0] + (elm.offsetWidth/2 - this.img.offsetWidth/2) ) + "px",
				top: (p[1] + (elm.offsetHeight/2 - this.img.offsetHeight/2) ) + "px"
				});
		}
		
		this.bshow = true;
	},
	
	hide: function()
	{
		
		if (this.img) {
			Element.setStyle(this.img, "display", "none");
		}
		
		if (this.shadow) {
			Element.setStyle(this.shadow, "display", "none");
		}
		
		this.bshow = false;
	},
	
	getLoadGrafic: function()
	{
		return this.gfx;
	},
	
	setLoadGrafic: function(gfx)
	{
		this.gfx = gfx;
	}
	
});


var Helper = new Object();

Object.addElements(Helper,
	{
		setFilter: function(elm, filter, value)
		{			
			this.removeFilter(elm, filter);
			elm.style.filter += " " + filter + "(" + value + ")";
		},
		
		removeFilter: function(elm, filter)
		{
			if (!elm.style.filter)
				return false;
			
			var rg = new RegExp(filter+"\\([^\\)]*\\)","gi");
			var f = elm.style.filter.replace(rg,'');
			
			if (!f) {
				elm.style.filter = null;
			}
			else
			{
				elm.style.filter = f;
			}
		},
		
		isArray: function(data)
		{
			return typeof data == "object" && data.constructor == Array;
		},
		
		isUndef: function(data)
		{
			return typeof data == "undefined";
		},
		
		equals: function(s, d)
		{
			if (typeof s != typeof d) {
				return false;
			}
			else
			{
				if (typeof s == "object") {
					if (this.isArray(s) && this.isArray(d)) {
						if (s.length != d.length)
							return false
						
						for (var i = 0; i < s.length; i++)
							if (s[i] !== d[i])
								return false;
						
						return true;
					}
				}
			}
			
			return s == d;
		}
	}
);


var Element = new Object();

Object.addElements(Element,
	{
		newElement: function(elm, props, style)
		{
			var e = document.createElement(elm);
			
			if (props) {
				for (it in props) {
					e[it] = props[it];
				}
			}
			
			if (style) {
				this.setStyle(e, style);
			}
			
			return e;
		},
		
		newMenu: function(list) {
			var ul = document.createElement("ul");
			var li;
			var a;
			
			for (var i = 0; i < list.length; i++) {
				li = document.createElement("li");
				a = this.newElement("a",list[i]);
				
				ul.appendChild(li);
				li.appendChild(a);
			}
			
			return ul;
		},
		
		absPosition: function(elm)
		{
			if (!elm.offsetParent)
				return [elm.offsetLeft || 0, elm.offsetTop || 0];
			
			var pp = this.absPosition(elm.offsetParent);
			return [elm.offsetLeft+pp[0], elm.offsetTop+pp[1]];
		},
		
		insertRelative: function(elm, parent, x, y, r)
		{
			//$("b").innerHTML=(x + "," + y) + "<br />";
			for (var i = 0; i < parent.childNodes.length; i++)
			{
				if (this.hitTest(parent.childNodes[i], x, y))
				{
					var node = parent.childNodes[i];
					var p = this.absPosition(node);
					
					
					//$("b").innerHTML += ( + (node.offsetWidth / 2)) + ":";
					if (x < p[0] + node.offsetWidth / 2) {
						if (r == node)
							return node;
						
						parent.insertBefore(elm, node);
					}
					else
					{
						node = node.nextSibling;
						if (node == null) {
							parent.appendChild(elm);
						}
						else
						{
							if (node == r)
								return r;
							parent.insertBefore(elm, node);
						}
					}
					
					return node;
				}
			}
						
			return null;
		},
		
		hitTest: function(elm, x, y)
		{
			var p = this.absPosition(elm);
			
			return (x >= p[0] && x <= (p[0] + elm.offsetWidth) && y >= p[1] && y <= (p[1] + elm.offsetHeight));
		},
		
		remove: function(elm)
		{
			if (!elm)
				return;
			elm.parentNode.removeChild(elm);
			return elm;
		},
		
		//Werden gebraucht, da der IE und FF für manche Styles verschiedene Namen haben
		setStyle: function(elm, style, value)
		{
			if (typeof style == "object") {
				for (it in style) {
					if (typeof style[it] == "string" || typeof style[it] == "number") {
					this.setStyle(elm, it, style[it]);
				}
				}
				return;
			}
			
			switch (style)
			{
			case "float":
				if(/MSIE/.test(navigator.userAgent))
					elm.style["styleFloat"] = value;
				else
					elm.style["cssFloat"] = value;
				break;
			
			case "opacity":
				this.setOpacity(elm,value);
				break;
			
			case "display":
				if (value == "none" && elm._alpha_clone) {
					
					elm._alpha_clone.style.visibility = "visible";
					elm._alpha_clone.style.display = "none";
				}
			
			default:
				elm.style[style]=value;
			}
		},
		
		getStyle: function(elm, style)
		{
			switch (style)
			{
			case "float":
				if(/MSIE/.test(navigator.userAgent))
					return elm.style["styleFloat"];
				else
					return elm.style["cssFloat"];
				break;
			
			case "opacity":
				return this.setOpacity(elm);
				break;
			
			default:
				return elm.style[style];
			}
		},
		
		setOpacity: function(elm,value)
		{
			if (value == 1) {
				if(/MSIE/.test(navigator.userAgent)) {
					Helper.removeFilter(elm, "alpha");
					
					if (elm.nodeName != "div" && elm.style.display != "block") {
						
						if (elm._alpha_clone && typeof elm._alpha_pos != "undefined") {
							elm.style.position = elm._alpha_pos ? elm._alpha_pos : "";
							elm._alpha_pos = null;
							elm.parentNode.insertBefore(elm, elm._alpha_clone);
							elm._alpha_clone.style.display = "none";
							elm._alpha_clone.style.position = "absolute";
							elm.style.visibility = "visible";
						}
					}
				}
				else
				{
					elm.style.opacity=null;
				}
			}
			else
			{
				value = value < 0.0001 ? 0 : value;
				
				if(/MSIE/.test(navigator.userAgent)) {
					Helper.setFilter(elm, "alpha", "opacity="+(value*100));
					
					//Transparenz geht nur mit hasLayout Elementen...
					if (elm.currentStyle.hasLayout) {
						return;
					}
					else if (elm.nodeName == "div" || elm.style.display == "block")
					{
						if (!elm.style.height && !elm.style.width && elm.style.position != "absolute") {
							elm.style.height = "1%";
						}
					}
					else
					{
						var c;
						
						if (!elm.parentNode) {
							return;
						}
						
						if (elm._alpha_clone) {
							c = elm._alpha_clone;
						}
						else
						{
							c = elm.cloneNode(true);
						}
						
						if (elm.nextSibling) {
							elm.parentNode.insertBefore(c, elm.nextSibling);
						}
						else
						{
							elm.parentNode.appendChild(c);
						}
						
						if (typeof elm._alpha_pos == "undefined") {
							elm._alpha_pos = elm.style.position;
						}
						
						elm.style.position = "absolute";
						c.id = "";
						c.style.display = "";
						c.style.visibility = "hidden";
						elm._alpha_clone = c;
					}
				}
				else
				{
					elm.style.opacity=value;
				}
			}
		},
		
		getOpacity: function(elm)
		{
			if (elm.style.opacity)
			{
				return elm.style.opacity;
			}
			else if(elm.style.filter) //Internet Explorer
			{
				var m = elm.style.filter.match(/alpha\(opacity=(.*)\)/i);
				return m[1] ? parseFloat(m[1] / 100) : 1.0;
			}
			
			return 1.0;
		}
	}
);

var CSS = new Object();

Object.addElements(CSS,
	{
		getClasses: function(element)
		{
			return element.className.split(" ");
		},
		
		classExists: function(element,className)
		{
			var classes=false;
			
			if (typeof element.className != 'undefined') {
				element=element.className.split(" ");
			}
			
			if (typeof element == 'string')
			{
				classes=element.split(" ");
			}
			else if (typeof element == 'object')
			{
				classes=element;
			}
			else
			{
				return false;
			}
			
			return classes.isIn(className);
		},
		
		//Klasse hinzufügen
		addClass: function(element,className)
		{			
			if (typeof element.className == 'undefined') {
				return false;
			}
			
			if (!this.classExists(element,className)) {				
				if (element.className=="") {
					element.className=className;
				}
				else
				{
					element.className+=" "+className;
				}
			}
			
			return element;
		},
		
		//Klasse rauswerfen
		removeClass: function(element,className)
		{
			if (typeof element.className == 'undefined') {
				return false;
			}
			
			if (this.classExists(element,className)) {
				element.className=element.className.split(" ").without(className).concatString(" ");
			}
			
			return element;
		}
	}
);

//Effekte
var runningQueue = new Array();


var Effects = {
	_: function(elm,s) {
		var f=false;
		var e=false;
		
		if (!elm)
			return false;
		
		if (typeof s != "undefined" && s) {
			e = new Effect();
			e.elm = elm;
			e.opts = {};
		}
				
		e = elm._effect;
		
		if (e)
			return e;
		
		e = new Effect();
		e.elm = elm;
		e.opts = {};
		
		elm._effect = e;
				
		return e;
	},
	
	clearQueue: function(elm)
	{
		elm.queue = new Array();
	},
	
	getOpts: function(elm)
	{
		return elm._effect.opts;
	}
};


var Effect = new Object(function() { });

Object.addElements(Effect.prototype, {
	elm:false,
	interval:false,
	startTime:0,
	id:0,
	bStart:false,
	
	queue:new Array(),
	
	opts: false,
	
	jump: function(opts)
	{
		var from;
		
		opts=this.prepare(opts);
		
		if (typeof opts.from == "object" && typeof opts.from.length!="undefined" && opts.from.length>=2) {
			from=opts.from;
		}
		else
		{
			from=new Array(parseInt(this.elm.style.marginTop ? this.elm.style.marginTop : 0),parseInt(this.elm.style.marginBottom ? this.elm.style.marginBottom : 0));
		}
		
		this.elm._effect.queue.push({
			effect:this.jump_.bind(this),
			from:from,
			to:parseInt(opts.to),
			duration:opts.duration,
			obj:this.elm,
			after:opts.after,
			before:opts.before
		});


		if (opts.start) {
			this.start();
		}
		
		return this;
	},
	
	blink: function(opts)
	{
		opts.blink=true;
		opts.from=this.elm.style.backgroundColor ? this.prepareColor(this.elm.style.backgroundColor) : "ffffff";

		this.opts.startColor = this.prepareColor(this.elm.style.backgroundColor);
		
		if (!opts.to)
			opts.to="ffff99";
		if (!opts.duration)
			opts.duration=500;
			
		if (opts.swap) {
			var tmp = opts.to;
			opts.to = opts.from;
			opts.from = tmp;
			opts.blink=false;
		}
		
		return this.changeColor(opts);
	},
	
	changeColor: function(opts)
	{
		
		opts=this.prepare(opts);
		
		this.elm._effect.queue.push({
			effect:this.changeColor_.bind(this),
			from:this.prepareColor(opts.from),
			to:this.prepareColor(opts.to),
			duration:opts.duration,
			obj:this.elm,
			after:opts.after,
			before:opts.before,
			blink:opts.blink
		});


		if (opts.start) {
			this.start();
		}
		
		return this;
	},
	
	hide: function(opts)
	{
		
		if (!opts) {
			opts = {};
		}
		
		if (typeof opts.to == "undefined") {
			opts.to=0;
		}
		if (typeof opts.from == "undefined") {
			opts.from=1;
		} 
		
		opts=this.prepare(opts);
		
		this.elm._effect.queue.push({
			effect: this.opacity_.bind(this),
			from: opts.from,
			to: opts.to,
			duration: opts.duration,
			obj: this.elm,
			after: opts.after,
			before: opts.before
		});


		if (opts.start) {
			this.start();
		}
		
		return this;
	},
	
	resize: function(opts)
	{
		var from,to;
		
		opts=this.prepare(opts);
		if (!opts)
			return false;
		
		from=opts.from.split("x");
		to=opts.to.split("x");
		
		if (from.length<2 || to.length<2) {
			return false;
		}
		
		this.elm._effect.queue.push({
			effect:this.resizeX_.bind(this),
			from:parseInt(from[0]),
			to:parseInt(to[0]),
			duration:opts.duration,
			obj:this.elm,
			after:opts.after,
			before:opts.before
		});
		
		this.elm._effect.queue.push({
			effect:this.resizeY_.bind(this),
			from:parseInt(from[1]),
			to:parseInt(to[1]),
			duration:opts.duration,
			obj:this.elm,
			after:opts.after,
			before:opts.before
		});
		
		if (opts.start) {
			this.start();
		}
		
		return this;
	},
	
	prepare: function(opts)
	{
		if (typeof opts.from == 'undefined' &&
				typeof opts.to == 'undefined') {
			return false;			
		}
		
		if (typeof opts.duration == 'undefined') {
			opts.duration = 1000;
		}
		
		if (typeof opts.start == 'undefined') {
			opts.start = true;
		}
		
		return opts;
	},
	
	
	prepareColor: function(color)
	{
		
		if (typeof color == "number")
			return color;
		
		if (color.substr(0,1)=="#")
			color=color.substr(1);
		
		
		if (color.substr(0,4)=="rgb(") {
			color=color.substr(4,color.length-5);
			color=color.split(",");
			color=parseInt(color[0]).fH()+parseInt(color[1]).fH()+parseInt(color[2]).fH();
		}
		
		//Farbwert?
		if (isNaN("0x"+color)) {
			return false;
		}
		
		if (color.length==3)
			color=color.substr(0,1).repeat(2)+color.substr(1,1).repeat(2)+color.substr(2,1).repeat(2);
		else if(color.length!=6)
			return false;
			
		return parseInt("0x"+color);
	},
	
	
	start: function()
	{
		//Start...
		if (this.bStart==true) {
			return;
		}
		
		this.startTime = new Date().getTime();
		
		this.queue.each(function (obj,idx) {
			if (typeof obj.before == "function") {
				obj.before(obj);
			}
		});
				
		this.bStart=true;
		this.interval = setInterval(this.loop.bind(this),40);
	},
	
	stop: function()
	{
		this.bStart=false;
		clearInterval(this.interval);
		
		if (typeof this.opts.startColor != "undefined") {
			if (this.opts.startColor === false) {
				this.elm.style.backgroundColor = "";
			}
			else
			{
				this.elm.style.backgroundColor = this.opts.startColor;
			}
		}
		
		this.opts.startColor = null;
	},
	
	loop: function()
	{
		var now = new Date().getTime();
		var fC = 0, time = this.startTime;
		
		this.elm._effect.queue.each(function (obj,idx) {
			var pos=(now-time) / (obj.duration);
			
			if (obj.finished) {
				fC++;
				return
			}

			if (now>time+obj.duration) {
				fC++;
				obj.effect(1,obj);
				obj.finished=true;
				
				if (typeof obj.after == "function") {
					obj.after(obj);
				}
				return;
			}
			
			obj.effect(pos,obj);
			
		}.bind(this));
		
		if (fC>=this.queue.length) {
			this.stop();
			this.queue.each(function (obj,idx) {
				if (!obj.finished) {
					obj.effect(1,obj);
				}
			});
			
			this.elm._effect.queue = new Array();
			
			Effects.clearQueue(this.elm);
			
			runningQueue = runningQueue.without(this);
		}
	},
	
	changeColor_: function(pos,obj)
	{
		if (obj.blink)
			pos=Math.sin(pos*Math.PI).toFixed(2);

		obj.obj.style.backgroundColor="#"+( (obj.from >> 16 & 0xff) + parseInt( ( (obj.to >> 16 & 0xff)-(obj.from >> 16 & 0xff) )*pos)).toColorPart()+
								((obj.from >> 8 & 0xff)+parseInt(((obj.to >> 8 & 0xff)-(obj.from >> 8 & 0xff))*pos)).toColorPart()+
								((obj.from >> 0 & 0xff)+parseInt(((obj.to >> 0 & 0xff)-(obj.from >> 0 & 0xff))*pos)).toColorPart();
	},
	
	opacity_: function(pos,obj)
	{
		Element.setStyle(obj.obj, "opacity", obj.from+(obj.to-obj.from)*pos);
	},
	
	jump_: function(pos,obj)
	{
		obj.obj.style.marginBottom=parseInt(obj.from[1]+(obj.to+obj.from[0])*Math.sin(pos*Math.PI).toFixed(2))+"px";
		obj.obj.style.marginTop=parseInt(obj.from[0]-(obj.to+obj.from[0])*Math.sin(pos*Math.PI).toFixed(2))+"px";
	},
	
	resizeX_: function(pos,obj)
	{
		obj.obj.style.width=parseInt(obj.from+(obj.to-obj.from)*pos)+"px";
	},
	
	resizeY_: function(pos,obj)
	{
		obj.obj.style.height=parseInt(obj.from+(obj.to-obj.from)*pos)+"px";
	}
	
});


// Funktionshandler
Object.addElements(Event,
	{
		addHandler: function(name,element,callback)
		{
			if (element.attachEvent) {
				element.attachEvent("on"+name,callback);
			}
			else if (element.addEventListener)
			{
				element.addEventListener(name,callback,false);
			}
		},
		
		removeHandler: function(name, element, callback)
		{
			if (element.removeEventListener) {
				element.removeEventListener(name, callback, false);
			}
			else if (element.detachEvent)
			{
				element.detachEvent(name, callback);
			}
		},
		
		x: function(event)
		{
			return event.pageX || (event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft));
		},
		
		y: function(event)
		{
			return event.pageY || (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop));
		},
		
		position: function(event)
		{
			return [this.x(event), this.y(event)];
		}
		
	}
);


//Auflistungen - Enumerationen
var CEnum = {
	
	//Alle Elemente durchlaufen
	each: function(iterator) {
		var l=0;
		
		if (typeof this.length == 'function')
		{
			l=this.length();
		} 
		else if (typeof this.length == 'number')
		{
			l=this.length;
		}
		else
		{
			return false;
		}
		
		for (var i=0; i<l; i++) {
			if (iterator(this[i],i) === false) {
				return;
			}
		}
	},
	
	//Ist ein Wert vorhanden?
	isIn: function(data) {
		for (var i=0; i<this.length; i++) {
			if (this[i]==data) {
				return true;
			}
		}
		return false;
	},
	
	//Alle Ergebnisse in Array Speichern
	all: function(iterator) {
		var ret = new Array();
		var val;
		
		this.each(function(obj,idx) {
			val=iterator(obj,idx);
			if (val!=null)
				ret.push(iterator(obj,idx));
		});
		
		return ret;
	},
	
	//Größtes Element
	max: function() {
		var max;
		
		if (this.length==0)
			return false;
		else
			max=this[0];
		
		this.each(function (obj,idx) { max=obj>max?obj:max; });
		
		return max
	},
	
	//Kleinstes Element
	min: function() {
		var min;
		
		if (this.length==0)
			return false;
		else
			min=this[0];
		
		this.each(function (obj,idx) { min=obj<min?obj:min; });
		
		return min;
	},
	
	//Erstes Element
	first: function() {
		if (this.length==0)
			return false;
		else
			return this[0];
	},
	
	//Letztes Element
	last: function() {
		if (this.length==0)
			return false;
		else
			return this[this.length-1];
	},
	
	//Nur Elemente anhängen bei denen iterator true zurückgibt
	which: function(iterator) {
		var ret=new Array();
		
		this.each(function (obj,idx) { if (iterator(obj,idx)) ret.push(obj); });
		
		return ret;
	},
	
	//Solange bis iterator false zurückgibt Elemente anhängen
	until: function(iterator) {
		var ret=Array();
		var fbreak=false;
		
		this.each(function (obj,idx)
		{
			if (!fbreak && iterator(obj,idx))
				ret.push(obj);
			else
				fbreak=true;
		});
		
		return ret;
	},
	
	//Alle Elemente, auser
	without: function(data) {
		var ret=new Array();
		
		this.each(function (obj) { if (obj!=data) ret.push(obj); });
		
		return ret;
	},
	
	//Alle Elemente > number
	gt: function(number) {
		var ret=new Array();
		
		this.each(function (obj,idx) { if (typeof obj == 'number' && obj>number) ret.push(obj); });
		
		return ret;
	},
	
	//Alle Elemente < number
	lt: function(number) {
		var ret=new Array();
		
		this.each(function (obj,idx) { if (typeof obj == 'number' && obj<number) ret.push(obj); });
		
		return ret;
	},
	
	//ALle Elemente mit value Eigenschaft durchsuchen und schauen ob etwas darin steht
	areEmpty: function() {
		var ret=new Array();
		
		this.each(function (obj,idx) { if (typeof obj.value != 'undefined' && !obj.value) ret.push(obj);});
		
		return ret;
	},
	
	//unterstützt die getAttribute Funktion und besitzt ein bestimmtes Attribut (evtl. auch mit dem Wert(value)
	haveAttribute: function(attribute,value) {
		var ret=new Array();
		var found=false;
		
		this.each(function (obj,idx) {
			
			if (obj.getAttribute) {
				if (obj.getAttribute(attribute)!=null) {
					if (arguments.length == 2) {
						if (!value || value==obj.getAttribute(attribute)) {
							ret.push(obj);
						}
					}
					else
					{
						found=false;
						for (var i=1; i<arguments.length; i++) {
							if (arguments[i]==obj.getAttribute(attribute)) {
								found=true;
								break;
							}
						}
						if (found) {
							ret.push(obj);
						}
					}
				}
			}
			
		});
		
		return ret;
	},
	
	subarray: function (start,length) {
		var ret=new Array();
		
		if (typeof start == 'undefined') { 
			start=0;
		}
		
		if (typeof length == 'undefined') {
			if (start<0) {
				length=start;
			}
			else
			{
				length=this.length-start;
			}
		}
		
		for (var i=start;i<Math.abs(length); i++) {
			if (typeof this[start] != 'undefined') {  
				ret.push(this[start]);
			}
			start++;
		}
		
		return ret;
	},
	
	//Alle Elemente die toString unterstützen oder Strings sind aneinander reihen
	concatString: function(separator,iterator) {
		var ret="";
		
		this.each(function (obj,idx) {
			if (idx>0 && typeof separator != 'undefined') {
				ret+=separator;
			}
			
			if (typeof obj == 'string') {
				if (iterator) {
					if (iterator(obj,idx))
						ret+=obj;
				}
				else
				{
					ret+=obj;
				}
			} else if (obj.toString) {
				if (iterator) {
					if (iterator(obj,idx))
						ret+=obj.toString();
				}
				else
				{
					ret+=obj.toString();
				}
			}
		});
		
		return ret;
	}
}

//Array Enumeration hinzufügen
Object.addElements(Array.prototype,CEnum);

Object.addElements(String.prototype, {
	repeat: function(count) {
		var ret=String();
		var str=this;
		
		count.times(function() {
			ret=ret+str;
		});
		
		return ret;
	}
});

Object.addElements(Number.prototype, {
	times: function(iterator) {
		for (var i=0; i<this; i++) {
			iterator(i+1);
		}
	},
	
	toColorPart: function() {
    var digits = this.toString(16);
    if (this < 16) return '0' + digits;
    return digits;
  },
	
	fH: function(l) {		
		return this.f(l,16);
	},
	
	fD: function(l) {		
		return this.f(l,10);
	},
	
	fO: function(l) {		
		return this.f(l,8);
	},
	
	fB: function(l) {		
		return this.f(l,2);
	},
	
	f: function(l,b) {
		if (!b) {
			b=10;
		}
		
		var ret=this.toString(b);

		for (var i=0; i < l; i++) {
			if (this < Math.pow(b,i))
				ret="0"+ret;
		}
		
		return ret;
	}
	
});

//Element bzw. Elemente mit der Id/s zurückgeben
function $() {
	if (arguments.length == 1)
		return document.getElementById(arguments[0]);
		
	var elms=new Array();
	
	for (var i=0; i<arguments.length; i++)
		elms[i]=$(arguments[i]);
	
	return elms;
}

//Alle Element mit einem bestimmten Namen zurückgeben
function $$()
{
	var elms;
	var ret=new Array();
	
	for (var i=0; i<arguments.length; i++) {
		elms=document.getElementsByName(arguments[i]);
		
		for (var i=0; i<elms.length; i++)
			ret[i]=elms[i];
	}
	
	return ret;
}

//ALle Elemente mit einem bestimmten Tag zurückgeben
function $t()
{
	var p = document;
	
	if (arguments.length == 1) {
		return collectionToArray(document.getElementsByTagName(arguments[0]));
	}
	else if(arguments.length >= 2)
	{
		if (typeof arguments[0] == "object") {
			arguments = collectionToArray(arguments);
			p = arguments.shift();
			if (arguments.length == 1) {
				return collectionToArray(p.getElementsByTagName(arguments[0]));
			}
		}
	}
	
	var elms=new Array();
	
	for (var i=0; i<arguments.length; i++) {
		
		elms = elms.concat($t(p, arguments[i]));
	}
	
	return elms;
}


function $p(o,c) {
	if (c && typeof c == "number" && c!=0) {
		return $p(o.parentNode, c-1);
	}
	return o.parentNode;
}

var $C = document.getElementsByClassName = function(className,parent) {
	return collectionToArray((typeof parent != 'undefined' ? parent : document).getElementsByTagName("*")).all(function (obj) {
		return (CSS.classExists(obj,className) ? obj : null);
	});
}

var collectionToArray = $A = function(collection)
{
	var ret=new Array();
	var it;

	if (collection.length) {
		
		for (var i=0; i<collection.length; i++) {
			ret.push(collection[i]);
		}
	}
	else if (collection.iterateNext) {
		while (it = collection.iterateNext()) {
			ret.push(it);
		}

}
	else
	{
		for (elm in collection) {
			ret[elm]=collection[elm];
			ret.push(collection[elm]);
		}
	}
	
	return ret;
}


Object.addElements(Function.prototype,
	{
		bind: function() {
			var __method = this, args = $A(arguments), object = args.shift();
			
			return function() {
				return __method.apply(object, args.concat($A(arguments)));
			}
		},
		
		bindEvent: function() {
			var __method = this, args = $A(arguments), object = args.shift();
			
			return function(event) {
				return __method.apply(object, [event || window.event].concat(args));
			}
		}
	}
);


function styleSheets()
{
	var styles=collectionToArray(document.styleSheets);
	
	styles.each(function (obj,idx) {

		obj.getRules=function () {		
			return collectionToArray(typeof this.cssRules != 'undefined' ? this.cssRules : this.rules);
		}
	});
	
	return styles;
}

//Array Enumeration hinzufügen
Object.addElements(Object.prototype,
	{
		toArray: function() {
			if (this.length) {
				
				var array=new Array();
			
				for (var i=0;i<this.length;i++) {
					array[i]=this[i];
				}
				
				return array;
			}
			return false;
		}
	}
);

function addOnLoadHandler(handler)
{
	Event.addHandler("load",window,handler);
}