  var undefined;
  
  function ImageFader (id) {
   this._timeOut;
   this._timeOutFade;
   this._imgIDX = 0;
   
   this.id = undefined;
   this.imageList = [];
   this.drawElementIDX = undefined;
   this.groundImageIDX = undefined;
   this.fadeElementIDX = undefined;
   this.time = 5000; // default 5 sec (Angaben in Millisekunden)
   this.timeFade = 100; // default 10 millisec (Angaben in Millisekunden)
  
   this._setID(id);
  }
  
  //################################################################
  
  ImageFader.prototype._setID = function (str) {
    if (arguments.length != 1) {
      focus();
      throw new Error("ImageFader->_setID: Falsche Anzahl von Argumenten!");
    }
    if (typeof str != "string") {
      focus();
      throw new Error("ImageFader->_setID: Argument str ist nicht vom Typ String!");
    }
    this.id = str;
  }
  
  //################################################################
  
  ImageFader.prototype.addImageList = function (str) {
    if (arguments.length != 1) {
      focus();
      throw new Error("ImageFader->addImageList: Falsche Anzahl von Argumenten!");
    }
    if (typeof str != "string") {
      focus();
      throw new Error("ImageFader->addImageList: Argument str ist nicht vom Typ String!");
    }
    var img = new Image();
    img.src = str;
    this.imageList.push(img);
  }
  
  //################################################################
  
  ImageFader.prototype.setDrawElementIDX = function (str) {
    if (arguments.length != 1) {
      focus();
      throw new Error("ImageFader->setDrawElementIDX: Falsche Anzahl von Argumenten!");
    }
    if (typeof str != "string") {
      focus();
      throw new Error("ImageFader->setDrawElementIDX: Argument str ist nicht vom Typ String!");
    }
    this.drawElementIDX = str;
  }
  
  //################################################################
  
  ImageFader.prototype.setFadeElementIDX = function (str) {
    if (arguments.length != 1) {
      focus();
      throw new Error("ImageFader->setFadeElementIDX: Falsche Anzahl von Argumenten!");
    }
    if (typeof str != "string") {
      focus();
      throw new Error("ImageFader->setFadeElementIDX: Argument str ist nicht vom Typ String!");
    }
    this.fadeElementIDX = str;
  }
  
  //################################################################
  
  ImageFader.prototype.setGroundImageIDX = function (str) {
    if (arguments.length != 1) {
      focus();
      throw new Error("ImageFader->setGroundImageIDX: Falsche Anzahl von Argumenten!");
    }
    if (typeof str != "string") {
      focus();
      throw new Error("ImageFader->setGroundImageIDX: Argument str ist nicht vom Typ String!");
    }
    this.groundImageIDX = str;
  }
  
  //################################################################
  
  ImageFader.prototype.setTime = function (n) {
    if (arguments.length!=1) {
      focus();
      throw new Error("ImageFader->setTime: Falsche Anzahl von Argumenten!");
    }
    if (typeof n != "number") {
      focus();
      throw new Error("ImageFader->setTime: Argument ist nicht vom Typ number!");
    }
    this.time = n;
  }
  
  //################################################################
  
  ImageFader.prototype.setTimeFade = function (n) {
    if (arguments.length!=1) {
      focus();
      throw new Error("ImageFader->setTimeFade: Falsche Anzahl von Argumenten!");
    }
    if (typeof n != "number") {
      focus();
      throw new Error("ImageFader->setTimeFade: Argument ist nicht vom Typ number!");
    }
    this.timeFade = n;
  }
  
  //################################################################
  
  ImageFader.prototype.runImageFader = function () {
     var elem = document.getElementById(this.drawElementIDX);
     var fadeElem = document.getElementById(this.fadeElementIDX);
     var groundElem = document.getElementById(this.groundImageIDX);
     if (! elem){
      focus();
      throw new Error("ImageFader->runImageFader: Es existiert kein HTML-Element mit ID = " +  this.drawElementIDX);
     }
     if (! fadeElem){
      focus();
      throw new Error("ImageFader->runImageFader: Es existiert kein HTML-Element mit ID = " +  this.fadeElementIDX);
     }
     if (! groundElem){
      focus();
      throw new Error("ImageFader->runImageFader: Es existiert kein HTML-Element mit ID = " +  this.groundImageIDX);
     }
     if (! this.imageList.length){
      focus();
      throw new Error("ImageFader->runImageFader: Es wurden keine Images hinzugefügt");
     }
     this._setFadeElementAttr();
     var idx = this.id;
     var func = function () {ImageFader.getInstance(idx)._fadeNext();}
     var img = this.imageList[this._imgIDX];
     if (! img.complete) {
       var onloadFunc = function () {ImageFader.getInstance(idx)._timeOut = window.setTimeout(func, ImageFader.getInstance(idx).time);}
       img.onload = onloadFunc;
       return;
     }   
     this._timeOut = window.setTimeout(func, this.time);
  }
  
  //################################################################
  
  ImageFader.prototype._fadeNext = function () {
    if (this._timeOut) {
      window.clearTimeout(this._timeOut);
    }
    this._imgIDX++;
    if (! this.imageList[this._imgIDX]){
      this._imgIDX = 0;
    }
    var idx = this.id;
    var funcNext = function () {ImageFader.getInstance(idx)._fadeNext();}
    var timeOutFuncNext = function () {ImageFader.getInstance(idx)._timeOut = window.setTimeout(funcNext, ImageFader.getInstance(idx).time);}
    var funcFade = function () {ImageFader.getInstance(idx)._fadeImage(0, timeOutFuncNext);}
    var fadeElem = document.getElementById(this.fadeElementIDX);
    fadeElem.innerHTML = '';
    var img = this.imageList[this._imgIDX];
    fadeElem.appendChild(img);
    if (! img.complete) {
       var onloadFunc = funcFade;
       return;
    }   
    funcFade();
  }
  
  //################################################################
  
  ImageFader.prototype._fadeImage = function (diff, endFunc) {
    if (this._timeOutFade){
      window.clearTimeout(this._timeOutFade);
    }
    var idx = this.id;
    var fadeElem = document.getElementById(this.fadeElementIDX);
    var opac;
    var opacGrenzwert = 1;
    if (fadeElem.filters != undefined){
      // IE
      opacGrenzwert = 100;
      opac = parseFloat(0 + parseFloat(diff));
      if (fadeElem.filters['Alpha']) {
        fadeElem.filters['Alpha']['opacity'] = opac;
        fadeElem.filters['Alpha']['finishopacity'] = opac;
      }
      diff += 8;
    } else {
      // Other
      var opac = parseFloat(0 + parseFloat(diff));
      fadeElem.style.opacity = opac;
      diff += 0.08;
    }
    //alert(opac + ' : ' + diff +' : ' + opacGrenzwert );
    if (opac < opacGrenzwert){
      var funcFade = function () {ImageFader.getInstance(idx)._fadeImage(diff, endFunc);}
      ImageFader.getInstance(idx)._timeOutFade = window.setTimeout(funcFade, ImageFader.getInstance(idx).timeFade);
      return;
    }
    this._resetFadeElement();
    endFunc();
  }
  
  //################################################################
  
  ImageFader.prototype._resetFadeElement = function () {
    var fadeElem = document.getElementById(this.fadeElementIDX);
    if (fadeElem.filters != undefined){
      // IE
      if (fadeElem.filters['Alpha']) {
        fadeElem.filters['Alpha']['opacity'] = 0;
        fadeElem.filters['Alpha']['finishopacity'] = 0;
      }  
    } else {
      // Other
      fadeElem.style.opacity = 0;
    }
    var groundElem = document.getElementById(this.groundImageIDX);
    var img = this.imageList[this._imgIDX];
    groundElem.src = img.src;
  }
  
  //################################################################
  
  ImageFader.prototype._setFadeElementAttr = function () {
    var elem = document.getElementById(this.drawElementIDX);
    var fadeElem = document.getElementById(this.fadeElementIDX);
    var groundElem = document.getElementById(this.groundImageIDX);
    fadeElem.style.position = 'absolute';
    //fadeElem.style.border = '10px solid #000000;';
    //fadeElem.style.zIndex = '10000';
    fadeElem.style.margin = 0;
    fadeElem.style.padding = 0;
    fadeElem.style.width = groundElem.offsetWidth + 'px';
    fadeElem.style.height = groundElem.offsetHeight + 'px';
    //fadeElem.style.top = ImageFader.getElementDocumentPositionTop(elem) + 'px';
    //fadeElem.style.left = ImageFader.getElementDocumentPositionLeft(elem) + 'px';
  }
  
  //################################################################
  
  ImageFader._increment = [];
  ImageFader._registerInstance = {};
  ImageFader._registerInstanceLength = [];
  
  //################################################################
  
  ImageFader.getInstance = function(id) {
    if (arguments.length!=1) {
      throw new Error("Falsche Anzahl von Argumenten!");
    }
    if (! (ImageFader._registerInstance[id])){
      focus();
      throw new Error("Es ist keine ImageFader.Instance mit id=" + id + " registriert!");
    }
    return ImageFader._registerInstance[id];
  }
  
  //################################################################
  
  ImageFader.createInstance = function(id) {
    if (!arguments.length) {
      id = 'ImageFader' + ImageFader._increment.length;
      ImageFader._increment.push(1);
    }
    if (! (ImageFader._registerInstance[id])){
      ImageFader._registerInstance[id] = new ImageFader(id);
      ImageFader._registerInstanceLength.push(id);
    } else {
      focus();
      throw new Error("ImageFader.createInstance: id schon vorhanden!");
    }
    return ImageFader.getInstance(id);
  }
  
  //################################################################

  ImageFader.getElementDocumentPositionTop = function(elem){
    var pos = 0;
    if (elem.nodeName.toLowerCase() == 'area'){
      elem = elem.parentNode;
    }
    if (elem.nodeName.toLowerCase() == 'map'){
      elem = elem.parentNode;
    }
    var nextElem = elem;
    pos += nextElem.offsetTop;
    while (nextElem.offsetParent) {
      pos += nextElem.offsetParent.offsetTop;
      nextElem = nextElem.offsetParent;
    }
    return parseFloat(pos);
  }
  
  //################################################################

  ImageFader.getElementDocumentPositionLeft = function(elem){
    var pos = 0;
    if (elem.nodeName.toLowerCase() == 'area'){
      elem = elem.parentNode;
    }
    if (elem.nodeName.toLowerCase() == 'map'){
      elem = elem.parentNode;
    }
    var nextElem = elem;
    pos += nextElem.offsetLeft;
    while (nextElem.offsetParent) {
      pos += nextElem.offsetParent.offsetLeft;
      nextElem = nextElem.offsetParent;
    }
    return parseFloat(pos);
  }
 
 
 


