
/**
 * A compact JavaScript-Helper Libary for Cross Browser Scripting
 * Used for twoday / antville
 * 
 * Written by Matthias Platzer at http://knallgrau.at
 * inspired by code found at various places in the net
 * especially by HTMLArea by Mihai Bazon http://students.infoiasi.ro/~mishoo
 * and Tim Taylor http://tool-man.org/
 *
 * use it as you need it
 */

function _gel(id) { return document.getElementById(id); }
String.prototype.lc = String.prototype.toLowerCase;
String.prototype.uc = String.prototype.toUpperCase;

function addEvent(el, evname, func) {
  if (el.attachEvent) el.attachEvent("on" + evname, func);
  else el.addEventListener(evname, func, true);
}

function stopEvent(evt) {
  if (evt.preventDefault) {
    evt.preventDefault();
    evt.stopPropagation();
  } else {
    evt.cancelBubble = true;
    evt.returnValue = false;
  }
}

function addEvents(el, evs, func) {
	for (var i in evs) { addEvent(el, evs[i], func) }
}

function removeEvent(el, evname, func) {
	if (el.detachEvent) el.detachEvent("on" + evname, func);
	else el.removeEventListener(evname, func, true);
}

function removeEvents(el, evs, func) {
	for (var i in evs) { removeEvent(el, evs[i], func) }
}

function removeClass(el, className) {
	if (!(el && el.className)) return;

	var cls = el.className.split(" ");
	var ar = new Array();
	for (var i = cls.length; i > 0;) {
		if (cls[--i] != className) {
			ar[ar.length] = cls[i];
		}
	}
	el.className = ar.join(" ");
}

function addClass(el, className) {
	// remove the class first, if already there
	removeClass(el, className);
	el.className += " " + className;
}

function hasClass(el, className) {
	if (!(el && el.className)) return false;

	var cls = el.className.split(" ");
	for (var i = cls.length; i > 0;) {
		if (cls[--i] == className) return true;
	}
	return false;
}

function hitTest (ele1, ele2) {
	if (getAbsOffsetLeft(ele1)+ele1.offsetWidth<getAbsOffsetLeft(ele2)) return false;
	if (getAbsOffsetTop(ele1)+ele1.offsetHeight<getAbsOffsetTop(ele2)) return false;
	if (getAbsOffsetLeft(ele2)+ele2.offsetWidth<getAbsOffsetLeft(ele1)) return false;
	if (getAbsOffsetTop(ele2)+ele2.offsetHeight<getAbsOffsetTop(ele1)) return false;
	return true;
}

function isUnderMouse (evt, ele) {
  var evt = evt ? evt : window.event;
  var sl = (window.pageXOffset ? window.pageXOffset : document.body.scrollLeft);
  var st = (window.pageYOffset ? window.pageYOffset : document.body.scrollTop);

	var x = (evt.clientX + sl);
	var y = (evt.clientY + st);
	if (x<getAbsOffsetLeft(ele)) return false;
	if (y<getAbsOffsetTop(ele)) return false;
	if (x>getAbsOffsetLeft(ele)+ele.offsetWidth) return false;
	if (y>getAbsOffsetTop(ele)+ele.offsetHeight) return false;
	return true;
}

function getAbsOffsetTop(ele) {
  var offset = 0;
  var st = (window.pageYOffset ? window.pageYOffset : document.body.scrollTop);
  do { offset += ele.offsetTop; if (window.getComputedStyle && window.getComputedStyle(ele, "").getPropertyValue("position")=="fixed") { offset+=st }; ele = ele.offsetParent; } while (ele!=null)
  return offset;
}

function getAbsOffsetLeft(ele) {
  var offset = 0;
  var sl = (window.pageXOffset ? window.pageXOffset : document.body.scrollLeft);
  do { offset += ele.offsetLeft; if (window.getComputedStyle && window.getComputedStyle(ele, "").getPropertyValue("position")=="fixed") { offset+=sl }; ele = ele.offsetParent; } while (ele!=null)
  return offset;
}


// Array functions
Array.contains = function(arr, el) {
  for (var i=0; i<arr.length; i++) {
    if (arr[i] == el) return i;
  }
  return false;
}

// Cookie Functions
function ClientCookie() {
	if (document.cookie.length) { this.cookies = ' ' + document.cookie; }
}

ClientCookie.prototype.setCookie = function (key, value) {
	document.cookie = key + "=" + escape(value);
}

ClientCookie.prototype.getCookie = function (key) {
	if (this.cookies) {
		var start = this.cookies.indexOf(' ' + key + '=');
		if (start == -1) { return null; }
		var end = this.cookies.indexOf(";", start);
		if (end == -1) { end = this.cookies.length; }
		end -= start;
		var cookie = this.cookies.substr(start,end);
		return unescape(cookie.substr(cookie.indexOf('=') + 1, cookie.length - cookie.indexOf('=') + 1));
	}
	else { return null; }
}

// html dom functions

function getChildren(item, nodeName, className) {
  if (item == null) return [];
  var result = [];
  for (var c = 0; c<item.childNodes.length; c++) {
    if ((nodeName == "*" && item.childNodes[c].nodeType == 1) || item.childNodes[c].nodeName.lc() == nodeName.lc()) {
      if (!className || hasClass(item.childNodes[c], className)) result.push(item.childNodes[c]);
    }
  }
  return result;
}

function getParentElement(item, nodeName, className) {
  if (item == null) return;
  var parent = item.parentNode;
  while (parent != null) {
    if ((nodeName == "*" && parent.nodeType == 1) || parent.nodeName.lc() == nodeName.lc()) {
      if (!className || hasClass(parent, className)) return parent;
    }
    parent = parent.parentNode;
  }
  return null;
}

function getNextElement(item, nodeName, className) {
  if (item == null) return;
  var next = item.nextSibling;
  while (next != null) {
    if ((nodeName == "*" && next.nodeType == 1) || next.nodeName.lc() == nodeName.lc()) {
      if (!className || hasClass(next, className)) return next;
    }
    next = next.nextSibling;
  }
  return null;
}

function getPreviousElement(item, nodeName, className) {
  var previous = item.previousSibling;
  while (previous != null) {
    if ((nodeName == "*" && previous.nodeType == 1) || previous.nodeName.lc() == nodeName.lc()) {
      if (!className || hasClass(previous, className)) return previous;
    }
    previous = previous.previousSibling;
  }
  return null;
}

function moveBefore(item1, item2) {
  var parent = item1.parentNode;
  parent.removeChild(item1);
  parent.insertBefore(item1, item2);
}

function moveAfter(item1, item2) {
  var parent = item1.parentNode;
  parent.removeChild(item1);
  parent.insertBefore(item1, item2 ? item2.nextSibling : null);
}

function newXmlRequest() {
  var r = null;
  try {
    r = new ActiveXObject("Msxml2.XMLHTTP")
  } catch(a) {}
  if (r != null) return r;
  
  try {
    r = new ActiveXObject("Microsoft.XMLHTTP");
  } catch(b) {}
  if (r != null) return r;
  
  return new XMLHttpRequest();
}

/**
 * Helper functions for showing/hidding form sections contained in divs
 * @example
 * <p><span id="prefsFontsToggle"></span></p> 
 * <div id="prefsFonts">...</div> 
 * <script type="text/javascript">
 * activateVisibilityToggle ("prefsFonts", {inactiveText: "[+] Details anzeigen", activeText: "[-] Details ausblenden", activeIcon: "icon-minus-16.png", inactiveIcon2: "icon-plus-16.png"}, false); 
 * </script>
*/
function VT(id, param) {
  this.id = id;
  this.param = param;
  this.div = _gel(id);
  this.tgl = _gel(id + "Toggle");
  switch (this.tgl.nodeName.lc()) {
    case "input": this.type = "input"; break;
    case "select": this.type = "select"; break;
    default: this.type = "span";
  }

  switch (this.type) {
  case "input":
    addEvent(this.tgl, "click", function (evt) { var ele = evt.srcElement ? evt.srcElement : evt.target; var id = ele.getAttribute("for") ? ele.getAttribute("for") : ele.id; tV(id.substring(0, id.indexOf("Toggle"))); });
    break;
  case "select":
    addEvent(this.tgl, "change", function (evt) { var ele = evt.srcElement ? evt.srcElement : evt.target; tV(ele.id.substring(0, ele.id.indexOf("Toggle"))); });
    break;
  default:
    this.vC = "";
    if (param.activeIcon) this.vC = '<img src="'+param.activeIcon+'" width="'+param.activeIcon+'" alt="[-]" onclick="tV(\'' + id + '\')" />';
    this.vC += '<a href="javascript:tV(\'' + id + '\')">' + param.activeText + '</a>';
    this.invC = "";
    if (param.inactiveIcon) this.invC = '<img src="'+param.inactiveIcon+'" width="'+param.inactiveIcon+'" alt="[+]" onclick="tV(\'' + id + '\')" />';
    this.invC += '<a href="javascript:tV(\'' + id + '\')">' + param.inactiveText + '</a>';
    break;
  }
}

VT.prototype.toggle = function() {
  switch (this.type) {
  case "input":
    if (this.tgl.checked) this.show();
    else this.hide();
    break;
  case "select":
    if ((","+this.param.activeOptionValue+",").indexOf(","+this.tgl.options[this.tgl.selectedIndex].value+",")!=-1) this.show();
    else this.hide();
    break;
  default:
     if (this.div.style.display == "none") this.show();
     else this.hide();
     break;
  }
}

VT.prototype.show = function() {
  this.div.style.display = "block";
  if (this.type=="span") this.tgl.innerHTML = this.vC;
}

VT.prototype.hide = function() {
  this.div.style.display = "none";
  if (this.type=="span") this.tgl.innerHTML = this.invC;
}

vTs = {};
function activateVisibilityToggle(id, param, visible) {
  var vT = new VT(id, param);
  vTs[id] = vT;
  if (vT.type=="input") vT.tgl.checked = visible;
  if (vT.type=="select" && vT.param.activeOptionValue.indexOf(",")==-1) {
     for (var i=0; i<vT.tgl.options.length; i++) {
        if (vT.tgl.options[i].value == vT.param.activeOptionValue) vT.tgl.selectedIndex = i;
     }
  }
  if (visible) vT.show();
  else vT.hide();
}

function tV(id) {
  vTs[id].toggle();
}

// ToolTip Helper
var ttDiv = null;
// add class styles for
// .tooltip-div {}
// .tooltip-trigger {}
function initToolTips() {
  ttDiv = document.createElement("div");
  document.body.appendChild(ttDiv);
  ttDiv.id = "ttDiv";
  ttDiv.className = "tooltip-div";
  ttDiv.style.position = "absolute";
  ttDiv.style.display = "none";

  var elements = document.body.getElementsByTagName("*");
  for (var i = 0; i < elements.length; i++) {
    var ele = elements[i];
    if (hasClass(ele, "tooltip")) {
      var trigger = getChildren(ele,"*","tooltip-trigger")[0];
      var text = getChildren(ele,"*","tooltip-text")[0];
      text.style.display = "none";
      addEvent(trigger, "mouseover", function (evt) { 
        var sl = (window.pageXOffset ? window.pageXOffset : document.body.scrollLeft);
        var st = (window.pageYOffset ? window.pageYOffset : document.body.scrollTop);
        var x = (evt.clientX + sl);
        var y = (evt.clientY + st);
        var ele = evt.srcElement ? evt.srcElement : evt.target;
        var p = getParentElement(ele, "*", "tooltip");
        var text = getChildren(p,"*","tooltip-text")[0];
        ttDiv.innerHTML = text.innerHTML;
        ttDiv.style.display = "block";
        ttDiv.style.left = (x+10)+"px";
        ttDiv.style.top = (y+10)+"px";
      });
      addEvent(trigger, "mouseout", function (evt) { 
        ttDiv.style.display = "none";
      });
    }
  }
}
addEvent(window, "load", initToolTips);

userAgent = navigator.userAgent.toLowerCase();
isIE     = ((userAgent.indexOf("msie") != -1) && (userAgent.indexOf("opera") == -1));
isOpera  = (userAgent.indexOf("opera") != -1);
isMac     = (userAgent.indexOf("mac") != -1);
isMacIE = (isIE && isMac);
isWinIE = (isIE && !isMac);
isSafari = (userAgent.indexOf("safari") != -1);
isGecko  = (navigator.product == "Gecko" && !isSafari);

KEY_TAB = 9;
KEY_REFRESH = 116; //F5
KEY_ENTER= 13; 
TAB_INDENT = 2;
KEY_SPACE = 32;
