function ImgStreamerLightbox() {
  if(ImgStreamerLightbox.singleton == null) {
    ImgStreamerLightbox.singleton = new ImgStreamerLightboxClass();
  }
  return ImgStreamerLightbox.singleton;
}

function ImgStreamerLightboxClass()
{
  this.browser = 'UNKNOWN';
  this.opacity = 0.8;
  this.backgroundColor = '000000';
  this.foregroundColor = 'ffffff';
  this.ciColor = '019934';
  this.layer = null;
  this.galleryId = 'ImgStreamerLightboxPlayerId_';
  this.player = null;
  this.playerLayer = null;
  this.playerBG = null;
  this.closeLayer = null;
  this.swfWidth = 800;
  this.swfHeight = 600;
  this.zIndex = 10000;
  this.flashHiding = true;
  this.polite = true;
  this.flashVars = null;
  this.swfURL = null;
  this.intImages = 0;

  /**
   * Sets a companion url
   */
  this.setSWFURL = function(_url) {
    this.swfURL = _url;
    return this;
  }
  
  this.setGalleryId = function(_id) {
	  this.galleryId += _id;
	  return this;
  }

  /**
   * Explicitly sets the dimension of the player.
   */
  this.setDimension = function(_width, _height) {
    this.swfWidth  = _width;
    this.swfHeight = _height;
    return this;
  }

  /**
   * Sets the level on which the interstitial is displayed
   *
   * @param _zIndex the display level
   */
  this.setZIndex = function(_zIndex) {
    this.zIndex = new String(_zIndex);
    if(this.zIndex == null || !this.zIndex.match(/^[1-9][0-9]*$/)) {
      this.zIndex = 10000;
    }

    return this;
  }

  /**
   * Sets the background color of the layer.
   *
   * @param _color the background color
   */
  this.setBackgroundColor = function(_color) {
    this.backgroundColor = _color;
    if(this.backgroundColor == null || typeof(this.backgroundColor.match) == 'undefined' || !this.backgroundColor.match(/^[A-Fa-f0-9]{6}$/)) {
      this.backgroundColor = '000000';
    }

    return this;
  }

  /**
   * Sets the opacity of the layer.
   *
   * @param _opacity opacity value
   */
  this.setOpacity = function(_opacity) {
    this.opacity = _opacity;
    if(isNaN(this.opacity) || this.opacity < 0.0 || this.opacity > 1.0) {
      this.opacity = 0.8;
    }

    return this;
  }

  /**
   * Disables hiding other flash elements.
   */
  this.disableFlashHiding = function() {
    this.flashHiding = false;

    return this;
  }

  /**
   * Method which needs to be called when the page is completely loaded; usually done from <body onload="">.
   */
  this.init = function() {

    var onLoad   = false;
    var onResize = this.addEvent(window, "resize", OnResize);
    var onScroll = this.addEvent(window, "scroll", OnResize);
    var flashVer = this.getFlashVersion();

	//*
    // If one of the events where not registered, quit
    if(!onResize || !onScroll || flashVer < 9 || !this.detectBrowser()) {
      this.removeEvent(window, "resize", OnResize);
      this.removeEvent(window, "scroll", OnResize);

      // Make sure the layers are hidden
      this.closeLayers();
    } else {
      this.initLayers();
	  this.onResize();
    }
  }

  /**
   * Hides all <object> and <embed> tags
   */
  this.hideObjectsAndEmbeds = function() {
    // Check whether we have the necessary JS function
    if(typeof(document.getElementsByTagName) != 'undefined' && document.getElementsByTagName != null) {
      // Run through all <object> and <embed> tags
      var tags = [ 'object', 'embed' ];
      for(var j = 0; j < tags.length; j++) {
        // Get all tags with the given tag name
        var objects = document.getElementsByTagName(tags[j]);
        for(var i = 0; i < objects.length; i++) {
          // Exclude the interstitial player
          if(objects[i].getAttribute('id') != this.galleryId && objects[i].getAttribute('id') != this.companionPlayerId) {
            // Set a new attribute with the current visibility (either visible or hidden)
            objects[i].setAttribute('sc_ov', objects[i].style.visibility == null ? 'visible' : objects[i].style.visibility);

            // Hide the tag
            objects[i].style.visibility = 'hidden';
          }
        }
      }
    }
  }

  /**
   * Is called when the video ad has ended.
   */
  this.closeLayers = function(_galleryId) {
	  
      if(this.layer != null) {
        this.layer.style.visibility = 'hidden';
      }

      if(this.playerBG != null) {
        this.playerBG.style.visibility = 'hidden';
      }
	  
      if(this.playerLayer != null) {
        this.playerLayer.style.visibility = 'hidden';
      }
	  
      if(this.closeLayer != null) {
        this.closeLayer.style.visibility = 'hidden';
      }

      if(this.flashHiding) {
        this.showObjectsAndEmbeds();
      }

      // Call on end call back (if any)
      if(this.onEndCallback != null) {
        try {
          this.onEndCallback();
        } catch(e) {
          //this.debug('Couldn\'t call on end callback function');
        }
      }
  }

  /**
   * Shows <object> and <embed> tags which have been hidden by 'hideObjectsAndEmbeds'.
   */
  this.showObjectsAndEmbeds = function() {
    // Check whether we have the necessary JS function
    if(typeof(document.getElementsByTagName) != 'undefined' && document.getElementsByTagName != null) {
      // Run through all <object> and <embed> tags
      var tags = [ 'object', 'embed' ];
      for(var j = 0; j < tags.length; j++) {
        // Get all tags with the given tag name
        var objects = document.getElementsByTagName(tags[j]);
        for(var i = 0; i < objects.length; i++) {
          // For all <object> and <embed> tags with the 'sc_ov' attribute, revert the visibility
          var ov = objects[i].getAttribute('sc_ov');
          if(ov != null) {
            objects[i].style.visibility = ov;
          }
        }
      }
    }
  }

  /**
   * Centers the player depending on the view port and scrolling.
   */
  this.onResize = function() {
    //this.debug('- onResize()');

    // Let's see whether there is something to resize at all
    if(this.layer != null && this.playerLayer != null && this.playerBG != null && this.closeLayer != null) {
      var scroll   = this.getScrolling();
      var viewport = this.getViewport();

      var popWidth = viewport[0];
      if(popWidth < scroll[2]) {
        popWidth = scroll[2];
      }

      var popHeight = viewport[1];
      if(popHeight < scroll[3]) {
        popHeight = scroll[3];
      }

      this.layer.style.height = popHeight + "px";
      this.layer.style.width  = popWidth + "px";

      this.playerBG.style.width  = this.swfWidth + "px";
      this.playerBG.style.height = this.swfHeight + "px";
      this.playerBG.style.left   = Math.round((scroll[0] + ((viewport[0] - this.swfWidth - 2) / 2))) + "px";
      this.playerBG.style.top    = Math.round((scroll[1] + ((viewport[1] - this.swfHeight - 2) / 2))) + "px";

      this.playerLayer.style.width  = this.swfWidth + "px";
      this.playerLayer.style.height = this.swfHeight + "px";
      this.playerLayer.style.left   = Math.round((scroll[0] + ((viewport[0] - this.swfWidth - 2) / 2))) + "px";
      this.playerLayer.style.top    = Math.round((scroll[1] + ((viewport[1] - this.swfHeight - 2) / 2))) + "px";
	  
      this.closeLayer.style.width  = "13px";
      this.closeLayer.style.height = "13px";
      this.closeLayer.style.left   = Math.round((scroll[0] + ((viewport[0] - this.swfWidth - 2) / 2) - 21 + this.swfWidth)) + "px";
      this.closeLayer.style.top    = Math.round((scroll[1] + ((viewport[1] - this.swfHeight - 2) / 2) + 8)) + "px";
   }
  }

  /**
   * Add an event to the given object
   *
   * @param _obj the page element to add the event to
   * @param _event which event to add (e.g. "load")
   * @param _func the event handler
   * @return true if the event could be added, false otherwise
   */
  this.addEvent = function(_obj, _event, _func) {
    if(_obj.addEventListener) {
      _obj.addEventListener(_event, _func, false);
      return true;
    } else if(_obj.attachEvent) {
      return _obj.attachEvent("on" + _event, _func);
    }
    return false;
  }

  /**
   * Remove an event from the given object
   *
   * @param _obj the page element to add the event to
   * @param _event which event to add (e.g. "load")
   * @param _func the event handler
   * @return true if the event could be added, false otherwise
   */
  this.removeEvent = function(_obj, _event, _func) {
    if(typeof(_obj.removeEventListener) != 'undefined') {
      _obj.removeEventListener(_event, _func, false);
      return true;
    } else if(typeof(_obj.detachEvent) != 'undefined') {
      return _obj.detachEvent("on" + _event, _func);
    }
    return false;
  }
  
  /**
   * Sets the transparency (opacity) of an element in the page.
   *
   * @param _obj    the page element
   * @param _value the transparency (ranging from 0.0 (completely transparent) - 1.0 (not transparent at all))
   */
  this.makeTransparent = function(_obj, _value) {
    if(this.browser == 'IE') {
      _obj.style.filter = 'alpha(opacity=' + (_value * 100) + ')';
    } else {
      _obj.style.opacity = _value;
    }
  }

  /**
   * Determines the scroll position
   *
   * @return the top left position of the scroll area, false otherwise.
   */
  this.getScrolling = function() {
    if(document.compatMode == 'CSS1Compat') {
      return [ document.documentElement.scrollLeft, document.documentElement.scrollTop, document.documentElement.scrollWidth, document.documentElement.scrollHeight ];
    } else {
      return [ document.body.scrollLeft, document.body.scrollTop, document.body.scrollWidth, document.body.scrollHeight ];
    }
  }

  /**
   * Determines the view port.
   *
   * @return the width and height of the view port or false.
   */
  this.getViewport = function() {
    if(window.innerHeight != window.undefined) {
      return [ window.innerWidth - 15, window.innerHeight - 15 ];
    } else if(document.compatMode == 'CSS1Compat') {
      return [ document.documentElement.clientWidth - 15, document.documentElement.clientHeight - 15 ];
    } else if(document.body) {
      return [ document.body.clientWidth - 15, document.body.clientHeight - 15 ];
    }
    return false;
  }

  /**
   * Adds a hidden and transparent layer to the page which contains the mini player; the layer
   * is positioned on top of the player.
   */
  this.initLayers = function() {

    // Create player
    this.player = this.createPlayer(this.galleryId, this.swfWidth, this.swfHeight);
	this.closeBtn = this.createCloseBtn(this.galleryId);

    // For IE we need to create complete tags
    if(this.browser == 'IE') {
      this.layer = document.createElement('<div style="position:absolute; z-index:' + this.zIndex + '; top:0px; left:0px; width:100%; height:100%; filter:alpha(opacity=' + (this.opacity * 100) + '); background-color:#' + this.backgroundColor + ';">');

	  this.playerBG = document.createElement('<div style="position:absolute; z-index:' + this.zIndex + '; top:0px; left:0px; width:' + this.swfWidth + 'px; height:' + this.swfHeight + 'px; filter:alpha(opacity=' + (this.opacity * 100) + '); background-color:#' + this.foregroundColor + ';">');

      this.playerLayer = document.createElement('<div style="position:absolute; z-index:' + (this.zIndex + 1) + '; left:0px; top:0px; width:' + this.swfWidth + 'px; height:' + this.swfHeight + 'px; padding:0px 0px;">');
      this.playerLayer.appendChild(this.player);
	  
	  this.closeLayer = document.createElement('<div style="position:absolute; z-index:' + (this.zIndex + 2) + '; left:' + (this.swfWidth - 22) + 'px; top:9px; width:13px; height:13px; padding:0px 0px; background-color:#' + this.ciColor + ';">');
      this.closeLayer.appendChild(this.closeBtn);
    } else {
	  this.layer = document.createElement('div');
      this.layer.setAttribute('style', 'position:absolute; z-index:' + this.zIndex + '; top:0px; left:0px; width:100%; height:100%; opacity:' + this.opacity + '; background-color:#' + this.backgroundColor + ';');

      this.playerBG = document.createElement('div');
      this.playerBG.setAttribute('style', 'position:absolute; z-index:' + this.zIndex + '; top:0px; left:0px; width:' + this.swfWidth + 'px; height:' + this.swfHeight + 'px; opacity:' + this.opacity + '; background-color:#' + this.foregroundColor + ';');

      this.playerLayer = document.createElement('div');
      this.playerLayer.setAttribute('style', 'position:absolute; z-index:' + (this.zIndex + 1) + '; left:0px; top:0px; width:' + this.swfWidth + 'px; height:' + this.swfHeight + 'px; padding:0px 0px;">');
      this.playerLayer.appendChild(this.player);

      this.closeLayer = document.createElement('div');
      this.closeLayer.setAttribute('style', 'position:absolute; z-index:' + (this.zIndex + 2) + '; top:9px; left:' + (this.swfWidth - 22) + 'px; width:13px; height:13px; background-color:#' + this.ciColor + ';');
	  this.closeLayer.appendChild(this.closeBtn);
    }

    document.body.insertBefore(this.closeLayer, document.body.firstChild);
    document.body.insertBefore(this.playerLayer, document.body.firstChild);
    document.body.insertBefore(this.playerBG, document.body.firstChild);
    document.body.insertBefore(this.layer, document.body.firstChild);
	
    return true;
  }
  
  /**
   * Creates a close button for the current layer-set
   */
  this.createCloseBtn = function(_id) {
	  var closeBtn = null;
	  var closeText = null;

      // Create player tag
      if(this.browser == 'IE') {
		closeBtn = document.createElement('<a href = "javascript:ImgStreamerLightbox().closeLayers();" title = "Fenster schliessen" style = "color:#ffffff;font-weight:bold;align:center;">');
      } else {
		closeBtn = document.createElement('a');
		closeBtn.setAttribute('href', 'javascript:ImgStreamerLightbox().closeLayers();');
		closeBtn.setAttribute('title', 'Fenster schliessen');
		closeBtn.setAttribute('style', 'color:#ffffff;font-weight:bold;align:center;');
      }

	  closeText = document.createTextNode("X");
	  closeBtn.appendChild(closeText);
    
	  return closeBtn;
  }

  /**
   * Creates a player with the given parameters.
   */
  this.createPlayer = function(_id, _width, _height) {
    var player = null;

    // Create player tag
    if(this.browser == 'IE') {
      player = document.createElement('<object id="' + _id + '" classid="clsid:D27CDB6E-AE6D-11CF-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0" width="' + this.swfWidth + '" height="' + this.swfHeight + '" type="application/x-shockwave-flash">');
    } else {
      player = document.createElement('object');
      player.setAttribute('id', _id);
      player.setAttribute('width', this.swfWidth);
      player.setAttribute('height', this.swfHeight);
      player.setAttribute('type', 'application/x-shockwave-flash');
      player.setAttribute('data', this.swfURL);
    }

    player.appendChild(this.createParam('movie', this.swfURL));
    player.appendChild(this.createParam('menu', 'false'));
    player.appendChild(this.createParam('scale', 'noscale'));
    player.appendChild(this.createParam('wmode', 'transparent'));
    player.appendChild(this.createParam('bgcolor', '#ffffff'));
    player.appendChild(this.createParam('allowScriptAccess', 'always'));
    player.appendChild(this.createParam('FlashVars', '_img_path=uploads/tx_imgstreamerflash/&_num_pics=' + this.intImages + '' + this.flashVars));

    return player;
  }

  /**
   * Method to detect which browser the user is on.
   */
  this.detectBrowser = function() {
    var agent = navigator.userAgent;
    if(agent.match(/Firefox.(\d.\d)/i) != null) {
      this.browser = 'FIREFOX';
      return true;
    } else if(agent.match(/MSIE.(\d.\d)/i) != null) {
      this.browser = 'IE';
      return true;
    } else if(agent.match(/Opera.(\d.\d)/i) != null) {
      this.browser = 'OPERA';
      return true;
    } else if(agent.match(/Safari.(\d)/i) != null) {
      this.browser = 'SAFARI';
      return true;
    }
    return false;
  }

  /**
   * Convenience function to create a <param> tag for an <object> element.
   *
   * @param _name  the name of the parameter
   * @param _value the value of the parameter
   * @return the <param> element
   */
  this.createParam = function(_name, _value) {
    var param = null;

    if(this.browser == 'IE') {
      param = document.createElement('<param name="' + _name + '" value="' + _value + '">');
    } else {
      param = document.createElement('param');
      param.setAttribute('name', _name);
      param.setAttribute('value', _value);
    }

    return param;
  }

  /**
   * Determines the flash version of the user. We don't need to the exact version,
   * if it's below 8. Therefore, version 7 is returned if we have a flash version 7
   * or lower.
   *
   * @returns flash version
   */
  this.getFlashVersion = function() {
    var isIE     = (navigator.appVersion.indexOf("MSIE") != -1) ? true : false;
    var isWin    = (navigator.appVersion.toLowerCase().indexOf("win") != -1) ? true : false;
    var isOpera  = (navigator.userAgent.indexOf("Opera") != -1) ? true : false;
    var descr    = null;
    var versions = null;

    if(navigator.plugins != null && navigator.plugins.length > 0) {
      if(navigator.plugins["Shockwave Flash 2.0"] || navigator.plugins["Shockwave Flash"]) {
        descr  = navigator.plugins["Shockwave Flash" + (navigator.plugins["Shockwave Flash 2.0"] ? " 2.0" : "")].description.split(" ");
        versions = descr[2].split(".");
        return versions[0];
      }
    } else if(isIE && isWin && !isOpera) {
      try {
        versions = (new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7")).GetVariable("$version").split(",");
        return versions[0].substr(4);
      } catch(exception) {}
    }
    return 7;
  }
  
  this.setFlashvars = function(_arg) {
	  this.flashVars = _arg;
	  return this;
  }
  
  this.setNofImages = function(_num) {
	  this.intImages = _num;
	  return this;
  }

}

/**
 * Global functions.
 */

function OnResize() {
  ImgStreamerLightbox().onResize();
}

var streams = new Array();
function pushStream(_id, _flashvars, _num, _width, _height, _swf) {
	var i = streams.push([_id, _flashvars, _num, _width, _height, _swf])
	return i;
}

function imgStream() {
	this.addStream = pushStream;
}
var imgStreams = new imgStream();
				
function initImgStreamerLightbox(_id) {
	
	/* Search the corresponding stream */
	for(i=0; i < streams.length; i++) {
		if(streams[i][0] == _id) {
			select = i;
			i = streams.length;
		}
	}
	
	ImgStreamerLightbox()
		.setGalleryId(streams[select][0])
		.setFlashvars(streams[select][1])
		.setNofImages(streams[select][2])
		.setDimension(streams[select][3], streams[select][4])
		.setSWFURL(streams[select][5])
		//.setImgPath(_imgPath)
		.init();	
}
