/**
 * addEvent & removeEvent -- cross-browser event handling
 * Copyright (C) 2006  Dao Gottwald
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Contact information:
 *   Dao Gottwald  <dao at design-noir.de>
 *
 * @version  1.1.6
 */

/*@cc_on if (window.addEventListener) { @*/
	function addEvent (o, type, fn) {
		o.addEventListener (type, fn, false);
	}
	function removeEvent (o, type, fn) {
		o.removeEventListener (type, fn, false);
	}
/*@ } else if (window.attachEvent) {
	function addEvent (o, type, fn) {
		if (!o._events) o._events = {};
		var queue = o._events[type];
		if (!queue) {
			o._events[type] = [fn];
			if (!o._events._callback)
				o._events._callback = function (e) { Event._callListeners (e, o) };
			o.attachEvent ('on' + type, o._events._callback);
		} else if (Event._fnIndex (o, type, fn) == -1)
			queue[queue.length] = fn;
		else return;
		Event._mem[Event._mem.length] = [o, type, fn];
	}
	function removeEvent (o, type, fn) {
		var i = Event._fnIndex (o, type, fn);
		if (i < 0) return;
		var queue = o._events[type];
		if (queue.calling) {
			delete queue[i];
			if (queue.removeListeners)
				queue.removeListeners[queue.removeListeners.length] = i;
			else
				queue.removeListeners = [i];
		} else
			if (queue.length == 1)
				Event._detach (o, type);
			else
				queue.splice (i, 1);
	}
	var Event = {
		AT_TARGET : 2,
		BUBBLING_PHASE : 3,
		stopPropagation : function() { this.cancelBubble = true },
		preventDefault : function() { this.returnValue = false },
		_mem : [],
		_callListeners : function (e, o) {
			e.stopPropagation = Event.stopPropagation;
			e.preventDefault = Event.preventDefault;
			e.currentTarget = o;
			e.target = e.srcElement;
			e.eventPhase = e.currentTarget == e.target ? Event.AT_TARGET : Event.BUBBLING_PHASE;
			switch (e.type) {
				case 'mouseover':
					e.relatedTarget = e.fromElement;
					break;
				case 'mouseout':
					e.relatedTarget = e.toElement;
			}
			var queue = o._events[e.type];
			queue.calling = true;
			for (var i=0, l = queue.length; i < l; i++)
				if (queue[i])
					queue[i].call(o,e);
			queue.calling = null;
			if (!queue.removeListeners)
				return;
			if (queue.length == queue.removeListeners.length) {
				Event._detach (o, e.type);
				return;
			}
			queue.removeListeners = queue.removeListeners.sort(function(a,b){return a-b});
			var i = queue.removeListeners.length;
			while (i--)
				queue.splice (queue.removeListeners[i], 1);
			if (queue.length == 0)
				Event._detach (o, e.type);
			else
				queue.removeListeners = null;
		},
		_detach : function (o, type) {
			o.detachEvent ('on' + type, o._events._callback);
			delete o._events[type];
		},
		_fnIndex : function (o, type, fn) {
			var queue = o._events[type];
			if (queue)
				for (var i=0, l = queue.length; i < l; i++)
					if (queue[i] == fn)
						return i;
			return -1;
		},
		_cleanup : function() {
			for (var m, i=0; m = Event._mem[i]; i++)
				if (m[1] != 'unload' || m[2] == Event._cleanup)
					removeEvent (m[0], m[1], m[2]);
		}
	};
	addEvent (window, 'unload', Event._cleanup);
} @*/

/**
 * function whenDOMReady
 * Copyright (C) 2006-2007 Dao Gottwald
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Contact information:
 *   Dao Gottwald  <dao at design-noir.de>
 *
 * @version  1.2
 * @url      http://design-noir.de/webdev/JS/whenDOMReady/
 */

function whenDOMReady(fn) {
	var f = arguments.callee;
	if ("listeners" in f) {
		if (f.listeners)
			f.listeners.push(fn);
		else
			fn();
		return;
	}
	f.listeners = [fn];
	var callback = function() {
		/*@if (@_win32) f.script.onreadystatechange = null; @end @*/
		removeEvent(window, "load", callback);
		if (document.removeEventListener)
			document.removeEventListener("DOMContentLoaded", callback, false);
		while (f.listeners.length)
			f.listeners.shift()();
		f.listeners = null;
	};
	if (document.addEventListener)
		document.addEventListener("DOMContentLoaded", callback, false);
	/*@if (@_win32) else {
		document.write("<script id=__ie_scriptdummy defer src=javascript:void(0)><\/script>");
		f.script = document.getElementById("__ie_scriptdummy");
		f.script.onreadystatechange = function() {
			if (this.readyState == "complete")
				callback();
		};
	} @end @*/
	addEvent(window, "load", callback);
}

function fadeIn(obj, cb) {
  _doFade(obj, cb, [0, .1, .3, .65, 1]);
}
function fadeOut(obj, cb) {
  _doFade(obj, cb, [1, .65, .3, .1, 0]);
}
function _doFade(obj, cb, opacities) {
  /*@
  if (cb)
    cb();
  return;
  @*/
  var i = 0;
  var anim_id;
  function processFrame() {
    if (i < opacities.length) {
      obj.style.opacity = opacities[i];
      ++i;
    } else {
      clearInterval(anim_id);
      if (cb)
        cb();
    }
  }
  anim_id = setInterval(processFrame, 60);
  processFrame();
}

whenDOMReady(function() {
  var menu = document.getElementById("submenu");
  if (!menu)
    return;
  var currentNode;
  var toggle = function(node, show, cb) {
    var className = show ? "" : "collapsed";
    var fn = show ?
        function(node) {
          node.className = className;
          fadeIn(node, function() {
            if (cb)
              cb();
          });
        } :
        function(node) {
          fadeOut(node, function() {
            node.className = className;
            if (cb)
              cb();
          });
        };
    do {
      if (node.nodeType == 1)
        fn(node);
      node = node.nextSibling;
    } while (node && node.nodeName.toLowerCase() != "h3");
  };
  var toggleAnchor = function(anchor) {
    var node = document.getElementById(anchor.replace(/.*#/, ""));
    if (node && node != currentNode) {
      var showContent = (function(currentNode) {
        return currentNode ?
          function() {
            toggle(currentNode, false, function() {
              toggle(node, true);
            });
          } :
          function() {
            toggle(node, true);
          };
      })(currentNode);
      if (menu.className != "submenu-dyn") {
        fadeOut(menu, function() {
          menu.className = "submenu-dyn";
          fadeIn(menu);
          showContent();
        });
      } else
        showContent();
      currentNode = node;
    }
  };
  addEvent(menu, "click", function(e) {
    var href = e.target.getAttribute("href");
    if (href && href.indexOf("#") > -1) {
      toggleAnchor(href);
      e.preventDefault();
    }
  });
  var node = menu.nextSibling;
  while (node && node.nodeName.toLowerCase() != "address") {
    if (node.nodeType == 1)
      node.className = "collapsed";
    node = node.nextSibling;
  }
  if (location.hash) {
    toggleAnchor(location.hash);
  }
});

/* E-Mail-Adressen */
whenDOMReady (function() {
	var link, all = document.getElementsByTagName('a');
	for (var i=0, ele; ele = all[i]; i++)
		if (!ele.href && ele.firstChild && ele.firstChild.nodeValue)
			if (/\)$/.test(ele.firstChild.nodeValue)) {
				link = ele.firstChild.nodeValue.match(/^(.*) \((.*?) at (.*?)\)$/);
				if (link) {
					ele.firstChild.nodeValue = link[1];
					ele.href = 'mailto:' + link[2] + '@' + link[3];
				}
			} else {
				link = ele.firstChild.nodeValue.match(/^(.*) at (.*)$/);
				if (link)
					ele.href = 'mailto:' + (ele.firstChild.nodeValue = link[1] + '@' + link[2]);
			}
});

whenDOMReady (function() {
	Galerie.prototype.close = function (e) {
		if (!this.container || this.container.style.display != "block")
			return;
		if (e)
			e.preventDefault();
		this.slideHalt();
		var self = this;
		fadeOut(this.image, function() {
			Galerie.restoreDocumentLayout(!!e);
			self.container.style.display = "none";
			self.image.style.opacity = "";
		});
	};
});
