/*
DropDownMenu - Unterstützung für IE6
*/

var initNaviListForIE6 = function() {

  // für den orderprozess verhindern
  if ($$("body.order_process")[0]) {
    return false;
  }

  var level_0_li = null;

  try {
    level_0_li = $$("#navigation div.navi_level_0 ul li.level_0_li");
  }
  catch(err) {
    console.log("CSS-Class: navi_level_0 not found");
  }

  var styleObject = {
    current: {
      a: {
        color             : '',
        backgroundImage   : "url(http://www.fotoalbum.de/mandants/foa/gfx/navi_button_left_on.gif?1247122194)"
      },
      li: {
        backgroundImage   : "url(http://www4.fotoalbum.de/mandants/foa/gfx/navi_button_right_on.gif?1247122194)"
      }
    },
    normal: {
      a: {
        color             : '',
        backgroundImage   : "url(http://www8.fotoalbum.de/mandants/foa/gfx/navi_button_left.gif?1247122194)"
      },
      li: {
        backgroundImage   : "url(http://www2.fotoalbum.de/mandants/foa/gfx/navi_button_right.gif?1247122194)"
      }
    },
    hover: {
      a: {
        color             : $("defaultHoverColorMenu").getStyle('color'),
        backgroundImage   : "url(http://www8.fotoalbum.de/mandants/foa/gfx/navi_button_left_hover.gif?1247122194)"
      },
      li: {
        backgroundImage   : "url(http://www8.fotoalbum.de/mandants/foa/gfx/navi_button_right_hover.gif?1247122194)"
      }
    }
  };

  $A(level_0_li).each(function(node) {

    var ankerEl     = node.getElementsByTagName('a')[0];
    var linkStatus  = node.className.split(" ")[0] == "current" ? "current" : "normal";

    styleObject[linkStatus].a.color             = ankerEl.getStyle("color");
    styleObject[linkStatus].a.backgroundImage   = ankerEl.getStyle("backgroundImage");
    styleObject[linkStatus].li.backgroundImage  = node.getStyle("backgroundImage");

    node.onmouseover = function() {
      if(this.getStyle('backgroundImage') == 'none') {
        delete styleObject.hover.li.backgroundImage;
        delete styleObject.hover.a.backgroundImage;
      }
      Element.setStyle(this, styleObject.hover.li);
      Element.setStyle(this.getElementsByTagName('a')[0], styleObject.hover.a);

      if(box = this.getElementsByTagName('ul')[0]) {
        Element.setStyle(box, { display : "block" });
      }
    }.bind(node);

    node.onmouseout = function() {

      if(this.className.split(" ")[0] == "current") {
        if(this.getStyle('backgroundImage') == 'none') {
          delete styleObject.current.li.backgroundImage;
          delete styleObject.current.a.backgroundImage;
        }

        Element.setStyle(this, styleObject.current.li);
        Element.setStyle(this.getElementsByTagName('a')[0], styleObject.current.a);
      }
      else {
        if(this.getStyle('backgroundImage') == 'none') {
          delete styleObject.normal.li.backgroundImage;
          delete styleObject.normal.a.backgroundImage;
        }

        Element.setStyle(this, styleObject.normal.li);
        Element.setStyle(this.getElementsByTagName('a')[0], styleObject.normal.a);
      }

      if(box = this.getElementsByTagName('ul')[0]) {
        Element.setStyle(box, { display : "none" });
      }

    }.bind(node);
  });
}

/* Try to fix the IE 6 flickering bug!
Solution found on http://www.mister-pixel.com/
*/
try {
  document.execCommand("BackgroundImageCache", false, true);
} catch(err) {}


if (!window.Node) {
  var Node = {
    ELEMENT_NODE    : 1,
    ATTRIBUTE_NODE  : 2,
    TEXT_NODE        : 3,
    COMMENT_NODE    : 8,
    DOCUMENT_NODE    : 9
  };
}

/* resets a Formular */
resetFormular = function(formular) {

  var inputElements = Form.getInputs(formular, 'text');

  $A(inputElements).each(function(inputItem) {
    inputItem.value = '';
  });

  var selectElements = formular.getElementsByTagName('option');

  $A(selectElements).each(function(selectItem) {
    if(selectItem.selected == true) {
      // Browser-Unterscheidung
      //selectItem.removeAttribute('selected');
      //selectItem.selected = false;
    }
  });
}

/* grab Elements from the DOM by className */
function getElementsByClass(searchClass,node,tag) {
  var classElements = new Array();
  if ( node == null )
    node = document;
  if ( tag == null )
    tag = '*';
  var els = node.getElementsByTagName(tag);

  var elsLen = els.length;
  var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
  for (i = 0, j = 0; i < elsLen; i++) {
    if ( pattern.test(els[i].className) ) {
      classElements[j] = els[i];
      j++;
    }
  }
  return classElements;
}

/**
 * Sucht im Parenttree nach dem ersten Element mit der gesuchten Klasse
 */
function getParentByClass(searchClass, node) {
  if (node == null ) {
    return false;
  }

  while (node != document) {
    var node = node.parentNode;

    var pattern = new RegExp("(^|\\s)" + searchClass + "(\\s|$)");
    if (pattern.test(node.className) ) {
      return node;
    }
  }
  return false;
}

/* insert an element after a particular node */
function insertAfter(parent, node, referenceNode) {
  parent.insertBefore(node, referenceNode.nextSibling);
}

/* get, set, and delete cookies */
function getCookie( name ) {

  if (FOA.SESSION.id) {
    var sessionID = FOA.SESSION.id;
  }
  else {
    var start = document.cookie.indexOf( name + "=" );
    var len = start + name.length + 1;
    if ( ( !start ) && ( name != document.cookie.substring( 0, name.length ) ) ) {
      return null;
    }
    if ( start == -1 ) return null;
    var end = document.cookie.indexOf( ";", len );
    if ( end == -1 ) end = document.cookie.length;
    var sessionID = unescape( document.cookie.substring( len, end ) );
  }

  return sessionID;
}

function setCookie( name, value, expires, path, domain, secure ) {
  var today = new Date();
  today.setTime( today.getTime() );
  if ( expires ) {
    expires = expires * 1000 * 60 * 60 * 24;
  }
  var expires_date = new Date( today.getTime() + (expires) );
  document.cookie = name+"="+escape( value ) +
    ( ( expires ) ? ";expires="+expires_date.toGMTString() : "" ) + //expires.toGMTString()
    ( ( path ) ? ";path=" + path : "" ) +
    ( ( domain ) ? ";domain=" + domain : "" ) +
    ( ( secure ) ? ";secure" : "" );
}

function deleteCookie( name, path, domain ) {
  if ( getCookie( name ) ) document.cookie = name + "=" +
      ( ( path ) ? ";path=" + path : "") +
      ( ( domain ) ? ";domain=" + domain : "" ) +
      ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
}

/* sprintf for javascript */
function sprintf() {
    function pad(str, len, chr, leftJustify) {
  var padding = (str.length >= len) ? '' : Array(1 + len - str.length >>> 0).join(chr);
  return leftJustify ? str + padding : padding + str;

    }

    function justify(value, prefix, leftJustify, minWidth, zeroPad) {
  var diff = minWidth - value.length;
  if (diff > 0) {
      if (leftJustify || !zeroPad) {
    value = pad(value, minWidth, ' ', leftJustify);
      } else {
    value = value.slice(0, prefix.length) + pad('', diff, '0', true) + value.slice(prefix.length);
      }
  }
  return value;
    }

    function formatBaseX(value, base, prefix, leftJustify, minWidth, precision, zeroPad) {
  // Note: casts negative numbers to positive ones
  var number = value >>> 0;
  prefix = prefix && number && {'2': '0b', '8': '0', '16': '0x'}[base] || '';
  value = prefix + pad(number.toString(base), precision || 0, '0', false);
  return justify(value, prefix, leftJustify, minWidth, zeroPad);
    }

    function formatString(value, leftJustify, minWidth, precision, zeroPad) {
  if (precision != null) {
      value = value.slice(0, precision);
  }
  return justify(value, '', leftJustify, minWidth, zeroPad);
    }

    var a = arguments, i = 0, format = a[i++];
    return format.replace(sprintf.regex, function(substring, valueIndex, flags, minWidth, _, precision, type) {
      if (substring == '%%') return '%';

      // parse flags
      var leftJustify = false, positivePrefix = '', zeroPad = false, prefixBaseX = false;
      for (var j = 0; flags && j < flags.length; j++) switch (flags.charAt(j)) {
    case ' ': positivePrefix = ' '; break;
    case '+': positivePrefix = '+'; break;
    case '-': leftJustify = true; break;
    case '0': zeroPad = true; break;
    case '#': prefixBaseX = true; break;
      }

      // parameters may be null, undefined, empty-string or real valued
      // we want to ignore null, undefined and empty-string values

      if (!minWidth) {
    minWidth = 0;
      } else if (minWidth == '*') {
    minWidth = +a[i++];
      } else if (minWidth.charAt(0) == '*') {
    minWidth = +a[minWidth.slice(1, -1)];
      } else {
    minWidth = +minWidth;
      }

      // Note: undocumented perl feature:
      if (minWidth < 0) {
    minWidth = -minWidth;
    leftJustify = true;
      }

      if (!isFinite(minWidth)) {
    throw new Error('sprintf: (minimum-)width must be finite');
      }

      if (!precision) {
    precision = 'fFeE'.indexOf(type) > -1 ? 6 : (type == 'd') ? 0 : void(0);
      } else if (precision == '*') {
    precision = +a[i++];
      } else if (precision.charAt(0) == '*') {
    precision = +a[precision.slice(1, -1)];
      } else {
    precision = +precision;
      }

      // grab value using valueIndex if required?
      var value = valueIndex ? a[valueIndex.slice(0, -1)] : a[i++];

      switch (type) {
    case 's': return formatString(String(value), leftJustify, minWidth, precision, zeroPad);
    case 'c': return formatString(String.fromCharCode(+value), leftJustify, minWidth, precision, zeroPad);
    case 'b': return formatBaseX(value, 2, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
    case 'o': return formatBaseX(value, 8, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
    case 'x': return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
    case 'X': return formatBaseX(value, 16, prefixBaseX, leftJustify, minWidth, precision, zeroPad).toUpperCase();
    case 'u': return formatBaseX(value, 10, prefixBaseX, leftJustify, minWidth, precision, zeroPad);
    case 'i':
    case 'd': {
            var number = parseInt(+value);
            var prefix = number < 0 ? '-' : positivePrefix;
            value = prefix + pad(String(Math.abs(number)), precision, '0', false);
            return justify(value, prefix, leftJustify, minWidth, zeroPad);
        }
    case 'e':
    case 'E':
    case 'f':
    case 'F':
    case 'g':
    case 'G':
              {
            var number = +value;
            var prefix = number < 0 ? '-' : positivePrefix;
            var method = ['toExponential', 'toFixed', 'toPrecision']['efg'.indexOf(type.toLowerCase())];
            var textTransform = ['toString', 'toUpperCase']['eEfFgG'.indexOf(type) % 2];
            value = prefix + Math.abs(number)[method](precision);
            return justify(value, prefix, leftJustify, minWidth, zeroPad)[textTransform]();
        }
    default: return substring;
      }
        });
}
sprintf.regex = /%%|%(\d+\$)?([-+#0 ]*)(\*\d+\$|\*|\d+)?(\.(\*\d+\$|\*|\d+))?([scboxXuidfegEG])/g;

/**
 * Trival printf implementation, probably only useful during page-load.
 * Note: you may as well use "document.write(sprintf(....))" directly
 */
function printf() {
    // delegate the work to sprintf in an IE5 friendly manner:
    var i = 0, a = arguments, args = Array(arguments.length);
    while (i < args.length) args[i] = 'a[' + (i++) + ']';
    document.write(eval('sprintf(' + args + ')'));
}

if( !String.sprintf ) {
 String.sprintf = sprintf;
}

//
//  Extending built-in Array object
//  - array.removeDuplicates()
//  - array.empty()
//
Array.prototype.removeDuplicates = function () {
  for(i = 1; i < this.length; i++){
    if(this[i][0] == this[i-1][0]){
      this.splice(i,1);
    }
  }
}

// -----------------------------------------------------------------------------------

Array.prototype.empty = function () {
  for(i = 0; i <= this.length; i++){
    this.shift();
  }
}

// -----------------------------------------------------------------------------------

function number_format (number, decimals, dec_point, thousands_sep) {
  var exponent = "";
  var numberstr = number.toString ();
  var eindex = numberstr.indexOf ("e");
  if (eindex > -1)
  {
    exponent = numberstr.substring (eindex);
    number = parseFloat (numberstr.substring (0, eindex));
  }

  if (decimals != null)
  {
    var temp = Math.pow (10, decimals);
    number = Math.round (number * temp) / temp;
  }
  var sign = number < 0 ? "-" : "";
  var integer = (number > 0 ?
      Math.floor (number) : Math.abs (Math.ceil (number))).toString ();

  var fractional = number.toString ().substring (integer.length + sign.length);
  dec_point = dec_point != null ? dec_point : ".";
  fractional = decimals != null && decimals > 0 || fractional.length > 1 ?
               (dec_point + fractional.substring (1)) : "";
  if (decimals != null && decimals > 0)
  {
    for (i = fractional.length - 1, z = decimals; i < z; ++i)
      fractional += "0";
  }

  thousands_sep = (thousands_sep != dec_point || fractional.length == 0) ?
                  thousands_sep : null;
  if (thousands_sep != null && thousands_sep != "")
  {
  for (i = integer.length - 3; i > 0; i -= 3)
      integer = integer.substring (0 , i) + thousands_sep + integer.substring (i);
  }

  return sign + integer + fractional + exponent;
}

function format_bytes(bytes) {

  var byteTypes  = new Array("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB");
  var factor    = 1024;
  var unit      = 0;

  while (bytes >= factor) {

    bytes = bytes / factor;
    unit++;
  }
  return number_format(bytes, 2, ".", ",") + " " + byteTypes[unit];
}


/*===================================================================================*/

function UTF8Encoder() {

  /**
   * Codiert einen String in UTF-8
   */
  this.encode2UTF8 = function (nonUTF8) {
    var c, s;
    var enc = "";
    var i = 0;
    while (i < nonUTF8.length) {
      c = nonUTF8.charCodeAt(i++);

      // handle UTF-16 surrogates
      if (c>=0xDC00 && c<0xE000) {
        continue;
      }

      if (c>=0xD800 && c<0xDC00) {
        if (i >= nonUTF8.length) {
          continue;
        }

        s = nonUTF8.charCodeAt(i++);

        if (s<0xDC00 || c>=0xDE00) {
          continue;
        }

        c = ((c - 0xD800) << 10) + (s - 0xDC00) + 0x10000;
      }
      // output value
      if (c < 0x80) {
        enc += String.fromCharCode(c);
      }
      else if (c < 0x800) {
        enc += String.fromCharCode(0xC0 + (c >> 6), 0x80 + (c & 0x3F));
      }
      else if (c < 0x10000) {
        enc += String.fromCharCode(0xE0 + (c >> 12), 0x80 + (c >> 6 & 0x3F), 0x80 + (c & 0x3F));
      }
      else {
        enc += String.fromCharCode(0xF0 + (c >> 18), 0x80 + (c >> 12 & 0x3F), 0x80 + (c >> 6 & 0x3F), 0x80 + (c & 0x3F));
      }
    }
    return enc;
  }

  /**
   * Gültige Hexadezimale Zeichen
   */
  var hexchars = "0123456789ABCDEF";

  /**
   * Dezimal => Hexadezimal-Converter
   */
  var toHex = function (n) {
    return hexchars.charAt(n>>4)+hexchars.charAt(n & 0xF);
  }

  /**
   * Gültige Zeichen in einer URL
   */
  var okURIchars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";

  /**
   * Wandelt einen String in eine URL-Komponente um
   * => UTF-8-codiert
   * => urlencoded
   */
  this.urlencode = function(s) {
    var s = this.encode2UTF8(s);
    var c;
    var enc = "";
    for (var i= 0; i < s.length; i++) {
      if (okURIchars.indexOf(s.charAt(i))==-1)
        enc += "%"+toHex(s.charCodeAt(i));
      else
        enc += s.charAt(i);
    }
    return enc;
  }
}

/* ObserverHandler zum (de)registriern der Observer in Prototype */
var ObserverHandler = Class.create();
ObserverHandler.prototype = {

  initialize:function() {
    this.Listeners = new Hash();
  },

  // unset Eventhandler(obs) from one Element
  unsetObserver:function(e,obs) {
    e = $(e);
    var elementID = e.id;

    // use this to unset a observer: this.unsetObserver(Element.id, obs);
    if (this.Listeners[elementID]) {
      for (var i = 0; i < this.Listeners[elementID].length; i++) {
        if(obs == this.Listeners[elementID][i].obs) {
          Event.stopObserving(this.Listeners[elementID][i].e, this.Listeners[elementID][i].obs, this.Listeners[elementID][i].fct);
        }
      }
    }
  },

  // unset all Eventhandler from one Element
  unsetAllObserver:function(elementID) {
    var e;
    if (e = $(elementID)) {
      // use this to unset a observer: this.unsetObserver(Element.id);
      if (this.Listeners[elementID]) {
        for (var i = 0; i < this.Listeners[elementID].length; i++) {
          Event.stopObserving(this.Listeners[elementID][i].e, this.Listeners[elementID][i].obs, this.Listeners[elementID][i].fct);
        }
      }
    }
  },

  unsetAll:function() {
    $A(this.Listeners).each(function(oneListener) {
      this.unsetAllObserver(oneListener.key);
    }.bind(this));
  },

  setObserver:function(e,obs,fct) {
    e = $(e);

    // attach to observerlist
    // use this to set a observer: this.setObserver(Element, "click", myFunction());
    var elementID    = e.id
    var elListener   = new Object;
    elListener.e     = e;
    elListener.obs  = obs;
    elListener.fct  = fct;

    if (!this.Listeners[elementID]) {
      this.Listeners[elementID] = new Array();
    }
     this.Listeners[elementID].push(elListener);

    Event.observe(
      elListener.e,
      elListener.obs,
      elListener.fct
    );
  }
}


var Overlay = Class.create();
Overlay.prototype = {

  overlayElement: 0,

  initialize: function (element) {
    this.element = $(element);
    var elDims = Element.getDimensions(element);

    Position.relativize(element);
    new Insertion.Top(element, '<div class="overlayElement"></div>');
    var overlayElement = element.firstChild;

    elDims.width  = (elDims.width == 0)?'100%':elDims.width + 'px';
    elDims.height = (elDims.height == 0)?'100%':elDims.height + 'px';

    Element.setStyle(overlayElement, {
      width: elDims.width,
      height: elDims.height
    });

    //return overlayElement;
    this.overlayElement = overlayElement;
  },

  remove: function() {
    if (this.overlayElement) {
      Element.remove(this.overlayElement);
    }
  },

  removeOnload: function(element) {
    if (element) {
      Event.observe(element, 'load', (function() {
        this.remove();
      }).bind(this));
    }
  }
}


function fixIEPNG() {
  var arVersion = navigator.appVersion.split("MSIE")
  var version = parseFloat(arVersion[1])
  var isWin = navigator.appVersion.match(/Windows/)
  if (version < 7 && isWin) {
    for(var i=0; i<document.images.length; i++) {
      var img = document.images[i];
      var imgName = img.src.toUpperCase();

      if (imgName.substring(imgName.length-3, imgName.length) == "PNG") {
        var imgID = (img.id) ? "id='" + img.id + "' " : "";
        var imgClass = (img.className) ? "class='" + img.className + "' " : "";
        var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' ";
        var imgStyle = "display:inline-block;" + img.style.cssText;
        if (img.align == "left") imgStyle = "float:left;" + imgStyle;
        if (img.align == "right") imgStyle = "float:right;" + imgStyle;
        if (img.parentElement.href) imgStyle = "cursor:hand;" + imgStyle;
        var strNewHTML = "<span " + imgID + imgClass + imgTitle
          + " src=\"" + img.src + "\" style=\"" + "width:" + img.width + "px; height:" + img.height + "px;" + imgStyle + ";"
          + "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
          + "(src=\'" + img.src + "\', sizingMethod='scale');\"></span>";
        img.outerHTML = strNewHTML;
        i = i-1;
      }
    }
  }
}

var BasicBorderBox = Class.create();
BasicBorderBox.prototype = {

  initialize: function() {
    this.draggable = false;
    this.onClose   = null;
  },

  /**
   * Zeigt die Box an
   */
  show: function(boxID) {

    // Element-ID merken
    this.boxID = boxID;

    // Innere und äußere Boxen ("borderBox" / "borderedBox")
    this.content = $(boxID);

    // Wenn die Borderbox noch nicht gerendert ist...
    if (!Element.hasClassName(this.content.parentNode, "borderedBox")) {

      // deleteBox absolut positionieren (wichtig zur Vermeidung des Ruckelns)
      this.content.style.position = 'absolute';

      // Klassennamen richtig setzen (wichtig, damit die Box von der Funktion prepareBorderBoxes() erfasst wird)
      Element.addClassName(this.content, "borderBox");

      // borderedBox erstellen
      this.createBorderBox();

      // DeleteBox neu ermitteln (wichtig, das es nach der ausführung von prepareBorderBoxes() zur Verschiebung von ...
      // child<->parent-Beziehungen kommt
      this.content = $(boxID);
      this.borderBox = this.content.parentNode;

      // innere Box anzeigen
      Element.show(this.content);

      //console.log("totalWidth: " + this.outerSize.width + "x" +  + this.outerSize.height);
      //debug("conentSize: " + this.contentWidth);
      //debug("bgSize: " + this.bgSize.width + "x" + this.bgSize.height);
    }
    // Die Borderbox ist bereits gerendert
    else {
      this.borderBox = this.content.parentNode;

      // Äussere Box ("borderedBox") einblenden
      Element.show(this.borderBox);
    }
  },

  /**
   * macht die Box draggable, !!! erst nachdem die Box gerendert wurde !!!
   */
  makeDraggable: function(dragID) {
    this.obs = new ObserverHandler();
    this.draggable = true;
    this.content.parentNode.id = dragID;
    dndMgr.registerDraggable( new Rico.Draggable(dragID, dragID));
    this.obs.setObserver(this.content.parentNode, "mouseup", function(){dndMgr._doStopDragProcessing()});
  },

  /**
   * Fügt das Schließen-Icon hinzu (für Popups)
   */
  addCloseIcon: function() {

    // Wenn das Schließen-Icon noch nicht erstellt wurde, jetzt anlegen
    if (!getElementsByClass('borderBoxCloseLink', this.borderBox)[0]) {

      // Link-Element außenherum
      var aTag = document.createElement('a');
      aTag.href = '#';
      Element.addClassName(aTag, 'borderBoxCloseLink');

      // Darin ein (x)-Icon
      var closeIcon = document.createElement('img');
      closeIcon.src = this.closeIcon.url;

      // Position legt der BorderboxTyp fest (A/B)
      Element.setStyle(closeIcon, {
        position: 'absolute',
        top:    this.closeIcon.top    + 'px',
        right:  this.closeIcon.right  + 'px',
        width:  this.closeIcon.width  + 'px',
        height: this.closeIcon.height + 'px'
      })
      aTag.appendChild(closeIcon);
      this.borderBox.appendChild(aTag);
      this.fixIEPNG(closeIcon);

      // Click auf den Closelink abfangen
      var closeLink = getElementsByClass('borderBoxCloseLink', this.borderBox, 'a')[0];
      this.closeIconObserver = this.hide.bind(this);
      Event.observe(closeLink, 'click', this.closeIconObserver);
    }
  },

  /**
   * Zeige als Popup
   */
  showAsPopup: function(boxID, hideByDocumentClick) {

    // Box anzeigen
    this.show(boxID);

    // Position absolut setzen
    Element.setStyle(this.borderBox, {
      position: 'absolute',
      zIndex: 1000
    })

    // Close-Icon einblenden
    this.addCloseIcon();

    // Click auf die Box selbst abfangen: nichts tun!
    Event.observe(this.borderBox, 'click', Page._linkDoNothing.bindAsEventListener());


    // Click auf das document abfangen: Box schließen
    this.docObserver = this.hide.bind(this);

    if(!hideByDocumentClick) {
      Event.observe(document, 'click', this.docObserver, false);
    }
  },

  /**
   * Erstellt die Borderbox
   */
  createBorderBox: function() {

    // Gibt es eine Width-Angabe über Styles?
    if (this.content.style.width) {
      //debug("width via Styles");

      // Größe der Borderboxen festlegen
      this.outerSize = Element.getDimensions(this.content);

      // Innengröße auf Außengröße umrechnen (Höhe ist automatisch)
      this.contentWidth = this.outerSize.width
                       - (this.imgSizes.left + this.imgSizes.right)
                       + (this.centerOffset.left + this.centerOffset.right);

    }
    // Ansonsten Breite automatisch bestimmen
    else {
      //debug("width automatisch");

      // Innengröße auf Außengröße umrechnen (Höhe ist automatisch)
      this.contentWidth = Element.getDimensions(this.content).width;

      // Größe der Borderboxen festlegen
      this.outerSize = {
        width: (this.imgSizes.left + this.imgSizes.right)
              + Math.max(1, this.contentWidth - (this.centerOffset.left + this.centerOffset.right))
      }
    }

    // Borderbox erstellen und Styles aus dem Ausgangselement mitnehmen
    var borderBox = document.createElement('div');
    Element.setStyle(borderBox, {
      float:        Element.getStyle(this.content, 'float'),
      marginTop:    Element.getStyle(this.content, 'marginTop'),
      marginBottom: Element.getStyle(this.content, 'marginBottom'),
      marginLeft:   Element.getStyle(this.content, 'marginLeft'),
      marginRight:  Element.getStyle(this.content, 'marginRight')
    })
    Element.addClassName(borderBox, 'borderedBox');

    // Contentbox für den Inhalt erstellen
    var contentBox = this.content.cloneNode(true);

    // gibts einen Abstand(bottom)
    var marginBottom = 10;
    if (marginBottom = contentBox.style.marginBottom) {
      marginBottom = parseInt(marginBottom);
    }

    Element.addClassName(contentBox, 'borderBoxContent');
    Element.removeClassName(contentBox, 'borderBox');
    Element.setStyle(contentBox, {
      width: this.contentWidth + 'px',
      float: 'none',
      margin: '0'
    })
    borderBox.appendChild(contentBox);

    // Elemente in den DOM-Tree einfügen
    this.content.parentNode.replaceChild(borderBox, this.content);

    // Größe der ContentBox messen (Höhe interessiert uns!)
    var contentBoxSize = Element.getDimensions(contentBox);

    // Größe der Hintergrundbox bestimmen
    this.bgSize = {
      width:  Math.max(1, contentBoxSize.width - (this.centerOffset.left + this.centerOffset.right)),
      height: Math.max(1, contentBoxSize.height - (this.centerOffset.top + this.centerOffset.bottom) + marginBottom)
    }

    // Daraus ergibt sich die Größe der äußeren Box!
    this.outerSize.height = this.bgSize.height
                          + this.imgSizes.top
                          + this.imgSizes.bottom;
    Element.setStyle(borderBox, {
      position: 'relative',
      width:    this.outerSize.width  + 'px',
      height:   this.outerSize.height + 'px'
    })

    // Eine Box in der richtigen Größe für den weißen Hintergrund erstellen
    var innerBGBox = document.createElement('div');

    var bgColorElement;
    var bgColor = "white";
    if ((bgColorElement = $("borderBoxBGColorIndex")) && bgColor != "transparent") {
      bgColor = bgColorElement.getStyle('backgroundColor');
    }

    Element.setStyle(innerBGBox, {
      float:     'left',
      background: bgColor,
      width:      this.bgSize.width  + 'px',
      height:     this.bgSize.height + 'px'
    });

    borderBox.insertBefore(innerBGBox, contentBox);

    // Die Contentbox absolut positionieren
    Element.setStyle(contentBox, {
      position: 'absolute',
      top: (this.imgSizes.top - this.centerOffset.top) + 'px',
      left: (this.imgSizes.left - this.centerOffset.left) + 'px'
    });

    var imgNodeTopLeft = document.createElement('img');
    imgNodeTopLeft.src = this.images.topleft;
    Element.setStyle(imgNodeTopLeft, {
      float: 'left',
      width: this.imgSizes.left + 'px',
      height: this.imgSizes.top + 'px'
    })
    borderBox.insertBefore(imgNodeTopLeft, innerBGBox);
    this.fixIEPNG(imgNodeTopLeft);

    var imgNodeTop = document.createElement('img');
    imgNodeTop.src = this.images.top;
    Element.setStyle(imgNodeTop, {
      float: 'left',
      width: this.bgSize.width + 'px',
      height: this.imgSizes.top + 'px'
    })
    borderBox.insertBefore(imgNodeTop, innerBGBox);
    this.fixIEPNG(imgNodeTop);

    var imgNodeTopRight = document.createElement('img');
    imgNodeTopRight.src = this.images.topright;
    Element.setStyle(imgNodeTopRight, {
      float: 'left',
      width: this.imgSizes.right + 'px',
      height: this.imgSizes.top + 'px'
    })
    borderBox.insertBefore(imgNodeTopRight, innerBGBox);
    this.fixIEPNG(imgNodeTopRight);

    var imgNodeLeft = document.createElement('img');
    imgNodeLeft.src = this.images.left;
    Element.setStyle(imgNodeLeft, {
      float: 'left',
      height: this.bgSize.height + 'px',
      width: this.imgSizes.left + 'px'
    })
    borderBox.insertBefore(imgNodeLeft, innerBGBox);
    this.fixIEPNG(imgNodeLeft);

    var imgNodeRight = document.createElement('img');
    imgNodeRight.src = this.images.right;
    Element.setStyle(imgNodeRight, {
      float: 'left',
      height: this.bgSize.height + 'px',
      width: this.imgSizes.right + 'px'
    })
    borderBox.appendChild(imgNodeRight);
    this.fixIEPNG(imgNodeRight);

    var imgNodeBottomLeft = document.createElement('img');
    imgNodeBottomLeft.src = this.images.bottomleft;
    Element.setStyle(imgNodeBottomLeft, {
      float: 'left',
      height: this.imgSizes.bottom + 'px',
      width: this.imgSizes.left + 'px'
    })
    borderBox.appendChild(imgNodeBottomLeft);
    this.fixIEPNG(imgNodeBottomLeft);

    var imgNodeBottom = document.createElement('img');
    imgNodeBottom.src =this.images.bottom;
    Element.setStyle(imgNodeBottom, {
      float: 'left',
      width: this.bgSize.width + 'px',
      height: this.imgSizes.bottom + 'px'
    })
    borderBox.appendChild(imgNodeBottom);
    this.fixIEPNG(imgNodeBottom);

    var imgNodeBottomRight = document.createElement('img');
    imgNodeBottomRight.src = this.images.bottomright;
    Element.setStyle(imgNodeBottomRight, {
      float: 'left',
      height: this.imgSizes.bottom + 'px',
      width: this.imgSizes.right + 'px'
    })
    borderBox.appendChild(imgNodeBottomRight);
    this.fixIEPNG(imgNodeBottomRight);
  },

  /**
   * Fixt ein PNG-Image für den IE < 7
   */
  fixIEPNG: function(img) {
    var arVersion = navigator.appVersion.split("MSIE")
    var version = parseFloat(arVersion[1])
    var isWin = navigator.appVersion.match(/Windows/)

    if (version >= 5.5 && isWin) {

      var imgName = img.src.toUpperCase()
      if (imgName.substring(imgName.length-3, imgName.length) == "PNG")
      {
         var imgID = (img.id) ? "id='" + img.id + "' " : ""
         var imgClass = (img.className) ? "class='" + img.className + "' " : ""
         var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' "
         var imgStyle = "display:inline-block;" + img.style.cssText
         if (img.align == "left") imgStyle = "float:left;" + imgStyle
         if (img.align == "right") imgStyle = "float:right;" + imgStyle
         if (img.parentElement.href) imgStyle = "cursor:hand;" + imgStyle
         var strNewHTML = "<span " + imgID + imgClass + imgTitle
         + " src=\"" + img.src + "\" style=\"" + "width:" + img.width + "px; height:" + img.height + "px;" + imgStyle + ";"
         + "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader"
         + "(src=\'" + img.src + "\', sizingMethod='scale');\"></span>"
         img.outerHTML = strNewHTML
         i = i-1
      }
    }
  },

  /**
   * Zeigt eine Borderbox mit einer bestimmten ID an
   */
  position: function(posX, posY) {

    // Positionen der äusseren Box setzen
    Element.setStyle(this.borderBox, {
      top:  (posY - this.borderBox.offsetHeight / 2) + "px",
      left: (posX - this.borderBox.offsetWidth  / 2) + "px"
    });
  },

  /**
   * Versteckt eine angezeigte Borderbox wieder
   */
  hide: function() {

    // deregister Draggable
    if (this.draggable) {
      dndMgr.deregisterDraggable(this.content.parentNode.id);
      this.obs.unsetAllObserver(this.content.parentNode.id);
    }

    // !!! eins von den elementen kann nicht dreregistriert werden !!!
    Event.stopObserving(this.borderBox, 'click', Page._linkDoNothing.bindAsEventListener());

    // Observer für document-click löschen
    Event.stopObserving(document, 'click', this.docObserver, false);

    if (this.closeIconObserver) {
      Event.stopObserving(this.closeIcon, 'click', this.closeIconObserver);
    }
    if(typeof this.onClose == 'function') {
      this.onClose();
    }
    // Element verstecken
    Element.hide(this.borderBox);
  }
}

/**
 * Basisformatierung
 */
var BaseFormat = {

  /**
   * Format-Funktion für Zahlen
   */
  _number_format: function (number, decimals, dec_point, thousands_sep) {

    // Exponentialschreibweise abfangen
    var exponent = "";
    var numberstr = number.toString ();
    var eindex = numberstr.indexOf ("e");
    if (eindex > -1) {
      exponent = numberstr.substring (eindex);
      number = parseFloat (numberstr.substring (0, eindex));
    }
    else {
      number = parseFloat(number);
    }

    // Nachkommastellen berechnen
    if (decimals != null) {
      var temp = Math.pow (10, decimals);
      number   = Math.round (number * temp) / temp;
    }

    // Vorzeichen festlegen
    var sign = number < 0 ? "-" : "";

    // Ganzzahlwert bestimmen (für Tausendertrennung)
    var integer = (number > 0 ?
        Math.floor(number):Math.abs(Math.ceil(number))).toString();

    // Nachkommastellen bestimmen
    var fractional = number.toString().substring(integer.length + sign.length);

    // Dezimalpunkt festlegen (default: .)
    dec_point = dec_point != null ? dec_point : ".";

    // Vor die Nachkommastellen kommt der Dezimaltrenner
    if (decimals != null && decimals > 0 || fractional.length > 1) {
      fractional = dec_point + fractional.substring(1);
    }
    else {
      fractional = "";
    }

    // ggf. Nullen an die Nachkommastellen anfügen
    if (decimals != null && decimals > 0) {
      for (i = fractional.length - 1, z = decimals; i < z; ++i)
        fractional += "0";
    }

    // Tausender-Trennzeichen angegeben und ungleich Dezimaltrenner?
    thousands_sep = (thousands_sep != dec_point || fractional.length == 0) ?
                    thousands_sep : null;

    // Tausender-Trennzeichen einfügen
    if (thousands_sep != null && thousands_sep != "") {
      for (i = integer.length - 3; i > 0; i -= 3) {
        integer = integer.substring (0 , i) + thousands_sep + integer.substring (i);
      }
    }

    // Vorzeichen, Ganzzahl, Nachkommastellen und ggf. Exponent zurückgeben
    return sign + integer + fractional + exponent;
  },

  amount: function(val) {
    return BaseFormat._number_format(parseFloat(val), 0, '.', ',');
  },

  number: function(val) {
    return BaseFormat._number_format(parseFloat(val), 2, '.', ',');
  },

  currency: function(val) {
    return BaseFormat.number(val);
  }
}

/* -----------------------------------*/
/* --->>> onDOMReady Extension <<<----*/
/* -----------------------------------*/


Object.extend(Event, {
  _domReady : function() {
    if (arguments.callee.done) return;
    arguments.callee.done = true;

    if (this._timer)  clearInterval(this._timer);

    this._readyCallbacks.each(function(f) { f() });
    this._readyCallbacks = null;
},
  onDOMReady : function(f) {
    if (!this._readyCallbacks) {
      var domReady = this._domReady.bind(this);

      if (document.addEventListener)
        document.addEventListener("DOMContentLoaded", domReady, false);

        /*@cc_on @*/
        /*@if (@_win32)
            document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
            document.getElementById("__ie_onload").onreadystatechange = function() {
                if (this.readyState == "complete") domReady();
            };
        /*@end @*/

        if (/WebKit/i.test(navigator.userAgent)) {
          this._timer = setInterval(function() {
            if (/loaded|complete/.test(document.readyState)) domReady();
          }, 10);
        }

        Event.observe(window, 'load', domReady);
        Event._readyCallbacks =  [];
    }
    Event._readyCallbacks.push(f);
  }
});

// Flash Player Version Detection - Rev 1.6
// Detect Client Browser type
// Copyright(c) 2005-2006 Adobe Macromedia Software, LLC. All rights reserved.
var FlashDetection = Class.create();
FlashDetection.prototype = {

  initialize: function() {
    this.isIE     = (navigator.appVersion.indexOf("MSIE") != -1)              ? true : false;
    this.isWin    = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
    this.isOpera  = (navigator.userAgent.indexOf("Opera") != -1)              ? true : false;
  },

  ControlFlashVersion: function() {

    var version;
    var axo;
    var e;

    // NOTE : new ActiveXObject(strFoo) throws an exception if strFoo isn't in the registry

    try {
      // version will be set for 7.X or greater players
      axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
      version = axo.GetVariable("$version");
    }
    catch (e) {}

    if (!version) {
      try {
        // version will be set for 6.X players only
        axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");

        // installed player is some revision of 6.0
        // GetVariable("$version") crashes for versions 6.0.22 through 6.0.29,
        // so we have to be careful.

        // default to the first public version
        version = "WIN 6,0,21,0";

        // throws if AllowScripAccess does not exist (introduced in 6.0r47)
        axo.AllowScriptAccess = "always";

        // safe to call for 6.0r47 or greater
        version = axo.GetVariable("$version");

      }
      catch (e) {}
    }

    if (!version)
    {
      try {
        // version will be set for 4.X or 5.X player
        axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
        version = axo.GetVariable("$version");
      }
      catch (e) {}
    }

    if (!version)
    {
      try {
        // version will be set for 3.X player
        axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.3");
        version = "WIN 3,0,18,0";
      }
      catch (e) {}
    }

    if (!version)
    {
      try {
        // version will be set for 2.X player
        axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
        version = "WIN 2,0,0,11";
      }
      catch (e) {
        version = -1;
      }
    }

    return version;
  },

  // JavaScript helper required to detect Flash Player PlugIn version information
  GetSwfVer: function () {

    // NS/Opera version >= 3 check for Flash plugin in plugin array
    var flashVer = -1;

    if (navigator.plugins != null && navigator.plugins.length > 0) {
      if (navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {

        var swVer2           = navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "";
        var flashDescription = navigator.plugins["Shockwave Flash" + swVer2].description;
        var descArray        = flashDescription.split(" ");
        var tempArrayMajor   = descArray[2].split(".");
        var versionMajor     = tempArrayMajor[0];
        var versionMinor     = tempArrayMajor[1];
        var versionRevision  = descArray[3];

        if (versionRevision == "") {
          versionRevision = descArray[4];
        }
        if (versionRevision[0] == "d") {
          versionRevision = versionRevision.substring(1);
        }
        else if (versionRevision[0] == "r") {
          versionRevision = versionRevision.substring(1);
          if (versionRevision.indexOf("d") > 0) {
            versionRevision = versionRevision.substring(0, versionRevision.indexOf("d"));
          }
        }
        var flashVer = versionMajor + "." + versionMinor + "." + versionRevision;
      }
    }
    // MSN/WebTV 2.6 supports Flash 4
    else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.6") != -1) flashVer = 4;
    // WebTV 2.5 supports Flash 3
    else if (navigator.userAgent.toLowerCase().indexOf("webtv/2.5") != -1) flashVer = 3;
    // older WebTV supports Flash 2
    else if (navigator.userAgent.toLowerCase().indexOf("webtv") != -1) flashVer = 2;
    else if ( this.isIE && this.isWin && !this.isOpera ) {
      flashVer = this.ControlFlashVersion();
    }

    return flashVer;
  },

  // When called with reqMajorVer, reqMinorVer, reqRevision returns true if that version or greater is available
  DetectFlashVer: function (reqMajorVer, reqMinorVer, reqRevision) {

    versionStr = this.GetSwfVer();

    if (versionStr == -1 ) {
      return false;
    }
    else if (versionStr != 0) {
      if(this.isIE && this.isWin && !this.isOpera) {
        // Given "WIN 2,0,0,11"
        tempArray         = versionStr.split(" ");   // ["WIN", "2,0,0,11"]
        tempString        = tempArray[1];      // "2,0,0,11"
        versionArray      = tempString.split(",");  // ['2', '0', '0', '11']
      }
      else {
        versionArray      = versionStr.split(".");
      }
      var versionMajor      = versionArray[0];
      var versionMinor      = versionArray[1];
      var versionRevision   = versionArray[2];

      // is the major.revision >= requested major.revision AND the minor version >= requested minor
      if (versionMajor > parseFloat(reqMajorVer)) {
        return true;
      }
      else if (versionMajor == parseFloat(reqMajorVer)) {
        if (versionMinor > parseFloat(reqMinorVer))
          return true;
        else if (versionMinor == parseFloat(reqMinorVer)) {
          if (versionRevision >= parseFloat(reqRevision))
            return true;
        }
      }
      return false;
    }
  }
};

