﻿ /*
 *  Simple Ajax Toolset 2.2 (small)
 *
 *  tested with: IE 5.01/5.5/6/7, Firefox 1/1.5/2, Opera 8.5/9, Safari 1.3/2/3
 *  (to some extent on IE 5.0 SP2)
 *
 *  (c) Copyright by Soeren Mueller, 2006-2009 - soeren.mueller@all-digital.de
 */

function _$(e) {
	if (typeof e == 'object' || typeof e == 'function') {
		return e;
	}
	if (document.getElementById) {
		return document.getElementById(e);
	}
	if (document.all) {
		return document.all[e];
	}
	return null;
}

function $C(e) {
	return document.createElement(e);
}

function $A(iterable, source) {
	var result = source || [], i;
	if (iterable) {
		for (i=0; i<iterable.length; ++i) {
			result.push(iterable[i]);
		}
	}
	return result;
}

function $E(doc, tag) {
	if (typeof doc == 'string') {
		if (typeof tag == 'undefined') {
			tag = doc;
			doc = null;
		} else {
			doc = _$(doc);
		}
	}
	doc = doc || document;
	var result = null;
	try {
		result = doc.getElementsByTagName(tag || 'e');
	} catch(e) {}
	if (!result || !result.length) {
		if (tag == '*' && document.all) {
			result = document.all;
		} else {
			result = null;
		}
	}
	return result;
}

function $EA(doc, tag) {
	var e = $E(doc, tag);
	if (e) {
		return $A(e);
	}
	return [];
}

function $isTag(el, tag) {
	return (el && el.tagName && el.tagName.toLowerCase() == tag);
}

function $hasClass(el, cname) {
	try {
		el = _$(el);
		if (el.className && el.className.length > 0) {
			var cn = el.className.split(' ');
			return cn.contains(cname);
		}
	} catch(e) {}
	return false;
}

function $remClass(el, cname) {
	try {
		el = _$(el);
		if (el.className && el.className.length > 0) {
			var cn = el.className.split(' ');
			el.className = cn.without(cname).join(" ");
		}
	} catch(e) {}
	return el;
}

function $addClass(el, cname) {
	if (typeof el == 'function') {
		this._cb = el;
		return el;
	}
	el = _$(el);
	if (cname.charAt(0) == '-') {
		$remClass(el, cname.substring(1));
		if (this._cb) {
			this._cb(el);
		}
	} else if (!$hasClass(el, cname)) {
		el.className = ((el.className && el.className.length > 0) ? (el.className + " ") : "") + cname;
		if (this._cb) {
			this._cb(el);
		}
	}
	return el;
}

function $CNS(doc, cname) {
	if (typeof cname == 'undefined' && typeof doc == 'string') {
		cname = doc;
		doc = null;
	}
	var result = [], el = $E(doc, '*'), i;
	if (el) {
		for (i=0; i<el.length; ++i) {
			if ($hasClass(el[i], cname)) {
				result.push(el[i]);
			}
		}
	}
	return result;
}

function $CN(doc, cname) {
	if (typeof cname == 'undefined' && typeof doc == 'string') {
		cname = doc;
		doc = null;
	}
	var el = $E(doc, '*'), i;
	if (el) {
		for (i=0; i<el.length; ++i) {
			if ($hasClass(el[i], cname)) {
				return el[i];
			}
		}
	}
	return null;
}

String.prototype.trim = function() {
	return this.replace(/^\s*/, "").replace(/\s*$/, "");
}

Array.prototype.iterate = function(func, bind) {
	var i;
	for (i=0; i<this.length; ++i) {
		if (bind) {		/* mootools compatibility! - required in Array.prototype.each */
			func.call(bind, this[i], i, this);
		} else {
			func(this[i], i);
		}
	}
};

Array.prototype.contains = function(what) {
	var i;
	for (i=0; i<this.length; ++i) {
		if (this[i] == what) {
			return true;
		}
	}
	return false;
};

if (!Array.prototype.each) {
	Array.prototype.each = Array.prototype.iterate;
}

String.prototype.contains = function(what) {
	return this.indexOf(what) >= 0;
};

Array.prototype.without = function(what) {
	var result = [], i;
	for (i=0; i<this.length; ++i) {
		if (this[i] != what) {
			result.push(this[i]);
		}
	}
	return result;
};

function $attachEvent(el, evt, func) {
	el = _$(el);
	if (el) {
		if (el.each) {
			el.each(function(e){
				$attachEvent(e, evt, func);
			});
		} else {
			try {
				if (evt != 'click' && evt != 'dblclick' && el.addEventListener) {
					el.addEventListener(evt, func, false);
				} else if (el.attachEvent) {
					el.attachEvent("on"+evt, func);
				} else {
					el["on"+evt] = func;
				}
				el["__"+evt] = [(el["__"+evt] || [0])[0] + 1];
			} catch(e) {}
		}
	}
}

function $detachEvent(el, evt, func) {
	el = _$(el);
	if (el) {
		if (el.each) {
			el.each(function(e){
				$detachEvent(e, evt, func);
			});
		} else {
			try {
				if (evt != 'click' && evt != 'dblclick' && el.removeEventListener) {
					el.removeEventListener(evt, func, false);
				} else if (el.detachEvent) {
					el.detachEvent("on"+evt, func);
				} else {
					el["on"+evt] = null;
				}
				var useCount = (el["__"+evt] || [0])[0];
				if (useCount > 1) {
					el["__"+evt] = [useCount-1];
				} else {
					el["__"+evt] = null;
				}
			} catch(e) {}
		}
	}
}

/* REMOVED FOR MOOTOOLS COMPAT
Function.prototype.bind = function() {
	var method = this, args = $A(arguments), object = args.shift();
	return function() {
		return method.apply(object, args);
	};
};*/

if (!Function.prototype.apply) {
	Function.prototype.apply = function(thisArg, argArray) {
		if (typeof this != 'function') {
			// throw is commented out because safari 1.3 requires the ';' after throw which is removed by yui compressor!!!
			return null; //throw new Error('apply called on incompatible object (not a function)');
		}
		if (argArray != null && !(argArray instanceof Array) && typeof argArray.callee != 'function') {
			return null; //throw new Error('The 2nd argument to apply must be an array or arguments object');
		}

		thisArg = (thisArg == null) ? window : Object(thisArg);
		thisArg.__applyTemp = this;

		// youngpup's hack
		var parameters = [], length = (argArray || '').length >>> 0, i, functionCall;
		for (i = 0; i < length; i++) {
			parameters[i] = 'argArray[' + i + ']';
		}
		functionCall = 'thisArg.__applyTemp(' + parameters + ')';

		try {
			return eval(functionCall);
		} finally {
			try {
				delete thisArg.__applyTemp;
			} catch (e){}
		}
	};
}

if (!Function.prototype.call) {
	Function.prototype.call = function(thisArg) {
		return this.apply(thisArg, Array.prototype.slice.apply(arguments, [1]));
	};
}

Function.prototype.bindAsEventListener = function(object) {
	var method = this;
	return function(evt) {
		evt = evt || window.event;
		var target = evt.currentTarget || evt.target || evt.srcElement, result;
		if (evt.type && target && !target["__"+evt.type]) {
			do {
				target = target.parentNode;
			} while(!target["__"+evt.type]);
		}
		result = method.call(object, evt, (target && target.nodeType == 3) ? target.parentNode : target);
		if (evt && result === false) {
			if (evt.stopPropagation) {
				evt.stopPropagation();
			}
			evt.cancelBubble = true;
			if (evt.preventDefault) {
				evt.preventDefault();
			}
			evt.returnValue = false;
		}
		return result;
	};
};

Function.prototype.delay = function() {
	var scope = this, args = $A(arguments), delay = args.shift();
	return setTimeout(function() {
		scope.apply(scope, args);
	}, delay);
};

Function.prototype.after = function(delay) {
	return setTimeout(this, delay);
};

function $style(el, which, def) {
	el = _$(el);
	var result = def, pos;
	try {
		if (document.defaultView && document.defaultView.getComputedStyle) {
			result = document.defaultView.getComputedStyle(el, "").getPropertyValue(which);
		} else if (el.currentStyle) {
			while((pos = which.indexOf('-')) != -1) {
				which = which.substring(0, pos) + which.substring(pos+1, pos+2).toUpperCase() + which.substring(pos+2);
			}
			result = el.currentStyle[which];
		}
		if ((pos = result.indexOf("px")) != -1) {
			return parseInt(result.substring(0, pos), 10);
		}
	} catch(e) {
	}
	return result;
}

function rand(max) {
	return Math.floor(Math.random()*max+1);
}

function $show(el, visible, opacity) {
	if (el.each) {
		el.each(function(e){
			$show(e, visible, opacity);
		});
		return el;
	}
	el = _$(el);
	if (typeof visible == 'number') {
		opacity = visible;
		visible = null;
	}
	if (typeof opacity != 'undefined') {
		$setOpacity(el, opacity);
	}
	try {
		el.style.display = (visible === false) ? 'none' : '';
		el.style.visibility = 'visible';
	} catch(e) {
	}
	return el;
}

function $hide(el, opacity) {
	return $show(el, false, opacity);
}

function $rem(el) {
	el = _$(el);
	if (el && el.parentNode) {
		el.parentNode.removeChild(el);
	}
}

function $append(where, el) {
	if (where.nextSibling) {
		where.parentNode.insertBefore(el, where.nextSibling);
	} else {
		where.parentNode.appendChild(el);
	}
}

function $visible(el) {
	el = _$(el);
	return ($style(el, "display").toLowerCase() != 'none' && $style(el, "visibility").toLowerCase() != 'hidden');
}

function $opacity(el, check) {
	if (check && !$visible(el)) {
		return 0;
	}
	try {
		var s = _$(el).style;
		if (s.opacity) {
			return (s.opacity.length > 0) ? (parseFloat(s.opacity) * 100) : 100;
		} else if (s.MozOpacity) {
			return (s.MozOpacity.length > 0) ? (parseFloat(s.MozOpacity) * 100) : 100;
		} else if (s.KhtmlOpacity) {
			return (s.KhtmlOpacity.length > 0) ? (parseFloat(s.KhtmlOpacity) * 100) : 100;
		} else if (s.KHTMLOpacity) {
			return (s.KHTMLOpacity.length > 0) ? (parseFloat(s.KHTMLOpacity) * 100) : 100;
		} else if (s.filter) {
			return (s.filter.length > 48) ? (parseInt(s.filter.substring(48), 10)) : 100;
		}
	} catch(e) {
	}
	return 100;
}

function $setOpacity(el, opacity) {
	if (el.each) {
		el.each(function(e){
			$setOpacity(e, opacity);
		});
		return;
	}
	try {
		var s = _$(el).style;
		if (typeof s.opacity != 'undefined') {
			s.opacity = (opacity / 100);
		} else if (typeof s.MozOpacity != 'undefined') {
			s.MozOpacity = (opacity / 100);
		} else if (typeof s.KhtmlOpacity != 'undefined') {
			s.KhtmlOpacity = (opacity / 100);
		} else if (typeof s.KHTMLOpacity != 'undefined') {
			s.KHTMLOpacity = (opacity / 100);
		} else if (typeof s.filter != 'undefined') {
			s.filter = (opacity > 99) ? "" : ("progid:DXImageTransform.Microsoft.Alpha(opacity=" + Math.round(opacity) + ")");
		}
	} catch(e) {
	}
}

function $fade(el, from, to, duration, startDelay, zindex) {
	if (!el.each) {
		from = (typeof from != 'number') ? ($visible(el) ? $opacity(el) : 0) : from;
		to = (typeof to != 'number') ? ($visible(el) ? $opacity(el) : 100) : to;
		if (to == from) {
			return;
		}
	}
	var me = this;
	this._el = _$(el);
	this._from = from || 0;
	this._to = to;
	this._duration = duration || 300;
	this._zindex = zindex || 0;
	this._update = function() {
		var time = 0;
		if (!me._starttime) {
			me._starttime = (new Date()).getTime();
		} else {
			time = (new Date()).getTime() - me._starttime;
			if (time > me._duration) {
				time = me._duration;
			}
		}
		$setOpacity(me._el, me._from+((me._to-me._from)*(-(Math.cos(Math.PI*(time/me._duration))-1)/2)));
		if (!time && !me._from) {
			$show(me._el);
		}
		if (me._zindex) {
			me._el.style.zIndex = me._zindex;
		}
		if (time < me._duration) {
			if (me._timer) {
				me._timer = me._update.after(13);	// was: 40
			}
		} else if (me._to === 0) {
			$hide(me._el);
		}
	};
	this.stop = function() {
		if (me._timer) {
			window.clearTimeout(me._timer);
			me._timer = null;
		}
	};
	this._timer = this._update.after(startDelay || 0);
}

function $anim(el, prop, from, to, duration, startDelay) {
	if (!el.each) {
		from = (typeof from != 'number') ? $style(el, prop, 0) : from;
		to = (typeof to != 'number') ? $style(el, prop, 0) : to;
		if (to == from) {
			return;
		}
	}
	var me = this;
	this._el = _$(el);
	this._prop = prop;
	this._from = from || 0;
	this._to = to;
	this._duration = duration || 300;
	this._update = function() {
		var time = 0;
		if (!me._starttime) {
			me._starttime = (new Date()).getTime();
		} else {
			time = (new Date()).getTime() - me._starttime;
			if (time > me._duration) {
				time = me._duration;
			}
		}
		me._el.style[prop] = me._from+((me._to-me._from)*(-(Math.cos(Math.PI*(time/me._duration))-1)/2)) + "px";
		if (time < me._duration) {
			if (me._timer) {
				me._timer = me._update.after(13);	// was: 40
			}
		}
	};
	this.stop = function() {
		if (me._timer) {
			window.clearTimeout(me._timer);
			me._timer = null;
		}
	};
	this._timer = this._update.after(startDelay || 0);
}

function $x(el) {
	el = _$(el);
	var left = 0;
	try {
		if (el.offsetParent) {
			do {
				left += el.offsetLeft;
			} while ((el = el.offsetParent));
		} else if (el.x) {
			left += el.x;
		}
	} catch(e) {}
    return left;
}

function $y(el) {
	el = _$(el);
	var top = 0;
	try {
		if (el.offsetParent) {
			do {
				top += el.offsetTop;
			} while ((el = el.offsetParent));
		} else if (el.y) {
			top += el.y;
		}
	} catch(e) {}
    return top;
}

function $width(el, client) {
	try {
		if (el) {
			el = _$(el);
			if (client && el.clientWidth) {
				return el.clientWidth;
			} else if (el.innerWidth) {
				return el.innerWidth;
			} else {
				return el.offsetWidth;
			}
		}
		if (window.innerWidth) {
			return window.innerWidth;
		} else if (document.documentElement && document.documentElement.clientWidth) {
			return document.documentElement.clientWidth;
		} else if (document.body && document.body.offsetWidth) {
			return document.body.offsetWidth;
		}
	} catch(e) {}
	return 0;
}

function $height(el, client) {
	try {
		if (el) {
			el = _$(el);
			if (client && el.clientHeight) {
				return el.clientHeight;
			} else if (el.innerHeight) {
				return el.innerHeight;
			} else {
				return el.offsetHeight;
			}
		}
		if (window.innerHeight) {
			return window.innerHeight;
		} else if (document.documentElement && document.documentElement.clientHeight) {
			return document.documentElement.clientHeight;
		} else if (document.body && document.body.offsetHeight) {
			return document.body.offsetHeight;
		}
	} catch(e) {}
	return 0;
}

function $setWidth(el, w) {
	el = _$(el);
	try {
		el.style.width = (w) ? w+'px' : '';
	} catch(e){}
}

function $setHeight(el, h) {
	el = _$(el);
	try {
		el.style.height = (h) ? h+'px' : '';
	} catch(e){}
}

function $link(text, url, target, title) {
	if (typeof url == 'undefined') {
		url = text;
	}
	var isMail = false;
	if (url && url.substring(0, 7) != "http://") {
		if (url.indexOf('@') >= 0) {
			isMail = true;
		} else {
			url = "http://"+url;
		}
	}
	return ((url)?("<a href='"+((isMail)?"mailto:":'')+url+"'"+((isMail)?" class='email'":'')+((target)?(" target='"+target+"'"):'')+((title)?(" title='"+title+"'"):'')+">"):'') + text + ((url)?"</a>":'');
}

function $pad(value, length, padding) {
	value = String(value);
	length = parseInt(length, 10) || 2;
	padding = padding || "0";
	while (value.length < length) {
		value = padding + value;
	}
	return value;
}

var pngfix = {
	fix : function(what) {
		if (util.isIE && util.browserVersion < 7.0 && !util.isMac) {
			pngfix._fixImg(what);
		}
	},
	_transparent : "/fileadmin/template/v1/img/transparent.gif",
	_fixImg : function(img) {
		if (img.src.contains(".png") && !img.__pngfix) {
			img.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,src='"+img.src+"',sizingMethod='scale')";
			img.src = pngfix._transparent;
			img.attachEvent('onpropertychange', pngfix._onchange);
			img.__pngfix = true;
		}
	},
	_init : function() {
		if (util.isIE && util.browserVersion < 8.0 && !util.isMac) {
			try {
				document.execCommand('BackgroundImageCache', false, true);
			} catch(e){}
			if (util.browserVersion < 7.0) {
				$EA('img').each(pngfix._fixImg);
					$EA('*').each(function(el){
						var image = el.currentStyle.backgroundImage, urlStart, urlEnd, sizingMethod;
						if (image.contains(".png") && !el.__pngfix) {
							urlStart = image.indexOf("url(");
							urlEnd = image.indexOf(")", urlStart);
							image = image.substring(urlStart+5, urlEnd-1);
//							if (el.currentStyle.width == 'auto') {
//								el.style.width = '100%';
//							}
							el.style.backgroundImage = "url("+pngfix._transparent+")";
							sizingMethod = (el.currentStyle.backgroundRepeat == 'no-repeat') ? 'crop' : 'scale';
							el.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true,src='"+image+"',sizingMethod='"+sizingMethod+"')";
							el.__pngfix = true;
						}
					});
			}
		}
	    return true;
	},
	_inchange : false,
	_onchange : function() {
		if (window.event.propertyName == 'src' && !window.event.srcElement.src.contains(pngfix._transparent) && !pngfix._inchange) {
			pngfix._inchange = true;
			window.event.srcElement.filters.item(0).src = window.event.srcElement.src;
			window.event.srcElement.src = pngfix._transparent;
			pngfix._inchange = false;
		}
	}
};

var $focusElement = null;

function $focus(el, doSelect) {
	el = _$(el);
	$focusElement = el;
	try {
		if (doSelect) {
			el.select();
		}
		el.focus();
	} catch(e) {}
}

function $restoreFocus() {
	if ($focusElement) {
		$focusElement.focus();
	}
}

var util = {

	waitForStyles : false,

	isIE : false,
	isGecko : false,
	isFirefox : false,
	isSafari : false,
	isOpera : false,
	isKonqueror : false,

	isWin : false,
	isMac : false,
	isLinux : false,

	browserVersion : 0,
	webkitVersion : 0,

	onInit : function(func) {
		if (util._inited) {
			func();
		} else {
			util._initqueue.push(func);
		}
	},
	onStart : function(func) {
		if (util._started) {
			func();
		} else {
			util._startqueue.push(func);
		}
	},
	css : function() {
		if (!util._css) {
			util._css = [];
			if (document.styleSheets) {
				var i;
				for (i=0; i<document.styleSheets.length; ++i) {
					util._css = $A(document.styleSheets[i].cssRules || document.styleSheets[i].rules, util._css);
				}
			}
		}
		return util._css;
	},

	_css : null,
	_initqueue : [],
	_startqueue : [],
	_inited : false,
	_started : false,
	_timer : null,
	_load : function() {
		var ua = navigator.userAgent.toLowerCase(), pos, ver;
		ver = parseFloat(navigator.appVersion);
		if (window.opera) {
			util.isOpera = true;
			if ((pos = ua.indexOf("opera")) > 0) {
				ver = parseFloat(ua.substring(pos+6));
			}
		} else if (window.attachEvent) {
			util.isIE = true;
			if ((pos = ua.indexOf("msie")) > 0) {
				ver = parseFloat(ua.substring(pos+5));
			}
		} else if (document.childNodes) {
			if (navigator.taintEnabled) {
				util.isGecko = true;
				if ((pos = ua.indexOf("firefox")) > 0) {
					util.isFirefox = true;
					ver = parseFloat(ua.substring(pos+8));
				}
			} else if (!navigator.accentColorName) {
				if (navigator.vendor == 'KDE') {
					util.isKonqueror = true;
					if ((pos = ua.indexOf("konqueror")) > 0) {
						ver = parseFloat(ua.substring(pos+10));
					}
				} else {
					util.isSafari = true;
					if ((pos = ua.indexOf("safari")) > 0) {
						ver = parseFloat(ua.substring(pos+7));
						if (ver >= 525) {
							ver = 3.1;
						} else if (ver >= 522) {
							ver = 3.0;
						} else if (ver >= 412) {
							ver = 2.0;
						} else if (ver >= 312) {
							ver = 1.3;
						} else if (ver >= 125) {
							ver = 1.2;
						} else if (ver >= 100) {
							ver = 1.1;
						} else if (ver >= 85) {
							ver = 1.0;
						} else if (ver >= 73) {
							ver = 0.9;
						} else if (ver >= 48) {
							ver = 0.8;
						}
					}
				}
			}
		}
		util.browserVersion = ver;
		if ((pos = ua.indexOf("webkit")) > 0) {
			util.webkitVersion = parseFloat(ua.substring(pos+7));
		}
		if (ua.contains("win")) {
			util.isWin = true;
		} else if (ua.contains("mac")) {
			util.isMac = true;
		} else if (ua.contains("linux")) {
			util.isLinux = true;
		}

//		window.onerror = function(){return true;};	// at least try to not totally bug out old browsers
		if (util.isIE) {
			// DOMContentLoaded event hack for IE
			try {
				document.write("<scr"+"ipt id=__onDOMContentLoaded defer src=//:><\/scr"+"ipt>");
				ua = _$("__onDOMContentLoaded");
				if (ua) {
					ua.onreadystatechange = function(){
						if (this.readyState == "complete") {
							this.parentNode.removeChild(this);
							util._start();
						}
					};
				}
			} catch(e) {
				ua = null;
			}
		} else if ((util.isSafari || util.isKonqueror) && typeof document.readyState != 'undefined') {
			// DOMContentLoaded event hack for old Safari and Konqueror (newer Safari builds fire DOMContentLoaded natively!)
			util._timer = setInterval(function(){
				if (document.readyState == "loaded" || document.readyState == "complete") {
					util._start();
				}
			}, 10);
		}
		$attachEvent(window, 'DOMContentLoaded', util._start);
		$attachEvent(window, 'load', util._start);
		$attachEvent(window, 'unload', util._unload);
		
		util._init();
	},
	_unload : function() {
	},
	_init : function() {
		if (util.waitForStyles && document.styleSheets && !document.styleSheets.length) {
			util._init.after(10);
			return;
		}
		util._inited = true;
		var i;
		for (i=0; i<util._initqueue.length; ++i) {
			(util._initqueue[i])();
			util._initqueue[i] = null;
		}
		util._initqueue = [];
	},
	_start : function() {
		if (util._timer) {
			clearInterval(util._timer);
			util._timer = null;
		}
		if (util._started) {	// we only start once!
			return;
		}
		util._started = true;
		pngfix._init();
		var i;
		for (i=0; i<util._startqueue.length; ++i) {
			(util._startqueue[i])();
			util._startqueue[i] = null;
		}
		util._startqueue = [];
	}
};

util._load();

var base64 = {

	_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",

	encode : function (input) {
		var output = "",
			chr1, chr2, chr3, enc1, enc2, enc3, enc4,
			i = 0;

		while (i < input.length) {
			chr1 = input.charCodeAt(i++);
			chr2 = input.charCodeAt(i++);
			chr3 = input.charCodeAt(i++);

			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;

			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(chr3)) {
				enc4 = 64;
			}
 
			output = output+base64._keyStr.charAt(enc1)+base64._keyStr.charAt(enc2)+base64._keyStr.charAt(enc3)+base64._keyStr.charAt(enc4);
		}
		return output;
	},

	decode : function(input) {
		var output = "",
			chr1, chr2, chr3,
			enc1, enc2, enc3, enc4,
			i = 0;
 
		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
		while (i < input.length) {
			enc1 = base64._keyStr.indexOf(input.charAt(i++));
			enc2 = base64._keyStr.indexOf(input.charAt(i++));
			enc3 = base64._keyStr.indexOf(input.charAt(i++));
			enc4 = base64._keyStr.indexOf(input.charAt(i++));

			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;

			output = output+String.fromCharCode(chr1);
			if (enc3 != 64) {
				output = output+String.fromCharCode(chr2);
			}
			if (enc4 != 64) {
				output = output+String.fromCharCode(chr3);
			}
		}
		return output;
	}
};

var styledSelect = {
	
	lastOpen : null,
	
	init : function(doc) {
		$EA(doc, "select").each(function(e){
			var list = $addClass($C("ul"), "styled-select"),
				entry, i;
			for (i=0; i < e.options.length; ++i) {
				entry = $C("li");
				entry.innerHTML = "<span class='"+e.options[i].className+"'>"+e.options[i].text+"</span>";
//				entry.className = e.options[i].className;
				if (e.options[i].selected) {
					$addClass(entry, "styled-select-sel");
				}
				entry._idx = e.options[i].index;
				entry._id = e.id;
				list.appendChild(entry);
				$attachEvent(entry, "click", styledSelect.onClick);
				$attachEvent(entry, "mousedown", styledSelect.onMouseDown);
			}
			$append(e, list);
			$hide(e);
		});
	},
	
	onClick : function(evt, target) {
		var p = target.parentNode;
		if ($hasClass(p, "styled-select-open")) {
			$remClass(p, "styled-select-open");
			$EA(p, "li").each(function(e){
				if (e != target) {
					$remClass (e, "styled-select-sel");
				}
			});
			$addClass(target, "styled-select-sel");
			if (target._id) {
				var el = _$(target._id);
				el.selectedIndex = target._idx;
				if (el.onchange) {
					el.onchange();
				}
			}
		} else {
			$addClass(p, "styled-select-open");
			styledSelect.lastOpen = p;
			$attachEvent(document.body, "mousedown", styledSelect.onCancel);
		}
	}.bindAsEventListener(),
	
	onMouseDown : function(evt, target) {
		return false;
	}.bindAsEventListener(),

	onCancel : function(evt, target) {
		if (styledSelect.lastOpen) {
			$remClass(styledSelect.lastOpen, "styled-select-open");
		}
		$detachEvent(document.body, "mousedown", styledSelect.onCancel);
	}.bindAsEventListener()
};

util.onStart(styledSelect.init);




//***********************
//  PICKLIST.JS
//***********************

var _lang = [{ /* german */
		tel:"Tel:",
		fax:"Fax:",
		suppliers:"Händler",
		sortBy:"Sortieren nach",
		email:"E-Mail",
		vcard:"Vcard",
		details:"Details",
		detailsClose:"Schließen",
		contactPerson:"Ansprechpartner",
		gotoSite:"Website im neuen Fenster öffnen",
		sortAZ:"Aufsteigend (A-Z)",
		sortZA:"Absteigend (Z-A)",
		noResults:"Es wurden keine Händler gefunden",
		sendMail:"Händler per E-Mail kontaktieren",
		openVcard:"Vcard des Händlers herunterladen",
		openDetails:"Detailansicht öffnen",
		closeDetails:"Detailansicht schließen",
		shortDesc:"Kurzprofil",
		showMap:"Navigation in neuem Fenster öffnen"
	},{ /* english */
		tel:"Phone:",
		fax:"Fax:",
		suppliers:"Distributors",
		sortBy:"Sort by",
		email:"E-Mail",
		vcard:"Vcard",
		details:"Details",
		detailsClose:"Close",
		contactPerson:"Contact person",
		gotoSite:"Open website in new window",
		sortAZ:"Ascending (A-Z)",
		sortZA:"Descending (Z-A)",
		noResults:"No suppliers found",
		sendMail:"Contact supplier via E-Mail",
		openVcard:"Open Vcard of the supplier",
		openDetails:"Open detail view",
		closeDetails:"Close detail view",
		shortDesc:"Short description",
		showMap:"Open navigation in new window"
	},{ /* french */
		tel:"Téléphone:",
		fax:"Téléfax:",
		suppliers:"Distributeur",
		sortBy:"Trier selon",
		email:"E-Mail",
		vcard:"Vcard",
		details:"Détails",
		detailsClose:"Fermer",
		contactPerson:"Interlocuteur",
		gotoSite:"Ouvrer le site web dans une nouvelle fenêtre",
		sortAZ:"Ascendant (A-Z)",
		sortZA:"Descendant (Z-A)",
		noResults:"Aucun distributeur trouvé",
		sendMail:"Prendre contact par e-mail avec le distributeur",
		openVcard:"Ouvrir la V-Card du distributeur",
		openDetails:"Ouvrir la vue détaillée",
		closeDetails:"Fermer la vue détaillée",
		shortDesc:"Profil concis",
		showMap:"Open navigation in new window"
	},{ /* italian */
		tel:"Telefono:",
		fax:"Fax:",
		suppliers:"Commercianti",
		sortBy:"Ordina per",
		email:"E-Mail",
		vcard:"Vcard",
		details:"Dettagli",
		detailsClose:"Chiudi",
		contactPerson:"Referente",
		gotoSite:"Apri il sito in una nuova finestra",
		sortAZ:"Ordine crescente (A-Z)",
		sortZA:"Ordine decrescente (Z-A)",
		noResults:"Non è stato trovato nessun commerciante",
		sendMail:"Contatta il commerciante via e-mail",
		openVcard:"Apri la Vcard del commerciante",
		openDetails:"Apri la Visualizzazione dettagli",
		closeDetails:"Chiudi la Visualizzazione dettagli",
		shortDesc:"Profilo in forma sommaria",
		showMap:"Open navigation in new window"
	},{ /* russian */
		tel:"тел.:",
		fax:"факс:",
		suppliers:"торговец",
		sortBy:"сортировать по",
		email:"E-Mail",
		vcard:"Vcard",
		details:"торговцев",
		detailsClose:"закрыть",
		contactPerson:"контактное лицо",
		gotoSite:"открыть веб-сайт в новом окошке",
		sortAZ:"поднимающийся (А-Я)",
		sortZA:"спускающийся (Я-А)",
		noResults:"Не было найдено торговцев",
		sendMail:"Вступить в контакт с торговцем через e-mail",
		openVcard:"Открыть Vcard торговца",
		openDetails:"открыть детальный вид",
		closeDetails:"закрыть детальный вид",
		shortDesc:"краткое описание",
		showMap:"Open navigation in new window"
	},{ /* chinese */
		tel:"电话:",
		fax:"传真:",
		suppliers:"供应商",
		sortBy:"按 … 排序",
		email:"电邮",
		vcard:"名片",
		details:"详情",
		detailsClose:"关闭",
		contactPerson:"联系人",
		gotoSite:"打开新的视窗",
		sortAZ:"按A-Z 排序",
		sortZA:"按Z-A 排序",
		noResults:"没有找到供应商",
		sendMail:"给供应商发邮件",
		openVcard:"打开供应商的电子名片",
		openDetails:"打开详情说明",
		closeDetails:"关闭详情说明",
		shortDesc:"简介",
		showMap:"Open navigation in new window"
	}], _l;


var picklist = {
	
	isLoaded : false,
	selection : [],
	selectedItems : 0,
	updateTimer : null,
	updateCancel : false,
	listView : null,
	listHeader : null,

	init : function() {
		if (!$hasClass(document.body, "picklist")) {
			return;
		}

		$EA($CN("navbar"), "li").each(function(e) {
			var sub = $EA(e, "ul");
			if (sub && sub[0]) {
				$addClass(e, "sub");
				e._sub = sub[0];
			}
			$attachEvent(e, "click", picklist.onClick);
			$attachEvent(e, "mousedown", picklist.onMouseDown);
			if ($isTag(e.firstChild, 'b')) {
				e._switch = e.firstChild;
				e._id = e._switch.innerHTML.trim().toLowerCase();
				e._switch.innerHTML = "";
				$attachEvent(e._switch, "click", picklist.onSelect);
			}
		});
		_l = _lang[sl];

		picklist.listHeader = $CN("content").appendChild($hide($addClass($C("div"), "picklist-header")));
		picklist.listView = $CN("content").appendChild($hide($addClass($C("div"), "picklist-wrap")));
		picklist.listHeader.innerHTML = "<div class='stat'>0</div> | <div class='sel'>-</div>"+
			"<select size='1' onchange='picklist.switchSort(this);return false' id='picklist-sort'>"+
			"<option value='AZ' selected='selected'>"+_l.sortAZ+"</option>"+
			"<option value='ZA'>"+_l.sortZA+"</option>"+
			"</select>";
		styledSelect.init(picklist.listHeader);
	},
	
	onClick : function(evt, target) {
		if (target._sub) {
			if ($visible(target._sub)) {
				target._sub.style.display = "none";
				$remClass(target, "open");
			} else {
				target._sub.style.display = "block";
				$addClass(target, "open");
			}
		} else if (target._switch) {
			picklist.handleSwitch(target);
		}
		return false;
	}.bindAsEventListener(),
	
	onMouseDown : function(evt, target) {
		return false;
	}.bindAsEventListener(),
	
	onSelect : function(evt, target) {
		picklist.handleSwitch(target.parentNode);
		return false;
	}.bindAsEventListener(),
	
	handleSwitch : function(el, state, isRecursive) {
		if (!el._switch) {
			return;
		}
		if ($hasClass(el._switch, "act")) {
			if (state !== true) {
				$remClass(el._switch, "act");
				if (picklist.selection[el._id]) {
					--picklist.selectedItems;
				}
				delete picklist.selection[el._id];

				if (!isRecursive) {
					if(el._sub) {
						$EA(el, "li").each(function(e){picklist.handleSwitch(e, false, true);});
					}
					picklist.update();
				}
			}
		} else if (state !== false) {
			$addClass(el._switch, "act");
			picklist.handleSwitch(el.parentNode.parentNode, true, true);
			if (!picklist.selection[el._id]) {
				++picklist.selectedItems;
			}
			picklist.selection[el._id] = {name:el.firstChild.nextSibling.data.trim(), hasSub:((el._sub)?true:false)};

			if (!isRecursive) {
				if (el._sub) {
					$EA(el, "li").each(function(e){picklist.handleSwitch(e, true, true);});
				}
				picklist.update();
			}
		}
	},
	
	update : function() {

		picklist.updateCancel = true;
		if (picklist.updateTimer) {
			window.clearTimeout(picklist.updateTimer);
		}

		if (picklist.selectedItems > 0) {
			picklist.updateTimer = picklist.updateHTML.after(300);

		} else {
			picklist.showPicklist(false);
		}
	},
	
	showPicklist : function(sw) {
		var el = $CN("picklist-intro-flash");
		if (sw && $visible(el)) {
			$hide(el);
			new $fade($CN("newsbar"), 100, 0, 300);
			new $fade($CN($CN("newsbar-wrap"), "bg"), 100, 0, 300);
			new $fade($CN("col23"), 100, 0, 300);
			$show.delay(300, picklist.listHeader);
			$show.delay(500, picklist.listView);
//			$show(picklist.listView);
		} else if (!sw && !$visible(el)) {
			$hide(picklist.listView);
			$hide(picklist.listHeader);
//			new $fade(picklist.listView, 100, 0, 100);
			new $fade($CN("col23"), 0, 100, 300, 100);
			new $fade($CN($CN("newsbar-wrap"), "bg"), 0, 100, 300, 100);
			new $fade($CN("newsbar"), 0, 100, 300, 100);
			$show(el);
		}
	},
	
	sortAs : "AZ",

	updateHTML : function() {
		picklist.updateCancel = false;
		picklist.updateTimer = null;
		picklist.listView.innerHTML = "";
		picklist.showPicklist(true);

		var i, sel, matches, total = 0, idx, newDiv;

		for (i=0; i<_db.length && !picklist.updateCancel; ++i) {
			idx = (picklist.sortAs == "AZ") ? i : (_db.length - i - 1);
			matches = false;
			for (sel in picklist.selection) {
				if (typeof picklist.selection[sel] != 'function' && _db[idx][sel]) {
					matches = true;
				}
			}

			if (matches) {
				++total;
				if (!_db[idx].html) {
					picklist.printHTML(_db[idx]);
				}
				newDiv = $C("div");
				newDiv.innerHTML = _db[idx].html;
				newDiv.lastChild.id = idx;
				picklist.listView.appendChild(newDiv);
			}
		}
		if(!total) {
			picklist.listView.innerHTML = "<b>"+_l.noResults+"</b>";
		}
		$CN(picklist.listHeader, 'stat').innerHTML = total+' '+_l.suppliers;

		var buf = "", entry = null;
		for (sel in picklist.selection) {
			if (typeof picklist.selection[sel] == 'function' || (picklist.selection[sel].name && picklist.selection[sel].name == 'array')) {
				continue;
			}
			if (entry) {
				buf += (entry.hasSub) ? ": " : " + ";
			}
			entry = picklist.selection[sel];
			buf += entry.name;
			if (buf.length > 150) {
				buf += "...";
				break;
			}
		}
		$CN(picklist.listHeader, 'sel').innerHTML = buf;
	},
	
	printHTML : function(db) {
		db.postalcode = $pad(db.postalcode, 5);
		db.html = "<div class='entry'>";
		if (db.logoname) {
			db.html += "<div class='logo'>"+$link("<img src='http://www.german-meat.org/uploads/tx_adpicklist/"+db.logoname+"' width='155' alt='Logo "+db.name+"' />", db.url, "_blank", _l.gotoSite)+"</div>";
		}
		db.html += "<h1>"+db.name+"</h1>";
		db.html += "<div class='overview'><div class='c1'>";
		db.html += $link(db.name1+' '+db.surname1, db.email1, null, _l.sendMail)+"<br/>"+((db.surname2)?$link(db.name2+' '+db.surname2, db.email2, null, _l.sendMail):'')+"<br/><br/>"+db.street+' '+db.streetnr+"<br/>"+db.postalcode+' '+db.city;
		db.html += "</div><div class='c2'>";
		db.html += $link(db.email1, db.email1, null, _l.sendMail)+"<br/>"+((db.email2)?$link(db.email2, db.email2, null, _l.sendMail):'')+"<br/><br/>";
		db.html += _l.tel+' '+db.phone+"<br/>";
		db.html += _l.fax+' '+db.fax+"<br/>";
		db.html += "</div><div class='c3'>";
		db.html += ((db.url)?$link(db.url, db.url, "_blank", _l.gotoSite):'');
		db.html += "</div></div>";

		db.html += "<div class='detailview' style='display:none'><div class='c1'>";
		db.html += db.street+' '+db.streetnr+"<br/>";
		db.html += db.postalcode+' '+db.city+"<br/>";
//		db.html += db.state+"<br/>";
		if(db.surname1 && db.phone1) {
			db.html += "<br/>";
			db.html += "<b>"+_l.contactPerson+":</b><br/><br/>";
			db.html += db.name1+' '+db.surname1+"<br/>";
			db.html += "<br/><br/>";
			if(db.surname2) {
				db.html += db.name2+' '+db.surname2+"<br/>";
			}
		}
		db.html += "</div><div class='c2'>";
		db.html += _l.tel+' '+db.phone+"<br/>";
		db.html += _l.fax+' '+db.fax+"<br/>";
//		db.html += "<br/>";
		if(db.surname1 && db.phone1) {
			db.html += "<br/>";
			db.html += "<br/><br/>";
			db.html += _l.tel+' '+db.phone1+"<br/>";
			db.html += $link(db.email1, db.email1, null, _l.sendMail)+"<br/><br/>";
			if(db.surname2 && db.phone2) {
				db.html += _l.tel+' '+db.phone2+"<br/>";
				db.html += $link(db.email2, db.email2, null, _l.sendMail)+"<br/>";
			}
		}
		db.html += "</div><div class='c3'>";
		db.html += ((db.url)?$link(db.url, db.url, "_blank", _l.gotoSite):'');
		db.html += "</div><div class='c12'>";
		var desc = (sl == 5) ? db.desccn : (sl == 4) ? db.descru : (sl == 3) ? db.descit : (sl == 2) ? db.descfr : (sl == 1) ? db.descen : db.descde;
		if (desc) {
			db.html += "<b>"+_l.shortDesc+":</b><br/><br/>";
			db.html += desc.replace(/\n/g,"<br/>");
		}
		db.html += "</div></div>";
		db.html += "<div class='buttons'>";
		db.html += $link(_l.email, db.email1, null, _l.sendMail);
		if (!db.vcard) {
			picklist.printVCARD(db);
			db.vcard = base64.encode(db.vcard);
		}
		db.html += "<a href='data:text/x-vcard;base64,"+db.vcard+"' class='vcard' title='"+_l.openVcard+"'>"+_l.vcard+"</a>";
		db.html += "<a href='#' class='details' onclick='picklist.switchDetails(this);return false' title='"+_l.openDetails+"' >"+_l.details+"</a>";
		db.html += "</div></div>";
	},
	
	printVCARD : function(db) {
		db.vcard = "BEGIN:VCARD\n"+
			"VERSION:3.0\n"+
			"N:"+db.surname1+";"+db.name1+"\n"+
			"FN:"+db.name1+" "+db.surname1+"\n"+
			"ORG:"+db.name+"\n";
		if (db.url) {
			db.vcard += "URL;TYPE=work:"+db.url+"\n";
		}
		db.vcard += "EMAIL;TYPE=internet,work:"+((db.email1)?db.email1:db.email)+"\n"+
			"TEL;TYPE=voice,work,pref:"+((db.phone1)?db.phone1:db.phone)+"\n"+
			"TEL;TYPE=fax,work,pref:"+db.fax+"\n"+
			"ADR;TYPE=intl,work,postal,parcel:;;"+db.street+" "+db.streetnr+";"+db.city+";;"+db.postalcode+";Germany\n"+
			"PHOTO;VALUE=URL;TYPE=GIF:http://www.german-meat.org/uploads/tx_adpicklist/"+db.logoname+"\n"+
			"END:VCARD\n";
	},

	geoCoder : null,

	switchDetails : function(el) {
		var entry = el.parentNode.parentNode,
			details = $CN(entry, "detailview"),
			overview = $CN(entry, "overview");
		if ($visible(details)) {
			$hide(details);
			$show(overview);
			el.innerHTML = _l.details;
			el.title = _l.openDetails;
			$remClass(el, "close");
		} else {
			$hide(overview);
			$show(details);
			el.innerHTML = _l.detailsClose;
			el.title = _l.closeDetails;
			$addClass(el, "close");

			var mapWrap = $CN(details, "map");
			if (!mapWrap && GBrowserIsCompatible()) {
				if (!picklist.geoCoder) {
					picklist.geoCoder = new GClientGeocoder();
				}
				mapWrap = $addClass($C("div"), "map");
				mapWrap = details.insertBefore(mapWrap, $CN(details, "c12"));
				var db = _db[entry.id];
				picklist.geoCoder.getLatLng(db.street+" "+db.streetnr+", "+db.postalcode+" "+db.city+", Germany", function(point){picklist.updateMap(point, mapWrap, db);});
			}
		}
	},

	updateMap : function(point, mapWrap, db) {
		var map = new GMap(mapWrap), marker = new GMarker(point, {title:_l.showMap});
		map.centerAndZoom(point, 4);
		map.addControl(new GSmallMapControl());
		map.setMapType(G_NORMAL_MAP);
		var address = db.street+" "+db.streetnr+", "+db.postalcode+" "+db.city+", Germany";
		GEvent.addListener(marker, "click", function(){window.open("http://maps.google.com/maps?q="+address.replace(/ /g,"+"),target='_blank')});
		map.addOverlay(marker);
//		var html = "<div class='map-overlay' style='width:50px;height:1em'>"+db.street+" "+db.streetnr+", "+db.postalcode+" "+db.city+"</div>";
//		marker.openInfoWindowHtml(html, {maxWidth:"50"});
	},
	
	switchSort : function(el) {
		picklist.sortAs = el.options[el.selectedIndex].value;
		picklist.update();
	}
};

util.onStart(picklist.init);
