



/* Event.onDOMReady */

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);
  	}
});



/* Ajax.LoadScript */

Ajax.LoadScript = Class.create();

Object.extend(Object.extend(Ajax.LoadScript.prototype, Ajax.Request.prototype), {
  initialize: function(url, options) {
    this.transport = Ajax.getTransport();
    this.setOptions(options);

    var onComplete = this.options.onComplete || Prototype.emptyFunction;
    this.options.onComplete = (function(transport, param) {
      this.executeScript();
      onComplete(transport, param);
    }).bind(this);

    this.request(url);
  },

  executeScript: function() {
    var response = this.transport.responseText;

	if (this.success()) {
		if (window.execScript) 
			window.execScript(response);
		else 
			window.setTimeout(response, 0);
	}
  }
});


/* Element.scrollTo */

Element.scrollTo = function(element) {
	element = $(element);

	var parent  = element.parentNode;
	var elementHeight = element.offsetHeight;
	var elementWidth = element.offsetWidth;
	var elementPosition = Position.cumulativeOffset(element);
	var scrollTop = 0;
	var scrollLeft = 0;
	
	while (parent.tagName != 'BODY') {
		if (parent.offsetWidth != parent.scrollWidth || parent.offsetHeight != parent.scrollHeight) {

			var currentPosition = Position.cumulativeOffset(parent);
			var x = elementPosition[0] - currentPosition[0];
			var y = elementPosition[1] - currentPosition[1];
			
			if (x > parseInt(parent.offsetWidth / 2) - elementWidth) {
				parent.scrollLeft = x - parseInt(parent.offsetWidth / 2) + elementWidth;
			}
			
			if (y > parseInt(parent.offsetHeight / 2) - elementHeight) {
				parent.scrollTop = y - parseInt(parent.offsetHeight / 2) + elementHeight;
			}
		}
		
		scrollTop += parent.scrollTop;
		scrollLeft =+ parent.scrollLeft;
		
		element = parent;
		parent = element.parentNode;
	}
	
	var offsetLeft = elementPosition[0] - scrollLeft;
	var offsetTop = elementPosition[1] - scrollTop;

	if (window.innerWidth) {
		var windowWidth = window.innerWidth;
		var windowHeight = window.innerHeight;
	} else if (document.documentElement && document.documentElement.clientWidth) {
		var windowWidth = document.documentElement.clientWidth;
		var windowHeight = document.documentElement.clientHeight;
	} else {
		var windowWidth = document.body.offsetWidth;
		var windowHeight = document.body.offsetHeight
	}

	if (offsetTop < windowHeight) {
		offsetTop = 0;	
	}

	if (offsetLeft < windowWidth) {
		offsetLeft = 0;	
	}
	
	window.scrollTo(offsetLeft, offsetTop);	
}




Event.onDOMReady(function() {
	$$('div.tree li').each(function(item) {
		Event.observe(item, 'mouseover', function(e) {
			Element.addClassName(Event.findElement(e, 'li'), 'hover');
	    }.bindAsEventListener(this));
		
		Event.observe(item, 'mouseout', function(e) {
			Element.removeClassName(Event.findElement(e, 'li'), 'hover');
	    }.bindAsEventListener(this));				  
    });

	$$('div.tree li ul').each(function(item) {
		Event.observe(item, 'mouseover', function(e) {
			Element.addClassName(Event.findElement(e, 'ul'), 'hover');
	    }.bindAsEventListener(this));
		
		Event.observe(item, 'mouseout', function(e) {
			Element.removeClassName(Event.findElement(e, 'ul'), 'hover');
	    }.bindAsEventListener(this));				  
    }); 
});


/**
 * PLUGIN FRAMEWORK, Version 0.5
 * For details, see the Knallgrau web site: http://www.knallgrau.code/prototype/plugins_js
 * Copyright (c) 2006 Matthias Platzer <matthias@knallgrau.at>
 * This code is freely distributable under the terms of an MIT-style license.
/*--------------------------------------------------------------------------*/

var PluginFactory = function() {

  // Returns if plugin with identifier name is installed
  // @see Plugin.getInfo
  this.isInstalled = function(name) {
    return Plugin.getInfo(name).isInstalled;
  }

  // Returns version number of plugin if available
  // @see Plugin.getInfo
  this.getVersion = function(name) {
    return Plugin.getInfo(name).version;
  }

  // Returns an Array of plugin identifier names, 
  // that can handle this mimeType.
  this.getPluginsForMimeType = function(mimeType) {
    var result = [];
    if (supportsNavigatorPlugins()) {
      // navigator.mimeTypes
      for (var i=0; i<navigator.mimeTypes.length; i++) {
        if (navigator.mimeTypes[i].type.indexOf(mimeType) == 0 && navigator.mimeTypes[i].enabledPlugin) {
          var pluginName = (findPluginName(navigator.mimeTypes[i].enabledPlugin.name) || navigator.mimeTypes[i].enabledPlugin.name);
          if (result.indexOf(pluginName) == -1) result.push(pluginName);
        }
      }
    } else {
      // Code for IE using ActiveX
      for (var pluginName in Plugin.PLUGINS) {
        var mimeTypes = Plugin.PLUGINS[pluginName].acceptedMimeTypes;
        if (!mimeTypes) continue;
        for (var j=0; j<mimeTypes.length; j++) {
          if (mimeTypes[j].type.indexOf(mimeType) == 0 && Plugin.isInstalled(pluginName)) {
            if (result.indexOf(pluginName) == -1) result.push(pluginName);
          }
        }
      }    
    }
    return result;
  }

  // Returns an Array of plugin identifier names, 
  // that can handle a file with this suffix.
  this.getPluginsForFileSuffix = function(suffix) {
    var result = [];
    if (supportsNavigatorPlugins()) {
      // navigator.mimeTypes
      for (var i=0; i<navigator.mimeTypes.length; i++) {
        if ((","+navigator.mimeTypes[i].suffixes+",").indexOf(","+suffix+",") != -1 && navigator.mimeTypes[i].enabledPlugin) {
          var pluginName = (findPluginName(navigator.mimeTypes[i].enabledPlugin.name) || navigator.mimeTypes[i].enabledPlugin.name);
          if (result.indexOf(pluginName) == -1) result.push(pluginName);
        }
      }
    } else {
      // Code for IE using ActiveX
      for (var pluginName in Plugin.PLUGINS) {
        var mimeTypes = Plugin.PLUGINS[pluginName].acceptedMimeTypes;
        if (!mimeTypes) continue;
        for (var j=0; j<mimeTypes.length; j++) {
          if ((","+mimeTypes[j].suffixes+",").indexOf(","+suffix+",") != -1 && Plugin.isInstalled(pluginName)) {
            if (result.indexOf(pluginName) == -1) result.push(pluginName);
          }
        }
      }    
    }
    return result;
  }

  // Returns general information about a plugin.
  // accepts: Acrobat, QuickTime, DivX, Director, 'Windows Media', 
  //          Flash, Java, RealPlayer, VLC
  this.getInfo = function(name) {

    var info = Plugin.PLUGINS[name];
    var isInstalled = false;
    var version = null;

    if (supportsNavigatorPlugins()) {
      // navigator.plugins
      var plugin = findNavigatorPluginByName((name == "RealPlayer") ? "RealPlayer Version Plugin" : name);
      if (plugin) {
        isInstalled = true;
        version = getVersionFromPlugin(plugin);
      }

    } else {
      // Code for IE using ActiveX
      isInstalled = hasActiveXObject(Plugin.PLUGINS[name] && Plugin.PLUGINS[name].progID);
      if (isInstalled) {
        if (Plugin.PLUGINS[name].getActiveXVersionInfo) {
          version = Plugin.PLUGINS[name].getActiveXVersionInfo();
        } else {
          // assume that the progID contains the version number
          // this is not always correct
          var progID = getProgIdForActiveXObject(Plugin.PLUGINS[name].progID);
          version = getVersionFromPlugin(progID);
        }
      } else {
        version = getActiveXPluginByClassId(Plugin.PLUGINS[name] && Plugin.PLUGINS[name].classID);
        if (version) version = version.replace(/,/g, ".");
        isInstalled = (version!=undefined);
      }

    }

    var result = {};
    for (var i in info) {
      result[i] = info[i];
    }
    result["isInstalled"] = isInstalled;
    result["version"] = version;
    result["name"] = name;

    return result;
  }

/**
 * writes an embed or object tag to document.write or target.
 * @param plugin   name of the plugin to be used
 * @param options  options for embed respectivly object tag.
 *   .src,.width,.height,.type,.activeXType will get a special treatment
 *   all other properties of options will be added to the 
 *   embed tag as attributes resp. to the object tag as param(eters).
 *   option names should be lower case!
 * @param target   optional (id of) container element for the embed/object tag
 */
  this.embed = function(plugin, options, target) {
    var embedOptions = Object.extend({
	}, options || {});
    
	var src = embedOptions.src;
    delete embedOptions.src;
    
	var id = embedOptions.id;
    delete embedOptions.id;
    
	var name = embedOptions.name || id;
    delete embedOptions.name;
    
	var width = embedOptions.width;
    delete embedOptions.width;
    
	var height = embedOptions.height;
    delete embedOptions.height;
    
	var type = embedOptions.type || (Plugin.PLUGINS[plugin] && Plugin.PLUGINS[plugin].mimeType) || "";
    delete embedOptions.type;
    
	var activeXType = embedOptions.activeXType || (Plugin.PLUGINS[plugin] && Plugin.PLUGINS[plugin].activeXType) || type;
    delete embedOptions.activeXType;
    
	var forceEmbedTag = (Plugin.PLUGINS[plugin] && Plugin.PLUGINS[plugin].forceEmbedTag === true) ? true : false;
    var forceObjectTag = (Plugin.PLUGINS[plugin] && Plugin.PLUGINS[plugin].forceObjectdTag === true) ? true : false;
    var embedOptions = Object.extend(((Plugin.PLUGINS[plugin] && Plugin.PLUGINS[plugin].standardEmbedAttributes) || {}), embedOptions);


	switch (plugin) {
      case "QuickTime":
        // get space for controls
        if (embedOptions.controller == "true" && (height+"").indexOf("%") == -1) {
          height += 16;
        }
        if (!options.activeXType) {
          activeXType = null;
        }
        break;

      case "DivX":
        // get space for controlls
        if ((height+"").indexOf("%") == -1) {
          if (embedOptions.mode == "mini") height += 20;
          else if (embedOptions.mode == "large") height += 65;
          else if (embedOptions.mode == "full") height += 90;
        }
        break;

      case "Windows Media":
        // check if ActiveX for Firefox is installed
        // http://help.yahoo.com/help/us/launch/videos/videos-07.html
        if (!supportsNavigatorPlugins() || window.GeckoActiveXObject) {
           forceObjectTag = true;
        }
        // get space for controlls
        if ((window.ActiveXObject || window.GeckoActiveXObject || window.opera) &&
            (height+"").indexOf("%") == -1) {
          height += 45;
        }
        break;

      case "Flash":
        // flash wants the src to be named "movie" if passed as object param
        if (!supportsNavigatorPlugins()) {
          embedOptions.movie = src;
          src = null;
        }
        break;

      case "VLC":
        // VLC wants the src to be named "target"
        // update: that's actualy wrong, even it's documented like that!
        if (supportsNavigatorPlugins()) {
          embedOptions.target = src;
        }
        break;

      case "RealPlayer":
        break;        

      default: 
        // do nothing
        break;
    }

    // prepare html code
    var html = "";
    if ((supportsNavigatorPlugins() && ! forceObjectTag) || forceEmbedTag) {
      // Netscape Plugin embed Tag
      html += '<embed' + getAttributeHtml("src", src)  + getAttributeHtml("id", id) + getAttributeHtml("name", name) + getAttributeHtml("width", width) + getAttributeHtml("height", height) + getAttributeHtml("pluginspage", Plugin.PLUGINS[plugin] && Plugin.PLUGINS[plugin].pluginsPage) + getAttributeHtml("type", type);
      for (var i in embedOptions) {
        html += ' '+i+'="'+embedOptions[i]+'"';
      }
      html += '></embed>\n';
	} else if (supportsNavigatorPlugins()) {
      // Standards compliant object tag
      html += '<object ';
      html += getAttributeHtml("id", id) + getAttributeHtml("name", name) + getAttributeHtml("width", width) + getAttributeHtml("height", height) + getAttributeHtml("type", type) + '>\n';
      html += (src) ? '  <param name="src" value="'+src+'">\n' : '';
      for (var i in embedOptions) {
        html += '  <param name="'+i+'" value="'+embedOptions[i]+'" />';
      }
      html += '</object>\n';
	} else {
      // ActiveX object tag
      html += '<object classid="clsid:'+(Plugin.PLUGINS[plugin] && Plugin.PLUGINS[plugin].classID)+'"';
      html += getAttributeHtml("id", id) + getAttributeHtml("name", name) + getAttributeHtml("width", width) + getAttributeHtml("height", height) + getAttributeHtml("codebase", (Plugin.PLUGINS[plugin] && Plugin.PLUGINS[plugin].codeBase)) + getAttributeHtml("type", activeXType) + '>\n';
      html += (src) ? '  <param name="src" value="'+src+'">\n' : '';
      for (var i in embedOptions) {
        html += '  <param name="'+i+'" value="'+embedOptions[i]+'" />';
      }
      html += '</object>\n';
    }

    if (target) {
      if (typeof target == "string") target = document.getElementById(target);
      target.innerHTML = html;
    } else {
      document.write(html);
    }
  }

  var getAttributeHtml = function(name, value) {
    return (value) ? (" " + name + "=\"" + value + "\"") : "";
  }

  // Info about known plugins
  this.PLUGINS = {
    "Acrobat": {
      description: "Adobe Acrobat Plugin",
      progID: ["PDF.PdfCtrl.7", "PDF.PdfCtrl.6", "PDF.PdfCtrl.5", "PDF.PdfCtrl.4", "PDF.PdfCtrl.3", "AcroPDF.PDF.1"],
      classID: "CA8A9780-280D-11CF-A24D-444553540000",
      pluginsPage: "http://www.adobe.com/products/acrobat/readstep2.html",
      acceptedMimeTypes: [
        { type: "application/pdf", suffixes: "pdf" },
        { type: "application/vnd.fdf", suffixes: "fdf" },
        { type: "application/vnd.adobe.xfdf", suffixes: "xfdf" },
        { type: "application/vnd.adobe.xdp+xml", suffixes: "xdp" },
        { type: "application/vnd.adobe.xfd+xml", suffixes: "xfd" }
      ]
    },
    "QuickTime": {
      description: "QuickTime Plug-in",
      progID: ["QuickTimeCheckObject.QuickTimeCheck.1", "QuickTime.QuickTime"],
      classID: "02BF25D5-8C17-4B23-BC80-D3488ABDDC6B",
      pluginsPage: "http://www.apple.com/quicktime/download/",
      codeBase: "http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0",
      mimeType: "video/quicktime",
      standardEmbedAttributes: {
        autoplay: "false"
      },
      // embedInfo: http://www.apple.com/quicktime/tutorials/embed.html 
      //            http://developer.apple.com/quicktime/compatibility.html
      getActiveXVersionInfo: function() { 
        var progID = getProgIdForActiveXObject(Plugin.PLUGINS["QuickTime"].progID); 
        var obj = new ActiveXObject(progID);
        var version = (obj && obj.QuickTimeVersion) ? obj.QuickTimeVersion.toString(16) : "";
        return version.substring(0,1) + '.' + version.substring(1,2) + '.' + version.substring(2,3);
      },
      acceptedMimeTypes: [
        { type: "image/tiff", suffixes: "tif,tiff" },
        { type: "image/x-tiff", suffixes: "tif,tiff" },
        { type: "video/x-m4v", suffixes: "m4v" },
        { type: "image/x-macpaint", suffixes: "pntg,pnt,mac" },
        { type: "image/pict", suffixes: "pict,pic,pct" },
        { type: "image/x-pict", suffixes: "pict,pic,pct" },
        { type: "image/x-quicktime", suffixes: "qtif,qti" },
        { type: "image/x-sgi", suffixes: "sgi,rgb" },
        { type: "image/x-targa", suffixes: "targa,tga" },
        { type: "audio/3gpp", suffixes: "3gp,3gpp" },
        { type: "video/3gpp2", suffixes: "3g2,3gp2" },
        { type: "audio/3gpp2", suffixes: "3g2,3gp2" },
        { type: "video/sd-video", suffixes: "sdv" },
        { type: "application/x-mpeg", suffixes: "amc" },
        { type: "video/mp4", suffixes: "mp4" },
        { type: "audio/mp4", suffixes: "mp4" },
        { type: "audio/x-m4a", suffixes: "m4a" },
        { type: "audio/x-m4p", suffixes: "m4p" },
        { type: "audio/x-m4b", suffixes: "m4b" },
        { type: "video/mpeg", suffixes: "mpeg,mpg,m1s,m1v,m1a,m75,m15,mp2,mpm,mpv,mpa" },
        { type: "audio/mpeg", suffixes: "mpeg,mpg,m1s,m1a,mp2,mpm,mpa,m2a" },
        { type: "audio/x-mpeg", suffixes: "mpeg,mpg,m1s,m1a,mp2,mpm,mpa,m2a" },
        { type: "video/3gpp", suffixes: "3gp,3gpp" },
        { type: "audio/x-gsm", suffixes: "gsm" },
        { type: "audio/AMR", suffixes: "AMR" },
        { type: "audio/aac", suffixes: "aac,adts" },
        { type: "audio/x-aac", suffixes: "aac,adts" },
        { type: "audio/x-caf", suffixes: "caf" },
        { type: "video/x-mpeg", suffixes: "mpeg,mpg,m1s,m1v,m1a,m75,m15,mp2,mpm,mpv,mpa" },
        { type: "audio/aiff", suffixes: "aiff,aif,aifc,cdda" },
        { type: "audio/x-aiff", suffixes: "aiff,aif,aifc,cdda" },
        { type: "audio/basic", suffixes: "au,snd,ulw" },
        { type: "audio/mid", suffixes: "mid,midi,smf,kar" },
        { type: "audio/x-midi", suffixes: "mid,midi,smf,kar" },
        { type: "audio/midi", suffixes: "mid,midi,smf,kar" },
        { type: "audio/vnd.qcelp", suffixes: "qcp" },
        { type: "application/sdp", suffixes: "sdp" },
        { type: "application/x-sdp", suffixes: "sdp" },
        { type: "application/x-rtsp", suffixes: "rtsp,rts" },
        { type: "video/quicktime", suffixes: "mov,qt,mqv" },
        { type: "video/flc", suffixes: "flc,fli,cel" },
        { type: "audio/x-wav", suffixes: "wav,bwf" },
        { type: "audio/wav", suffixes: "wav,bwf" }
      ]
    },
    "DivX": {
      description: "DivX Browser Plugin",
      progID: ["npdivx.DivXBrowserPlugin.1", "npdivx.DivXBrowserPlugin"],
      classID: "67DABFBF-D0AB-41fa-9C46-CC0F21721616",
      codeBase: "http://go.divx.com/plugin/DivXBrowserPlugin.cab",
      pluginsPage: "http://go.divx.com/plugin/download/",
      mimeType: "video/divx",
      standardEmbedAttributes: {
        mode: "mini",
        minversion: "1.0.0"
      },
      // embedInfo: Beta1: http://labs.divx.com/archives/000072.html
      //            SDK&Doc: http://download.divx.com/labs/Webmaster_SDK.zip
      getActiveXVersionInfo2: function() {
        var progID = getProgIdForActiveXObject(Plugin.PLUGINS["DivX"].progID); 
        return "1.0.0"; // that's the only currently available
      },
      acceptedMimeTypes: [
        { type: "video/divx", suffixes: "dvx,divx" }
      ]
    },
    "Director": {
      description: "Macromedia Director",
      progID: ["SWCtl.SWCtl.11","SWCtl.SWCtl.10","SWCtl.SWCtl.9","SWCtl.SWCtl.8","SWCtl.SWCtl.7","SWCtl.SWCtl.6","SWCtl.SWCtl.5","SWCtl.SWCtl.4"],
      classID: "166B1BCA-3F9C-11CF-8075-444553540000",
      pluginsPage: "http://www.macromedia.com/shockwave/download/",
      codeBase: "http://download.macromedia.com/pub/shockwave/cabs/director/sw.cab#version=8,5,1,0",
      mimeType: "application/x-director"
    },         
    "Flash": {
      description: "Macromedia Shockwave Flash",
      progID: ["ShockwaveFlash.ShockwaveFlash.9", "ShockwaveFlash.ShockwaveFlash.8.5", "ShockwaveFlash.ShockwaveFlash.8", "ShockwaveFlash.ShockwaveFlash.7", "ShockwaveFlash.ShockwaveFlash.6", "ShockwaveFlash.ShockwaveFlash.5", "ShockwaveFlash.ShockwaveFlash.4"],
      classID: "D27CDB6E-AE6D-11CF-96B8-444553540000",
      pluginsPage: "http://www.macromedia.com/go/getflashplayer",
      codeBase: "http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0",
      mimeType: "application/x-shockwave-flash",
      standardEmbedAttributes: {
        quality: "high"
      },
      // embedInfo: http://www.macromedia.com/cfusion/knowledgebase/index.cfm?id=tn_4150
      //            http://www.macromedia.com/cfusion/knowledgebase/index.cfm?id=tn_12701
      acceptedMimeTypes: [
        { type: "application/x-shockwave-flash", suffixes: "swf" },
        { type: "application/futuresplash", suffixes: "spl" }
      ]
    }, 
    "VLC": {
      description: "VLC multimedia plugin",
      progID: [],
      classID: "",
      pluginsPage: "http://www.videolan.org/doc/play-howto/en/ch02.html#id287569",
      codeBase: "http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0",
      mimeType: "application/x-vlc-plugin",
      standardEmbedAttributes: {
        quality: "high",
        autoplay: "no"
      },
      // embedInfo: http://www.videolan.org/doc/vlc-user-guide/en/ch07.html
      //            http://www.videolan.org/doc/play-howto/en/ch04.html#id293251
      acceptedMimeTypes: [
        { type: "audio/mpeg", suffixes: "mp2,mp3,mpga,mpega" },
        { type: "audio/x-mpeg", suffixes: "mp2,mp3,mpga,mpega" },
        { type: "video/mpeg", suffixes: "mpg,mpeg,mpe" },
        { type: "video/x-mpeg", suffixes: "mpg,mpeg,mpe" },
        { type: "video/mpeg-system", suffixes: "mpg,mpeg,vob" },
        { type: "video/x-mpeg-system", suffixes: "mpg,mpeg,vob" },
        { type: "video/mpeg4", suffixes: "mp4,mpg4" },
        { type: "audio/mpeg4", suffixes: "mp4,mpg4" },
        { type: "application/mpeg4-iod", suffixes: "mp4,mpg4" },
        { type: "application/mpeg4-muxcodetable", suffixes: "mp4,mpg4" },
        { type: "video/x-msvideo", suffixes: "avi" },
        { type: "video/quicktime", suffixes: "mov,qt" },
        { type: "application/x-ogg", suffixes: "ogg" },
        { type: "application/x-vlc-plugin", suffixes: "*" },
        { type: "video/x-ms-asf-plugin", suffixes: "asf,asx,*" },
        { type: "video/x-ms-asf", suffixes: "asf,asx,*" },
        { type: "application/x-mplayer2", suffixes: "dvx,divx,ivx,xvid,ivf,*" },
        { type: "video/x-ms-wmv", suffixes: "wmv,*" },
        { type: "application/x-google-vlc-plugin", suffixes: "*" }      
      ]
    },
    "Windows Media": {
      description: "Windows Media Player Plug-in Dynamic Link Library",
      progID: ["WMPlayer.OCX", "MediaPlayer.MediaPlayer.1"],
      classID: "22D6f312-B0F6-11D0-94AB-0080C74C7E95", // WMP6 -> semms to work a lot better, don't know why
      // classID: "6BF52A52-394A-11D3-B153-00C04F79FAA6", // WMP7+ -> doesn't work for me
      pluginsPage: "http://www.microsoft.com/windows/windowsmedia/",
      codeBase: "http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,0,02,902",
      mimeType: "application/x-mplayer2",
      activeXType: "application/x-oleobject",
      standardEmbedAttributes: {
        autoplay: "false"
      },
      // embedInfo: http://msdn.microsoft.com/archive/default.asp?url=/archive/en-us/samples/internet/imedia/netshow/crossbrowserembed/default.asp
      getActiveXVersionInfo: function() { 
        var progID = getProgIdForActiveXObject(Plugin.PLUGINS["Windows Media"].progID); 
        var obj = new ActiveXObject(progID);
        return (obj && obj.versionInfo) ? obj.versionInfo : "";
      },
      acceptedMimeTypes: [
        { type: "application/asx", suffixes: "*" },
        { type: "video/x-msvideo", suffixes: "avi" },
        { type: "video/x-ms-asf-plugin", suffixes: "*" },
        { type: "application/x-mplayer2", suffixes: "dvx,divx,ivx,xvid,ivf,*" },
        { type: "video/x-ms-asf", suffixes: "asf,asx,*" },
        { type: "video/x-ms-wm", suffixes: "wm,*" },
        { type: "audio/x-ms-wma", suffixes: "wma,*" },
        { type: "audio/x-ms-wax", suffixes: "wax,*" },
        { type: "video/x-ms-wmv", suffixes: "wmv,*" },
        { type: "video/x-ms-wvx", suffixes: "wvx,*" }
      ]
    },
    "Java": {
      description: "Java Virtual Machine",
      progID: [],
      classID: "08B0E5C0-4FCB-11CF-AAA5-00401C608500",
      pluginsPage: "http://www.java.com/de/download/manual.jsp",
      acceptedMimeTypes: [
        { type: "application/x-java-applet", suffixes: "" },
        { type: "application/x-java-bean", suffixes: "" },
        { type: "application/x-java-vm", suffixes: " " }
      ]
    },          
    "RealPlayer": {
      description: "RealPlayer Version Plugin",
      progID: ["RealPlayer.RealPlayer(tm) ActiveX Control (32-bit)", "RealVideo.RealVideo(tm) ActiveX Control (32-bit)", "rmocx.RealPlayer G2 Control"],
      classID: "CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA",
      mimeType: "audio/x-pn-realaudio-plugin",
      pluginsPage: "http://www.real.com/freeplayer/?rppr=rnwk",
      forceEmbedTag: true,
      standardEmbedAttributes: {
        controls: "ControlPanel",
        nojava: "true",
        autostart: "false"
      },
      // embedInfo: http://service.real.com/help/library/guides/realone/ProductionGuide/HTML/realpgd.htm?page=htmfiles/embed.htm
      // couldn't find any info about the object tag!
      getActiveXVersionInfo: function() { 
        var progID = getProgIdForActiveXObject(Plugin.PLUGINS["RealPlayer"].progID); 
        var obj = new ActiveXObject(progID);
        var version = (obj) ? obj.GetVersionInfo() : "";
        return version;
      },
      acceptedMimeTypes: [
        { type: "audio/x-pn-realaudio-plugin", suffixes: "rpm" },
        { type: "application/vnd.rn-realplayer-javascript", suffixes: "rpj" }
      ]
    }
  }

  var supportsNavigatorPlugins = function() {
    return (navigator.plugins && (navigator.plugins.length > 0));
  }

  var supportsActiveX = function() {
    return ((typeof 'ActiveXObject' != 'undefined') && (navigator.userAgent.indexOf('Win') != -1));
  }

  var findNavigatorPluginByName = function(name) {
    if (supportsNavigatorPlugins()) {
      for(var i=0;i<navigator.plugins.length;++i) {
        var plugin = navigator.plugins[i];
        if (plugin.name.indexOf(name) != -1) {
          return plugin;
        }
      }
    }
    return null;
  }

  var findPluginName = function(str) {
    for (var pluginName in Plugin.PLUGINS) {
      if (str.indexOf(pluginName) != -1) {
        return pluginName;
      }
    }
    return null;
  }

  var getIEClientCaps = function() {
    var clientcaps = document.getElementById("__Plugin_ClientCaps");
    if (!clientcaps) {
      var clientcaps = document.createElement("DIV");
      clientcaps.id = "__Plugin_ClientCaps";
      if (clientcaps.addBehavior) {
        clientcaps.addBehavior("#default#clientCaps");
        document.body.appendChild(clientcaps);
      }
      clientcaps = document.getElementById("__Plugin_ClientCaps");
    }
    return clientcaps;    
  }

  var getActiveXPluginByClassId = function(classID) {
    if (!classID) return null;
    if (!classID.match(/{[^}]+}/)) classID = "{" + classID + "}";
    var clientcaps = getIEClientCaps();
    try {
      var result = clientcaps.getComponentVersion(classID, "ComponentID")
      return result || null;
    } catch (err) { }
    return null;
  }

  var hasActiveXObject = function(progID) {
    progID = getProgIdForActiveXObject(progID);
    return (progID != null);
  }

  var getProgIdForActiveXObject = function(progID) {
    if (!progID) return null;
    for (var i=0; i<progID.length; i++) {
      try {
        var obj = new ActiveXObject(progID[i]);
        return progID[i] || null;
      }
      catch(e) { }
    }
    return null;
  }

  // accepts plugin or string
  var getVersionFromPlugin = function(plugin) {
    if (!plugin.name) plugin = { name: plugin, description: name };
    var matches = /[\d][\d\.]*/.exec(plugin.name);
    if (matches && plugin.name.indexOf("Java") == -1) return matches[0];
    matches = /[\d\.]+/.exec(plugin.description);
    return matches ? matches[0] : "";
  }
  
};

if (!window.Plugin) {
  var Plugin = new Object();
}
Object.extend(Plugin, (new PluginFactory()));


//	Lightbox v2.01
//	by Lokesh Dhakar - http://www.huddletogether.com


//
//	Configuration
//
var fileLoadingImage = "/images/lightbox/loading.gif";		
var fileBottomNavCloseImage = "/images/lightbox/closelabel.gif";

var resizeSpeed = 5;	// controls the speed of the image resizing (1=slowest and 10=fastest)

var borderSize = 10;	//if you adjust the padding in the CSS, you will need to update this variable

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

//
//	Global Variables
//
var imageArray = new Array;
var activeImage;

if(resizeSpeed > 10){ resizeSpeed = 10;}
if(resizeSpeed < 1){ resizeSpeed = 1;}
resizeDuration = (11 - resizeSpeed) * 0.15;

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

//
//	Additional methods for Element added by SU, Couloir
//	- further additions by Lokesh Dhakar (huddletogether.com)
//
Object.extend(Element, {
	getWidth: function(element) {
	   	element = $(element);
	   	return element.offsetWidth; 
	},
	setWidth: function(element,w) {
	   	element = $(element);
    	element.style.width = w +"px";
	},
	setHeight: function(element,h) {
   		element = $(element);
    	element.style.height = h +"px";
	},
	setTop: function(element,t) {
	   	element = $(element);
    	element.style.top = t +"px";
	},
	setSrc: function(element,src) {
    	element = $(element);
    	element.src = src; 
	},
	setHref: function(element,href) {
    	element = $(element);
    	element.href = href; 
	},
	setInnerHTML: function(element,content) {
		element = $(element);
		element.innerHTML = content;
	}
});

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

//
//	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();
	}
}

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

//
//	Lightbox Class Declaration
//	- initialize()
//	- start()
//	- changeImage()
//	- resizeImageContainer()
//	- showImage()
//	- updateDetails()
//	- updateNav()
//	- enableKeyboardNav()
//	- disableKeyboardNav()
//	- keyboardNavAction()
//	- preloadNeighborImages()
//	- end()
//
//	Structuring of code inspired by Scott Upton (http://www.uptonic.com/)
//
var Lightbox = Class.create();

Lightbox.prototype = {
	
	// initialize()
	// Constructor runs on completion of the DOM loading. Loops through anchor tags looking for 
	// 'lightbox' references and applies onclick events to appropriate links. The 2nd section of
	// the function inserts html at the bottom of the page which is used to display the shadow 
	// overlay and the image container.
	//
	initialize: function() {	
		if (!document.getElementsByTagName){ return; }
		var anchors = document.getElementsByTagName('a');

		// loop through all anchor tags
		for (var i=0; i<anchors.length; i++){
			var anchor = anchors[i];
			
			var relAttribute = String(anchor.getAttribute('rel'));
			
			// use the string.match() method to catch 'lightbox' references in the rel attribute
			if (anchor.getAttribute('href') && (relAttribute.toLowerCase().match('lightbox'))){
				anchor.onclick = function () {myLightbox.start(this); return false;}
			}
		}

		// The rest of this code inserts html at the bottom of the page that looks similar to this:
		//
		//	<div id="overlay"></div>
		//	<div id="lightbox">
		//		<div id="outerImageContainer">
		//			<div id="imageContainer">
		//				<img id="lightboxImage">
		//				<div style="" id="hoverNav">
		//					<a href="#" id="prevLink"></a>
		//					<a href="#" id="nextLink"></a>
		//				</div>
		//				<div id="loading">
		//					<a href="#" id="loadingLink">
		//						<img src="images/loading.gif">
		//					</a>
		//				</div>
		//			</div>
		//		</div>
		//		<div id="imageDataContainer">
		//			<div id="imageData">
		//				<div id="imageDetails">
		//					<span id="caption"></span>
		//					<span id="numberDisplay"></span>
		//				</div>
		//				<div id="bottomNav">
		//					<a href="#" id="bottomNavClose">
		//						<img src="images/close.gif">
		//					</a>
		//				</div>
		//			</div>
		//		</div>
		//	</div>


		var objBody = document.getElementsByTagName("body").item(0);
		
		var objOverlay = document.createElement("div");
		objOverlay.setAttribute('id','overlay');
		objOverlay.style.display = 'none';
		objOverlay.onclick = function() { myLightbox.end(); return false; }
		objBody.appendChild(objOverlay);
		
		var objLightbox = document.createElement("div");
		objLightbox.setAttribute('id','lightbox');
		objLightbox.style.display = 'none';
		objLightbox.onclick = function() { myLightbox.end(); return false; }
		objBody.appendChild(objLightbox);
	
		var objOuterImageContainer = document.createElement("div");
		objOuterImageContainer.setAttribute('id','outerImageContainer');
		objLightbox.appendChild(objOuterImageContainer);

		var objImageContainer = document.createElement("div");
		objImageContainer.setAttribute('id','imageContainer');
		objOuterImageContainer.appendChild(objImageContainer);
	
		var objHoverNav = document.createElement("div");
		objHoverNav.setAttribute('id','hoverNav');
		objImageContainer.appendChild(objHoverNav);
	
		var objPrevLink = document.createElement("a");
		objPrevLink.setAttribute('id','prevLink');
		objPrevLink.setAttribute('href','#');
		objHoverNav.appendChild(objPrevLink);
		
		var objNextLink = document.createElement("a");
		objNextLink.setAttribute('id','nextLink');
		objNextLink.setAttribute('href','#');
		objHoverNav.appendChild(objNextLink);
	
		var objLoading = document.createElement("div");
		objLoading.setAttribute('id','loading');
		objImageContainer.appendChild(objLoading);
	
		var objLoadingLink = document.createElement("a");
		objLoadingLink.setAttribute('id','loadingLink');
		objLoadingLink.setAttribute('href','#');
		objLoadingLink.onclick = function() { myLightbox.end(); return false; }
		objLoading.appendChild(objLoadingLink);
	
		var objLoadingImage = document.createElement("img");
		objLoadingImage.setAttribute('src', fileLoadingImage);
		objLoadingLink.appendChild(objLoadingImage);

		var objImageDataContainer = document.createElement("div");
		objImageDataContainer.setAttribute('id','imageDataContainer');
		objImageDataContainer.className = 'clearfix';
		objLightbox.appendChild(objImageDataContainer);

		var objImageData = document.createElement("div");
		objImageData.setAttribute('id','imageData');
		objImageDataContainer.appendChild(objImageData);
	
		var objImageDetails = document.createElement("div");
		objImageDetails.setAttribute('id','imageDetails');
		objImageData.appendChild(objImageDetails);
	
		var objCaption = document.createElement("span");
		objCaption.setAttribute('id','caption');
		objImageDetails.appendChild(objCaption);
	
		var objNumberDisplay = document.createElement("span");
		objNumberDisplay.setAttribute('id','numberDisplay');
		objImageDetails.appendChild(objNumberDisplay);
		
		var objBottomNav = document.createElement("div");
		objBottomNav.setAttribute('id','bottomNav');
		objImageData.appendChild(objBottomNav);
	
		var objBottomNavCloseLink = document.createElement("a");
		objBottomNavCloseLink.setAttribute('id','bottomNavClose');
		objBottomNavCloseLink.setAttribute('href','#');
		objBottomNavCloseLink.onclick = function() { myLightbox.end(); return false; }
		objBottomNav.appendChild(objBottomNavCloseLink);
	
		var objBottomNavCloseImage = document.createElement("img");
		objBottomNavCloseImage.setAttribute('src', fileBottomNavCloseImage);
		objBottomNavCloseLink.appendChild(objBottomNavCloseImage);
	},
	
	//
	//	start()
	//	Display overlay and lightbox. If image is part of a set, add siblings to imageArray.
	//
	start: function(imageLink) {	

		hideSelectBoxes();

		// stretch overlay to fill page and fade in
		var arrayPageSize = getPageSize();
		Element.setHeight('overlay', arrayPageSize[1]);
		new Effect.Appear('overlay', { duration: 0.2, from: 0.0, to: 0.7 });

		imageArray = [];
		imageNum = 0;		

		if (!document.getElementsByTagName){ return; }
		var anchors = document.getElementsByTagName('a');

		// if image is NOT part of a set..
		if((imageLink.getAttribute('rel') == 'lightbox')){
			// add single image to imageArray
			imageArray.push(new Array(imageLink.getAttribute('href'), imageLink.getAttribute('title')));			
		} else {
		// if image is part of a set..

			// loop through anchors, find other images in set, and add them to imageArray
			for (var i=0; i<anchors.length; i++){
				var anchor = anchors[i];
				if (anchor.getAttribute('href') && (anchor.getAttribute('rel') == imageLink.getAttribute('rel'))){
					imageArray.push(new Array(anchor.getAttribute('href'), anchor.getAttribute('title')));
				}
			}
			imageArray.removeDuplicates();
			while(imageArray[imageNum][0] != imageLink.getAttribute('href')) { imageNum++;}
		}

		// calculate top offset for the lightbox and display 
		var arrayPageSize = getPageSize();
		var arrayPageScroll = getPageScroll();
		var lightboxTop = arrayPageScroll[1] + (arrayPageSize[3] / 15);

		Element.setTop('lightbox', lightboxTop);
		Element.show('lightbox');
		
		this.changeImage(imageNum);
	},

	//
	//	changeImage()
	//	Hide most elements and preload image in preparation for resizing image container.
	//
	changeImage: function(imageNum) {	
		
		activeImage = imageNum;	// update global var
	
		// remove existing image
		var objLightboxImage = $('lightboxImage');
		var objImageContainer = $('imageContainer');
		if (objLightboxImage) {
			objImageContainer.removeChild(objLightboxImage);
		}
	
		// hide elements during transition
		Element.show('loading');
		Element.hide('hoverNav');
		Element.hide('prevLink');
		Element.hide('nextLink');
		Element.hide('imageDataContainer');
		Element.hide('numberDisplay');		
		
		imgPreloader = new Image();
		
		// once image is preloaded, resize image container
		imgPreloader.onload=function(){
			// recreate image element
			var objImageContainer = $('imageContainer');
			var objLightboxImage = document.createElement("img");
			objLightboxImage.setAttribute('id','lightboxImage');
			objLightboxImage.setAttribute('src',imgPreloader.src);
			objLightboxImage.setAttribute('width',imgPreloader.width);
			objLightboxImage.setAttribute('height',imgPreloader.height);
			Element.hide(objLightboxImage);
			objImageContainer.appendChild(objLightboxImage);
			myLightbox.resizeImageContainer(imgPreloader.width, imgPreloader.height);
		}
		imgPreloader.src = imageArray[activeImage][0];
	},

	//
	//	resizeImageContainer()
	//
	resizeImageContainer: function( imgWidth, imgHeight) {

		// get current height and width
		this.wCur = Element.getWidth('outerImageContainer');
		this.hCur = Element.getHeight('outerImageContainer');

		// scalars based on change from old to new
		this.xScale = ((imgWidth  + (borderSize * 2)) / this.wCur) * 100;
		this.yScale = ((imgHeight  + (borderSize * 2)) / this.hCur) * 100;

		// calculate size difference between new and old image, and resize if necessary
		wDiff = (this.wCur - borderSize * 2) - imgWidth;
		hDiff = (this.hCur - borderSize * 2) - imgHeight;

		if(!( hDiff == 0)){ new Effect.Scale('outerImageContainer', this.yScale, {scaleX: false, duration: resizeDuration, queue: 'front'}); }
		if(!( wDiff == 0)){ new Effect.Scale('outerImageContainer', this.xScale, {scaleY: false, delay: resizeDuration, duration: resizeDuration}); }

		// if new and old image are same size and no scaling transition is necessary, 
		// do a quick pause to prevent image flicker.
		if((hDiff == 0) && (wDiff == 0)){
			if (navigator.appVersion.indexOf("MSIE")!=-1){ pause(250); } else { pause(100);} 
		}

		Element.setHeight('prevLink', imgHeight);
		Element.setHeight('nextLink', imgHeight);
		Element.setWidth( 'imageDataContainer', imgWidth + (borderSize * 2));

		// calculate top offset for the lightbox and display 
		var arrayPageSize = getPageSize();
		var arrayPageScroll = getPageScroll();
		
		var lightboxTop = arrayPageScroll[1] + (arrayPageSize[3] / 15);
		var lightboxBottom = lightboxTop + imgHeight  + (borderSize * 2) + 50;
		if (lightboxBottom > arrayPageSize[1]) {
			Element.setHeight('overlay', lightboxBottom);
		}
		this.showImage();
	},
	
	//
	//	showImage()
	//	Display image and begin preloading neighbors.
	//
	showImage: function(){
		Element.hide('loading');
		new Effect.Appear('lightboxImage', { duration: 0.5, queue: 'end', afterFinish: function(){	myLightbox.updateDetails(); } });
		this.preloadNeighborImages();
	},

	//
	//	updateDetails()
	//	Display caption, image number, and bottom nav.
	//
	updateDetails: function() {
	
		Element.show('caption');
		Element.setInnerHTML( 'caption', imageArray[activeImage][1]);
		
		// if image is part of set display 'Image x of x' 
		if(imageArray.length > 1){
			Element.show('numberDisplay');
			Element.setInnerHTML( 'numberDisplay', "Image " + eval(activeImage + 1) + " of " + imageArray.length);
		}

		new Effect.Parallel(
			[ new Effect.SlideDown( 'imageDataContainer', { sync: true, duration: resizeDuration + 0.25, from: 0.0, to: 1.0 }), 
			  new Effect.Appear('imageDataContainer', { sync: true, duration: 1.0 }) ], 
			{ duration: 0.65, afterFinish: function() { myLightbox.updateNav();} } 
		);
	},

	//
	//	updateNav()
	//	Display appropriate previous and next hover navigation.
	//
	updateNav: function() {

		Element.show('hoverNav');				

		// if not first image in set, display prev image button
		if(activeImage != 0){
			Element.show('prevLink');
			document.getElementById('prevLink').onclick = function() {
				myLightbox.changeImage(activeImage - 1); return false;
			}
		}

		// if not last image in set, display next image button
		if(activeImage != (imageArray.length - 1)){
			Element.show('nextLink');
			document.getElementById('nextLink').onclick = function() {
				myLightbox.changeImage(activeImage + 1); return false;
			}
		}
		
		this.enableKeyboardNav();
	},

	//
	//	enableKeyboardNav()
	//
	enableKeyboardNav: function() {
		document.onkeydown = this.keyboardAction; 
	},

	//
	//	disableKeyboardNav()
	//
	disableKeyboardNav: function() {
		document.onkeydown = '';
	},

	//
	//	keyboardAction()
	//
	keyboardAction: function(e) {
		if (e == null) { // ie
			keycode = event.keyCode;
		} else { // mozilla
			keycode = e.which;
		}

		key = String.fromCharCode(keycode).toLowerCase();
		
		if((key == 'x') || (key == 'o') || (key == 'c')){	// close lightbox
			myLightbox.end();
		} else if(key == 'p'){	// display previous image
			if(activeImage != 0){
				myLightbox.disableKeyboardNav();
				myLightbox.changeImage(activeImage - 1);
			}
		} else if(key == 'n'){	// display next image
			if(activeImage != (imageArray.length - 1)){
				myLightbox.disableKeyboardNav();
				myLightbox.changeImage(activeImage + 1);
			}
		}


	},

	//
	//	preloadNeighborImages()
	//	Preload previous and next images.
	//
	preloadNeighborImages: function(){

		if((imageArray.length - 1) > activeImage){
			preloadNextImage = new Image();
			preloadNextImage.src = imageArray[activeImage + 1][0];
		}
		if(activeImage > 0){
			preloadPrevImage = new Image();
			preloadPrevImage.src = imageArray[activeImage - 1][0];
		}
	
	},

	//
	//	end()
	//
	end: function() {
		this.disableKeyboardNav();
		Element.hide('lightbox');
		new Effect.Fade('overlay', { duration: 0.2});
		showSelectBoxes();
	}
}

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

//
// getPageScroll()
// Returns array with x,y page scroll values.
// Core code from - quirksmode.org
//
function getPageScroll(){

	var yScroll;

	if (self.pageYOffset) {
		yScroll = self.pageYOffset;
	} else if (document.documentElement && document.documentElement.scrollTop){	 // Explorer 6 Strict
		yScroll = document.documentElement.scrollTop;
	} else if (document.body) {// all other Explorers
		yScroll = document.body.scrollTop;
	}

	arrayPageScroll = new Array('',yScroll) 
	return arrayPageScroll;
}

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

//
// getPageSize()
// Returns array with page width, height and window width, height
// Core code from - quirksmode.org
// Edit for Firefox by pHaez
//
function getPageSize(){
	
	var xScroll, yScroll;
	
	if (window.innerHeight && window.scrollMaxY) {	
		xScroll = document.body.scrollWidth;
		yScroll = window.innerHeight + window.scrollMaxY;
	} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
		xScroll = document.body.scrollWidth;
		yScroll = document.body.scrollHeight;
	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
		xScroll = document.body.offsetWidth;
		yScroll = document.body.offsetHeight;
	}
	
	var windowWidth, windowHeight;
	if (self.innerHeight) {	// all except Explorer
		windowWidth = self.innerWidth;
		windowHeight = self.innerHeight;
	} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
		windowWidth = document.documentElement.clientWidth;
		windowHeight = document.documentElement.clientHeight;
	} else if (document.body) { // other Explorers
		windowWidth = document.body.clientWidth;
		windowHeight = document.body.clientHeight;
	}	
	
	// for small pages with total height less then height of the viewport
	if(yScroll < windowHeight){
		pageHeight = windowHeight;
	} else { 
		pageHeight = yScroll;
	}

	// for small pages with total width less then width of the viewport
	if(xScroll < windowWidth){	
		pageWidth = windowWidth;
	} else {
		pageWidth = xScroll;
	}


	arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight) 
	return arrayPageSize;
}

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

//
// getKey(key)
// Gets keycode. If 'x' is pressed then it hides the lightbox.
//
function getKey(e){
	if (e == null) { // ie
		keycode = event.keyCode;
	} else { // mozilla
		keycode = e.which;
	}
	key = String.fromCharCode(keycode).toLowerCase();
	
	if(key == 'x'){
	}
}

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

//
// listenKey()
//
function listenKey () {	document.onkeypress = getKey; }
	
// ---------------------------------------------------

function showSelectBoxes(){
	selects = document.getElementsByTagName("select");
	for (i = 0; i != selects.length; i++) {
		selects[i].style.visibility = "visible";
	}
}

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

function hideSelectBoxes(){
	selects = document.getElementsByTagName("select");
	for (i = 0; i != selects.length; i++) {
		selects[i].style.visibility = "hidden";
	}
}

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

//
// pause(numberMillis)
// Pauses code execution for specified time. Uses busy code, not good.
// Code from http://www.faqts.com/knowledge_base/view.phtml/aid/1602
//
function pause(numberMillis) {
	var now = new Date();
	var exitTime = now.getTime() + numberMillis;
	while (true) {
		now = new Date();
		if (now.getTime() > exitTime)
			return;
	}
}

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



function initLightbox() { myLightbox = new Lightbox(); }
Event.onDOMReady(initLightbox);



var Boxable = Class.create();
Boxable.prototype = {
	
	initialize: function(element) {
    	var options = Object.extend({
      		handle: false,
      		left: 0,
      		right: 0,
      		top: 0,
      		bottom: 0,
      		endeffect: false
    	}, arguments[1] || {});
    
		this.element      = $(element);
		this.element.drag = this;
		this.handle       = options.handle ? $(options.handle) : this.element;
		
		this.offsetTop = 0;
		this.offsetLeft = 0;
	
		oo = this.element;
		while (oo.tagName != 'BODY') {
			if (oo.offsetTop) this.offsetTop += oo.offsetTop;
			if (oo.offsetLeft) this.offsetLeft += oo.offsetLeft;
			oo = oo.offsetParent;
		}
	
		this.startX       = 0;
		this.startY       = 0;
    
		this.left         = options.left;
		this.right        = options.right;
		this.top          = options.top;
		this.bottom       = options.bottom;
		
		this.options      = options;
		this.active       = false;
		this.dragging     = false;
		this.rect         = false;
		this.outerRect    = false;
		this.innerRect    = false;
		
		Event.observe(this.handle, "mousedown", this.startDrag.bindAsEventListener(this));
		Event.observe(document, "mouseup", this.endDrag.bindAsEventListener(this));
		Event.observe(document, "mousemove", this.update.bindAsEventListener(this));
		
		// Create inner structure...
		this.innerRect = document.createElement('div');
		this.outerRect = document.createElement('div');
		this.outerRect.style.position = 'relative';
		this.outerRect.style.display = 'none';
		this.outerRect.appendChild(this.innerRect);
		this.element.appendChild(this.outerRect);
	
		// Draw current structure...
		this.draw();
		if(this.options.change) this.options.change(this);
  	},

	startDrag: function(event) {
    	if(Event.isLeftClick(event)) {
      		this.active = true;

			this.startX = parseInt(Event.pointerX(event) - this.offsetLeft);
			this.startY = parseInt(Event.pointerY(event) - this.offsetTop);
			this.left = this.right = this.startX;
			this.top = this.bottom = this.startY;
			Event.stop(event);
		}
  	},
  
  	endDrag: function(event) {
    	if (this.active && this.dragging) {
      		this.active = false;
      		this.dragging = false;
    
			if (this.left + 10 > this.right || 
				this.top + 10 > this.bottom) {
				
				this.top = this.bottom = this.left = this.right = 0;
				this.draw();
				if(this.options.change) this.options.change(this);
			}

			Event.stop(event);
    	}
  	},
  
  	draw: function() {
    	var outerStyle = this.outerRect.style;
    	var innerStyle = this.innerRect.style;

    	if (this.left != 0 || this.right != 0 || this.top != 0 || this.bottom != 0)
    	{
    		var width = this.right - this.left;
      		var height = this.bottom - this.top;
      
      		outerStyle.left = this.left + 'px';
      		outerStyle.width = (width - 2 > 0 ? width - 2 : 0) + 'px';   
      		outerStyle.top = this.top + 'px';
      		outerStyle.height = (height - 2 > 0 ? height - 2 : 0) + 'px';   

      		innerStyle.width = (width - 4 > 0 ? width - 4 : 0) + 'px';
      		innerStyle.height = (height - 4 > 0 ? height - 4 : 0) + 'px';

      		outerStyle.display = 'block';
    	} 
		else 
		{
			if(this.options.endeffect) 
        		this.options.endeffect(this.outerRect);
      		else
        		outerStyle.display = 'none';   
    	}
  	},
  
  	update: function(event) {
   		if(this.active) {
      		if(!this.dragging) {
        		this.dragging = true;
      		}
      
			var newX = parseInt(Event.pointerX(event) - this.offsetLeft);
			var newY = parseInt(Event.pointerY(event) - this.offsetTop);
      
			if (newX > this.startX) {
				this.left = this.startX; 
				this.right = newX;
			} else {
				this.left = newX;
				this.right = this.startX;
			}
      
			if (newY > this.startY) {
				this.top = this.startY; 
				this.bottom = newY;
			} else {
				this.top = newY;
				this.bottom = this.startY;
			}
      
			if (this.left < 0) this.left = 0;
			if (this.top < 0) this.top = 0;
			if (this.right > this.element.offsetWidth) this.right = parseInt(this.element.offsetWidth);
			if (this.bottom > this.element.offsetHeight) this.bottom = parseInt(this.element.offsetHeight);
			
			this.draw();
			
			if(this.options.change) this.options.change(this);
			
			Event.stop(event);
		}
  	}
}

Contents = Class.create();
Contents.prototype = {
  initialize: function(element) {
    var options = Object.extend({
      handle: false
    }, arguments[1] || {});

    this.element      = $(element);
    this.handle       = options.handle ? $(options.handle) : this.element;
    this.contents     = options.text ? options.text : this.element.alt;
    this.parser       = document.createElement('div');
	this.parser.innerHTML = this.contents;

	Event.observe(this.element, "mousemove", this.set.bindAsEventListener(this));
    Event.observe(this.element, "click", this.cancel.bindAsEventListener(this));
  },
  set: function(event) {
	if (this.handle.innerHTML != this.parser.innerHTML)
	    this.handle.innerHTML = this.parser.innerHTML;
    Event.stop(event);
  },
  clear: function(event) {
    this.handle.innerHTML = '';
  },
  cancel: function(event) {
	Event.stop(event);
  }
}

Effect.ShakeAway = function(element) {
  new Effect.Parallel(
    [ new Effect.Shake(element, {}), new Effect.Fade(element, {}) ]
  );
}


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

	initialize: function(options) {
		this.options = Object.extend({
			url:				null,
			title:				'',
			id:					'tree',
			top:				0,
			left:				0
		}, options || {});
		
		this.container = Builder.node('div');
		
		this.dialog = Builder.node('div', {id: this.options.id}, [
			this.container
		]);
		
		if (this.options.top > 0 || this.options.left > 0) {
			Element.setStyle(this.dialog, {
				top:  this.options.top + 'px',
				left: this.options.left + 'px'
			});
		}
	
		document.body.appendChild(this.dialog);
		
		if (this.options.url) {
			new Ajax.Updater(this.container, this.options.url, {method: 'get', onComplete: this.complete.bind(this)});
		}
	},
	
	complete: function() {
		if (/\/edit\//.test(window.location.href)) {
			var tab = window.location.href;

			if (tab = tab.match(/\/edit\/.*\/(.*)/)) {
				tab = tab[1];	
			}
			
			$$('#tree a').each(function(element) {
				element.href = element.href.replace(/\/view\//, '/edit/');
				
				if (tab) {
					element.href += '/' + tab;	
				}
			});
		}
		
		var selected = $$('#' + this.options.id + ' .selected');
		if (selected) {
			selected = selected[0];
			Element.scrollTo(selected);
			selected.focus();
		}
	},
	
	destroy: function() {
		if (this.dialog) {
			Element.remove(this.dialog);	
			this.dialog = null;
		}
	}
};

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

	initialize: function(options) {
		this.options = Object.extend({
			url:				null,
			title:				'',
			id:					'tree',
			top:				0,
			left:				0
		}, options || {});
		
		this.container = Builder.node('div');
		
		this.dialog = Builder.node('div', {id: this.options.id}, [
			this.container
		]);
		
		if (this.options.top > 0 || this.options.left > 0) {
			Element.setStyle(this.dialog, {
				top:  this.options.top + 'px',
				left: this.options.left + 'px'
			});
		}
	
		document.body.appendChild(this.dialog);
		
		if (this.options.url) {
			new Ajax.Updater(this.container, this.options.url, {method: 'get', onComplete: this.complete.bind(this)});
		}
	},
	
	complete: function() {
		var selected = $$('#' + this.options.id + ' .selected');
		if (selected) {
			selected = selected[0];
			Element.scrollTo(selected);
			selected.focus();
		}
	},
	
	destroy: function() {
		if (this.dialog) {
			Element.remove(this.dialog);	
			this.dialog = null;
		}
	}
};

var DashboardSelector = Class.create();
DashboardSelector.prototype = {
	
	initialize: function(element, parentField, languageField, button) {
		this.element = $(element);
		this.parentField = $(parentField);
		this.languageField = $(languageField);
		this.button = $(button);
		this.selected = null;
	
		if (this.element) {
			Event.observe(this.element, 'click', this.click.bindAsEventListener(this));
			new Tree(this.element);
		}

		this.button.disabled = true;
	},
	
	click: function(e) {
		Event.stop(e);

		var element = Event.findElement(e, 'a');
		if (element.tagName) {
			this.unselect();
			this.select(Event.element(e));
		}
	},

	select: function(element) {
		var matches = /moveto_([^_]+)(_(.+))?/.exec(element.id);
		if (matches) {
			if (matches[1]) {
				this.parentField.value = matches[1];

				if (matches[3]) 
					this.languageField.value = matches[3];
				else
					this.languageField.value = '';
	
				Element.addClassName(element, 'selected');
				this.selected = element;
				this.button.disabled = false;
			}
		}
	},

	unselect: function() {
		this.button.disabled = true;
		this.parentField.value = '';
		Element.removeClassName(this.selected, 'selected');
	}
};

var DashboardForm = Class.create();
DashboardForm.prototype = {
	
	initialize: function(options) {
		this.options = Object.extend({
			url:				null,
			title:				'',
			id:					'dialog',
			top:				0,
			left:				0,
			wide:				false,
			onComplete:			null
		}, options || {});
		
		this.container = Builder.node('div');
		
		this.dialog = Builder.node('div', {id: this.options.id}, [
			Builder.node('h2', this.options.title),
			this.container
		]);
		
		if (this.options.wide) {
			Element.addClassName(this.dialog, 'wide');
		}
		
		if (this.options.top > 0 || this.options.left > 0) {
			Element.setStyle(this.dialog, {
				top:  this.options.top + 'px',
				left: this.options.left + 'px'
			});
		}
	
		document.body.appendChild(this.dialog);
		
		if (this.options.url) {
			new Ajax.Updater(this.container, this.options.url, {method: 'get', onComplete: this.complete.bind(this)});
		}
	},
	
	complete: function() {
		var form = this.container.getElementsByTagName('form');
		if (form) {
			Form.focusFirstElement(form[0]);
		}
		
		if (this.options.onComplete) {
			this.options.onComplete();
		}
	},
	
	destroy: function() {
		if (this.dialog) {
			Element.remove(this.dialog);	
			this.dialog = null;
		}
	}
};


var DashboardConfirm = Class.create();
DashboardConfirm.prototype = {
	
	initialize: function(options) {
		this.options = Object.extend({
			title:				'',
			okLabel:			'OK',
			cancelLabel:   		'Cancel',
			message:			'Are you sure?',
			id:					'dialog',
			messageClass:		'message',
			buttonsClass:		'buttons',
			onOk:				function () {},
			onCancel:			function () {},
			top:				0,
			left:				0
		}, options || {});		
		
		
		this.okButton = Builder.node('button', this.options.okLabel);
		this.cancelButton = Builder.node('button', this.options.cancelLabel);

		this.onClickOk = this.ok.bindAsEventListener(this);
		this.onClickCancel = this.cancel.bindAsEventListener(this);
		Event.observe(this.okButton, 'click', this.onClickOk);
		Event.observe(this.cancelButton, 'click', this.onClickCancel);
		
		this.dialog = Builder.node('div', {id: this.options.id}, [
			Builder.node('h2', this.options.title), 
			Builder.node('div', [
				Builder.node('p', {className: this.options.messageClass }, this.options.message),
				Builder.node('p', {className: this.options.buttonsClass }, [
					this.okButton,
					this.cancelButton
				])
			])
		]);
		
		if (this.options.top > 0 || this.options.left > 0) {
			Element.setStyle(this.dialog, {
				top:  this.options.top + 'px',
				left: this.options.left + 'px'
			});
		}
	
		document.body.appendChild(this.dialog);
		
		this.okButton.focus();
	},
	
	destroy: function() {
		if (this.dialog) {
			Element.remove(this.dialog);	
			this.dialog = null;
		}

		Event.stopObserving(this.okButton, 'click', this.onClickOk);
		Event.stopObserving(this.cancelButton, 'click', this.onClickCancel);
	},
	
	ok: function() {
		this.destroy();	

		if (this.options.onOk) {
			this.options.onOk();	
		}
	},
	
	cancel: function() {
		this.destroy();

		if (this.options.onCancel) {
			this.options.onCancel();	
		}
	}
};

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

	initialize: function() {
		this.deleteButton = $('dashboardDelete');
		this.createButton = $('dashboardCreate');
		this.moveButton = $('dashboardMove');
		this.pageButton = $('dashboardPage');
		this.languageButton = $('dashboardLanguage');
		
		if (this.moveButton) {
			this.onClickMove  = this.movePage.bindAsEventListener(this);
			Event.observe(this.moveButton, 'click', this.onClickMove);
		}
		
		if (this.createButton) {
			this.onClickCreate  = this.createPage.bindAsEventListener(this);
			Event.observe(this.createButton, 'click', this.onClickCreate);
		}
		
		if (this.deleteButton) {
			this.onClickDelete  = this.deletePage.bindAsEventListener(this);
			Event.observe(this.deleteButton, 'click', this.onClickDelete);
		}
		
		if (this.pageButton) {
			this.onClickPage	= this.showTree.bindAsEventListener(this);
			Event.observe(this.pageButton, 'click', this.onClickPage);
		}

		if (this.languageButton) {
			this.onClickLanguage = this.showLanguage.bindAsEventListener(this);
			Event.observe(this.languageButton, 'click', this.onClickLanguage);
		}

		this.onClickOverlay = this.clickOverlay.bindAsEventListener(this);

		this.dialog = null;
		this.initializeOverlay();
	},
	
	showTree: function(e) {
		this.showOverlay(0);

		var position = Position.cumulativeOffset(this.pageButton);
		
		this.dialog = new DashboardTree ({
			url:			this.pageButton.href,
			title:			'Ga naar:',
			left: 			position[0],
			top: 			position[1] + 20
		});

		Event.stop(e);	
	},
	
	showLanguage: function(e) {
		this.showOverlay(0);

		var position = Position.cumulativeOffset(this.languageButton);
		
		this.dialog = new DashboardLanguage ({
			url:			this.languageButton.href,
			title:			'Taal:',
			left: 			position[0],
			top: 			position[1] + 20
		});

		Event.stop(e);	
	},
	
	movePage: function(e) {
		this.showOverlay(0.6);

		var position = Position.cumulativeOffset(this.moveButton);

		this.dialog = new DashboardForm ({
			url:			this.moveButton.href + '/ajax',
			title:			this.moveButton.text ? this.moveButton.text : this.moveButton.innerText,
			left: 			position[0] - 8,
			top: 			position[1],
			wide:			true,
			onComplete:		function() {
				new DashboardSelector('parentSelector', 'parent', 'language', 'moveButton');
			}
		});
		
		Event.stop(e);	
	},
	
	createPage: function(e) {
		this.showOverlay(0.6);

		var position = Position.cumulativeOffset(this.createButton);

		this.dialog = new DashboardForm ({
			url:			this.createButton.href + '/ajax',
			title:			this.createButton.text ? this.createButton.text : this.createButton.innerText,
			left: 			position[0] - 8,
			top: 			position[1]
		});
		
		Event.stop(e);	
	},
	
	deletePage: function(e) {
		this.showOverlay(0.6);
		
		var position = Position.cumulativeOffset(this.deleteButton);
		
		this.dialog = new DashboardConfirm ({
			title:			this.deleteButton.text ? this.deleteButton.text : this.deleteButton.innerText,
			okLabel: 		'Ja',
			cancelLabel: 	'Nee',
			message: 		'Weet u zeker dat u deze pagina wilt verwijderen?',
			left: 			position[0] - 8,
			top: 			position[1],
			onOk: 			this.deletePageOk.bind(this),
			onCancel: 		this.deletePageCancel.bind(this)
		});

		Event.stop(e);	
	},
	
	deletePageOk: function() {
		window.location = this.deleteButton.href;
	},
	
	deletePageCancel: function() {
		this.hideOverlay();
	},
	
	initializeOverlay: function() {
		this.iframe  = document.createElement("iframe");
		this.iframe.setAttribute('id', 'dashboardIframe');
		this.iframe.setAttribute('frameborder', 0);
		Element.hide(this.iframe);

		document.body.appendChild(this.iframe);		

		this.overlay = document.createElement("div");
		this.overlay.setAttribute('id', 'dashboardOverlay');

		Element.hide(this.overlay);
		Event.observe(this.overlay, 'click', this.onClickOverlay);

		document.body.appendChild(this.overlay);		
	},
	
	showOverlay: function(opacity) {
	  	if (window.innerHeight && window.scrollMaxY) {	
			var pageHeight = window.innerHeight + window.scrollMaxY;
		} else if (document.documentElement && document.documentElement.clientHeight) {
			var pageHeight = Math.max(document.body.scrollHeight, document.documentElement.clientHeight);
		} else {
			var pageHeight = Math.max(document.body.scrollHeight, document.body.offsetHeight);
		}

		Element.setStyle(this.iframe, {
			height: pageHeight + 'px'
		});
		
		Element.show(this.iframe);


		Element.setStyle(this.overlay, {
			height: pageHeight + 'px'
		});
		
		Element.setOpacity(this.overlay, opacity);
		Element.show(this.overlay);
	},
	
	hideOverlay: function() {
		Element.hide(this.overlay);
		Element.hide(this.iframe);
	},
	
	clickOverlay: function() {	
		this.hideOverlay();
		
		if (this.dialog) {
			this.dialog.destroy();	
		}
	}
};


Event.onDOMReady(function (event) {
	if ($('dashboard')) {
		new Dashboard('dashboard');	
	}
});




var Tree = Class.create();
Tree.prototype = {
	
	initialize: function(element, options) {
		this.options = Object.extend({
			root: true
		}, options || {});
		
		this.element = $(element);

		if (this.options.root) {
			Element.addClassName(this.element, 'tree');
		}

		var listitem = null;

		for (var i = 0; i < this.element.childNodes.length; i++) 
		{
			if (this.element.childNodes[i].tagName && 
				this.element.childNodes[i].tagName.toLowerCase() == 'li') 
			{
				listitem = this.element.childNodes[i];
			
				var spanC = Builder.node('span', { className: 'c' });
				var spanB = Builder.node('span', { className: 'b' }, [ spanC ]);
				var spanA = Builder.node('span', { className: 'a' }, [ spanB ]);
				
				if (Element.hasClassName(this.element, 'closed')) {
					Element.setClassName(spanA, 'closed');
				}
			
				Event.observe(spanA, 'click', this.toggle.bindAsEventListener(this));

				// Find the UL within the LI, if it exists
				var stoppingPoint = listitem.childNodes.length;
				var startingPoint = 0;
				var childUL = null;

				for (var j = 0; j < listitem.childNodes.length; j++) {
					if (listitem.childNodes[j].tagName && listitem.childNodes[j].tagName.toLowerCase() == 'ul') {
						childUL = listitem.childNodes[j];
						stoppingPoint = j;
						break;					
					}
				}
				
				for (var j = startingPoint; j < stoppingPoint; j++) {
					spanC.appendChild(listitem.childNodes[startingPoint]);
				}
				
				// Insert the outermost extra span into the tree
				if (listitem.childNodes.length > startingPoint) {
					listitem.insertBefore(spanA, listitem.childNodes[startingPoint]);
				} else {
					listitem.appendChild(spanA);
				}
				
				// Process the children
				if(childUL != null) {
					new Tree(childUL, { root: false	});
					Element.addClassName(listitem, 'children');
					Element.addClassName(spanA, 'children');
				}
			}
		}

		if (listitem != null) {
			Element.addClassName(listitem, 'last');
			Element.addClassName(spanA, 'last');
		} 
	},
	
	
	toggle: function(e) {
		if (Event.findElement(e, 'span') != Event.element(e)) {
			return;	
		}

		Event.stop(e);

		var listitem = Event.findElement(e, 'li');

		// console.debug([Event.findElement(e, 'span'), Event.element(e)]);


		if (Element.hasClassName(listitem, 'children')) {
			if (Element.hasClassName(listitem, 'closed')) {
				Element.removeClassName(listitem, 'closed');
				Element.removeClassName(listitem.getElementsByTagName('li')[0], 'closed');
			} else {
				Element.addClassName(listitem, 'closed');
				Element.addClassName(listitem.getElementsByTagName('li')[0], 'closed');
			}
		}
	}
	
};