// lightwindow.js v2.0
//
// Copyright (c) 2007 stickmanlabs
// Author: Kevin P Miller | http://www.stickmanlabs.com
// 
// LightWindow is freely distributable under the terms of an MIT-style license.
//
// I don't care what you think about the file size...
//   Be a pro: 
//	    http://www.thinkvitamin.com/features/webapps/serving-javascript-fast
//      http://rakaz.nl/item/make_your_pages_load_faster_by_combining_and_compressing_javascript_and_css_files
//

/*-----------------------------------------------------------------------------------------------*/

if (typeof Effect == 'undefined')
  throw ("lightwindow.js requires including script.aculo.us' effects.js library!");

// This will stop image flickering in IE6 when elements with images are moved
try {
  document.execCommand("BackgroundImageCache", false, true);
} catch (e) { }

var lightwindow = Class.create();
lightwindow.prototype = {
  //
  //	Setup Variables
  //
  element: null,
  contentToFetch: null,
  windowActive: false,
  dataEffects: [],
  dimensions: {
    cruft: null,
    container: null,
    viewport: {
      height: null,
      width: null,
      offsetTop: null,
      offsetLeft: null
    }
  },
  pagePosition: {
    x: 0,
    y: 0
  },
  pageDimensions: {
    width: null,
    height: null
  },
  preloadImage: [],
  preloadedImage: [],
  galleries: [],
  resizeTo: {
    height: null,
    heightPercent: null,
    width: null,
    widthPercent: null,
    fixedTop: null,
    fixedLeft: null
  },
  scrollbarOffset: 18,
  navigationObservers: {
    previous: null,
    next: null
  },
  containerChange: {
    height: 0,
    width: 0
  },
  activeGallery: false,
  galleryLocation: {
    current: 0,
    total: 0
  },
  //
  //	Initialize the lightwindow.
  //
  initialize: function(options) {
    this.options = Object.extend({
      resizeSpeed: 8,
      contentOffset: {
        height: 20,
        width: 20
      },
      dimensions: {
        image: { height: 250, width: 250 },
        page: { height: 250, width: 250 },
        inline: { height: 250, width: 250 },
        media: { height: 250, width: 250 },
        external: { height: 250, width: 250 },
        titleHeight: 25
      },
      classNames: {
        standard: 'lightwindow',
        action: 'lightwindow_action'
      },
      fileTypes: {
        page: ['asp', 'aspx', 'cgi', 'cfm', 'htm', 'html', 'pl', 'php4', 'php3', 'php', 'php5', 'phtml', 'rhtml', 'shtml', 'txt', 'vbs', 'rb'],
        media: ['aif', 'aiff', 'asf', 'avi', 'divx', 'm1v', 'm2a', 'm2v', 'm3u', 'mid', 'midi', 'mov', 'moov', 'movie', 'mp2', 'mp3', 'mpa', 'mpa', 'mpe', 'mpeg', 'mpg', 'mpg', 'mpga', 'pps', 'qt', 'rm', 'ram', 'swf', 'viv', 'vivo', 'wav'],
        image: ['bmp', 'gif', 'jpg', 'png', 'tiff']
      },
      mimeTypes: {
        avi: 'video/avi',
        aif: 'audio/aiff',
        aiff: 'audio/aiff',
        gif: 'image/gif',
        bmp: 'image/bmp',
        jpeg: 'image/jpeg',
        m1v: 'video/mpeg',
        m2a: 'audio/mpeg',
        m2v: 'video/mpeg',
        m3u: 'audio/x-mpequrl',
        mid: 'audio/x-midi',
        midi: 'audio/x-midi',
        mjpg: 'video/x-motion-jpeg',
        moov: 'video/quicktime',
        mov: 'video/quicktime',
        movie: 'video/x-sgi-movie',
        mp2: 'audio/mpeg',
        mp3: 'audio/mpeg3',
        mpa: 'audio/mpeg',
        mpa: 'video/mpeg',
        mpe: 'video/mpeg',
        mpeg: 'video/mpeg',
        mpg: 'audio/mpeg',
        mpg: 'video/mpeg',
        mpga: 'audio/mpeg',
        pdf: 'application/pdf',
        png: 'image/png',
        pps: 'application/mspowerpoint',
        qt: 'video/quicktime',
        ram: 'audio/x-pn-realaudio-plugin',
        rm: 'application/vnd.rn-realmedia',
        swf: 'application/x-shockwave-flash',
        tiff: 'image/tiff',
        viv: 'video/vivo',
        vivo: 'video/vivo',
        wav: 'audio/wav',
        wmv: 'application/x-mplayer2'
      },
      classids: {
        mov: 'clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B',
        swf: 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000',
        wmv: 'clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6'
      },
      codebases: {
        mov: 'http://www.apple.com/qtactivex/qtplugin.cab#version=6,0,2,0',
        swf: 'http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,0,0',
        wmv: 'http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,5,715'
      },
      viewportPadding: 10,
      EOLASFix: 'swf,wmv,fla,flv',
      overlay: {
        opacity: 0.7,
        image: '/images/black.png',
        presetImage: '/images/black-70.png'
      },
      skin: {
        main: '<div id="lightwindow_container" >' +
							'<div id="lightwindow_title_bar" >' +
								'<div id="lightwindow_title_bar_inner" >' +
									'<span id="lightwindow_title_bar_title"></span>' +
									'<a id="lightwindow_title_bar_close_link" ><img src="' + '/images/close.png" border="0"></a>' +
								'</div>' +
							'</div>' +
							'<div id="lightwindow_stage" >' +
								'<div id="lightwindow_contents" >' +
								'</div>' +
								'<div id="lightwindow_navigation" >' +
									'<a href="#" id="lightwindow_previous" >' +
										'<span id="lightwindow_previous_title"></span>' +
									'</a>' +
									'<a href="#" id="lightwindow_next" >' +
										'<span id="lightwindow_next_title"></span>' +
									'</a>' +
									'<iframe name="lightwindow_navigation_shim" id="lightwindow_navigation_shim" src="javascript:false;" frameBorder="0" scrolling="no"></iframe>' +
								'</div>' +
								'<div id="lightwindow_galleries">' +
									'<div id="lightwindow_galleries_tab_container" >' +
										'<a href="#" id="lightwindow_galleries_tab" >' +
											'<span id="lightwindow_galleries_tab_span" class="up" >Galleries</span>' +
										'</a>' +
									'</div>' +
									'<div id="lightwindow_galleries_list" >' +
									'</div>' +
								'</div>' +
							'</div>' +
							'<div id="lightwindow_data_slide" >' +
								'<div id="lightwindow_data_slide_inner" >' +
									'<div id="lightwindow_data_details" >' +
										'<div id="lightwindow_data_gallery_container" >' +
											'<span id="lightwindow_data_gallery_current"></span>' +
											' of ' +
											'<span id="lightwindow_data_gallery_total"></span>' +
										'</div>' +
										'<div id="lightwindow_data_author_container" >' +
											'by <span id="lightwindow_data_author"></span>' +
										'</div>' +
									'</div>' +
									'<div id="lightwindow_data_caption" >' +
									'</div>' +
								'</div>' +
							'</div>' +
						'</div>',
        loading: '<div id="lightwindow_loading" >' +
								'<img src="/images/ajax-loading.gif" alt="A carregar..." />' +
								'<span>A carregar... ou <a href="javascript: myLightWindow.deactivate();">Cancelar</a></span>' +
								'<iframe name="lightwindow_loading_shim" id="lightwindow_loading_shim" src="javascript:false;" frameBorder="0" scrolling="no"></iframe>' +
							'</div>',
        iframe: '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">' +
							'<html xmlns="http://www.w3.org/1999/xhtml">' +
								'<body>' +
									'{body_replace}' +
								'</body>' +
							'</html>',
        gallery: {
          top: '<div class="lightwindow_galleries_list">' +
									'<h1>{gallery_title_replace}</h1>' +
									'<ul>',
          middle: '<li>' +
											'{gallery_link_replace}' +
										'</li>',
          bottom: '</ul>' +
								'</div>'
        }
      },
      formMethod: 'get',
      hideFlash: false,
      hideGalleryTab: false,
      showTitleBar: true,
      animationHandler: false,
      navigationHandler: false,
      transitionHandler: false,
      finalAnimationHandler: false,
      formHandler: false,
      galleryAnimationHandler: false,
      showGalleryCount: true
    }, options || {});
    this.duration = ((11 - this.options.resizeSpeed) * 0.15);
    this._setupLinks();
    this._getScroll();
    this._getPageDimensions();
    this._browserDimensions();
    this._addLightWindowMarkup(false);
    this._setupDimensions();
    this.buildGalleryList();
  },
  //
  //	Activate the lightwindow.
  //
  activate: function(e, link) {
    // Clear out the window Contents
    this._clearWindowContents(true);

    // Add back in out loading panel
    this._addLoadingWindowMarkup();

    // Setup the element properties
    this._setupWindowElements(link);

    // Setup everything
    this._getScroll();
    this._browserDimensions();
    this._setupDimensions();
    this._toggleTroubleElements('hidden', false);
    this._displayLightWindow('block', 'hidden');
    this._setStatus(true);
    this._monitorKeyboard(true);
    this._prepareIE(true);
    this._loadWindow();
  },
  //
  //	Turn off the window
  //
  deactivate: function() {
    // The window is not active
    this.windowActive = false;

    // There is no longer a gallery active
    this.activeGallery = false;
    if (!this.options.hideGalleryTab) {
      this._handleGalleryAnimation(false);
    }

    // Kill the animation
    this.animating = false;

    // Clear our element
    this.element = null;

    // hide the window.
    this._displayLightWindow('none', 'visible');

    // Clear out the window Contents
    this._clearWindowContents(false);

    // Stop all animation
    var queue = Effect.Queues.get('lightwindowAnimation').each(function(e) { e.cancel(); });

    // Undo the setup
    this._prepareIE(false);
    this._setupDimensions();
    this._toggleTroubleElements('visible', false);
    this._monitorKeyboard(false);
  },
  //
  //  Initialize specific window
  //
  createWindow: function(element, attributes) {
    this._processLink($(element));
  },
  //
  //  Open a Window from a hash of attributes
  //
  activateWindow: function(options) {
    this.element = Object.extend({
      href: null,
      title: null,
      author: null,
      caption: null,
      rel: null,
      top: null,
      left: null,
      type: null,
      showImages: null,
      height: null,
      width: null,
      loadingAnimation: null,
      iframeEmbed: null,
      form: null
    }, options || {});

    // Set the window type
    this.contentToFetch = this.element.href;
    this.windowType = this.element.type ? this.element.type : this._fileType(this.element.href);

    // Clear out the window Contents
    this._clearWindowContents(true);

    // Add back in out loading panel
    this._addLoadingWindowMarkup();

    // Setup everything
    this._getScroll();
    this._browserDimensions();
    this._setupDimensions();
    this._toggleTroubleElements('hidden', false);
    this._displayLightWindow('block', 'hidden');
    this._setStatus(true);
    this._monitorKeyboard(true);
    this._prepareIE(true);
    this._loadWindow();
  },
  //
  //  Fire off our Form handler
  //
  submitForm: function(e) {
    if (this.options.formHandler) {
      this.options.formHandler(e);
    } else {
      this._defaultFormHandler(e);
    }
  },
  //
  //	Reload the window with another location
  //
  openWindow: function(element) {
    var element = $(element);

    // The window is active
    this.windowActive = true;

    // Clear out the window Contents
    this._clearWindowContents(true);

    // Add back in out loading panel
    this._addLoadingWindowMarkup();

    // Setup the element properties
    this._setupWindowElements(element);

    this._setStatus(true);
    this._handleTransition();
  },
  //
  //  Navigate the window
  //
  navigateWindow: function(direction) {
    this._handleNavigation(false);
    if (direction == 'previous') {
      this.openWindow(this.navigationObservers.previous);
    } else if (direction == 'next') {
      this.openWindow(this.navigationObservers.next);
    }
  },
  //
  //  Build the Gallery List and Load it
  //
  buildGalleryList: function() {
    var output = '';
    var galleryLink;
    for (i in this.galleries) {
      if (typeof this.galleries[i] == 'object') {
        output += (this.options.skin.gallery.top).replace('{gallery_title_replace}', unescape(i));
        for (j in this.galleries[i]) {
          if (typeof this.galleries[i][j] == 'object') {
            galleryLink = '<a href="#" id="lightwindow_gallery_' + i + '_' + j + '" >' + unescape(j) + '</a>';
            output += (this.options.skin.gallery.middle).replace('{gallery_link_replace}', galleryLink);
          }
        }
        output += this.options.skin.gallery.bottom;
      }
    }
    new Insertion.Top('lightwindow_galleries_list', output);

    // Attach Events
    for (i in this.galleries) {
      if (typeof this.galleries[i] == 'object') {
        for (j in this.galleries[i]) {
          if (typeof this.galleries[i][j] == 'object') {
            Event.observe($('lightwindow_gallery_' + i + '_' + j), 'click', this.openWindow.bind(this, this.galleries[i][j][0]), false);
            $('lightwindow_gallery_' + i + '_' + j).onclick = function() { return false; };
          }
        }
      }
    }
  },
  // 
  //  Set Links Up
  //
  _setupLinks: function() {
    var links = $$('.' + this.options.classNames.standard);
    links.each(function(link) {
      this._processLink(link);
    } .bind(this));
  },
  //
  //  Process a Link
  //
  _processLink: function(link) {
    if ((this._fileType(link.getAttribute('href')) == 'image' || this._fileType(link.getAttribute('href')) == 'media')) {
      if (gallery = this._getGalleryInfo(link.rel)) {
        if (!this.galleries[gallery[0]]) {
          this.galleries[gallery[0]] = new Array();
        }
        if (!this.galleries[gallery[0]][gallery[1]]) {
          this.galleries[gallery[0]][gallery[1]] = new Array();
        }
        this.galleries[gallery[0]][gallery[1]].push(link);
      }
    }

    // Take care of our inline content
    var url = link.getAttribute('href');
    if (url.indexOf('?') > -1) {
      url = url.substring(0, url.indexOf('?'));
    }

    var container = url.substring(url.indexOf('#') + 1);
    if ($(container)) {
      $(container).setStyle({
        display: 'none'
      });
    }

    Event.observe(link, 'click', this.activate.bindAsEventListener(this, link), false);
    link.onclick = function() { return false; };
  },
  //
  //	Setup our actions
  //
  _setupActions: function() {
    var links = $$('#lightwindow_container .' + this.options.classNames.action);
    links.each(function(link) {
      Event.observe(link, 'click', this[link.getAttribute('rel')].bindAsEventListener(this, link), false);
      link.onclick = function() { return false; };
    } .bind(this));
  },
  //
  //	Add the markup to the page.
  //
  _addLightWindowMarkup: function(rebuild) {
    var overlay = Element.extend(document.createElement('div'));
    overlay.setAttribute('id', 'lightwindow_overlay');
    // FF Mac has a problem with putting Flash above a layer without a 100% opacity background, so we need to use a pre-made
    if (Prototype.Browser.Gecko) {
      overlay.setStyle({
        backgroundImage: 'url(' + this.options.overlay.presetImage + ')',
        backgroundRepeat: 'repeat',
        height: this.pageDimensions.height + 'px'
      });
    } else {
      overlay.setStyle({
        opacity: this.options.overlay.opacity,
        backgroundImage: 'url(' + this.options.overlay.image + ')',
        backgroundRepeat: 'repeat',
        height: this.pageDimensions.height + 'px'
      });
    }

    var lw = document.createElement('div');
    lw.setAttribute('id', 'lightwindow');
    lw.innerHTML = this.options.skin.main;

    var body = document.getElementsByTagName('body')[0];
    body.appendChild(overlay);
    body.appendChild(lw);

    if ($('lightwindow_title_bar_close_link')) {
      Event.observe('lightwindow_title_bar_close_link', 'click', this.deactivate.bindAsEventListener(this));
      $('lightwindow_title_bar_close_link').onclick = function() { return false; };
    }

    Event.observe($('lightwindow_previous'), 'click', this.navigateWindow.bind(this, 'previous'), false);
    $('lightwindow_previous').onclick = function() { return false; };
    Event.observe($('lightwindow_next'), 'click', this.navigateWindow.bind(this, 'next'), false);
    $('lightwindow_next').onclick = function() { return false; };

    if (!this.options.hideGalleryTab) {
      Event.observe($('lightwindow_galleries_tab'), 'click', this._handleGalleryAnimation.bind(this, true), false);
      $('lightwindow_galleries_tab').onclick = function() { return false; };
    }

    // Because we use position absolute, kill the scroll Wheel on animations
    if (Prototype.Browser.IE) {
      Event.observe(document, 'mousewheel', this._stopScrolling.bindAsEventListener(this), false);
    } else {
      Event.observe(window, 'DOMMouseScroll', this._stopScrolling.bindAsEventListener(this), false);
    }

    Event.observe(overlay, 'click', this.deactivate.bindAsEventListener(this), false);
    overlay.onclick = function() { return false; };
  },
  //
  //  Add loading window markup
  //
  _addLoadingWindowMarkup: function() {
    $('lightwindow_contents').innerHTML += this.options.skin.loading;
  },
  //
  //  Setup the window elements
  //
  _setupWindowElements: function(link) {
    this.element = link;
    this.element.title = null ? '' : link.getAttribute('title');
    this.element.author = null ? '' : link.getAttribute('author');
    this.element.caption = null ? '' : link.getAttribute('caption');
    this.element.rel = null ? '' : link.getAttribute('rel');
    this.element.params = null ? '' : link.getAttribute('params');

    // Set the window type
    this.contentToFetch = this.element.href;
    this.windowType = this._getParameter('lightwindow_type') ? this._getParameter('lightwindow_type') : this._fileType(this.contentToFetch);
  },
  //
  //  Clear the window contents out
  //
  _clearWindowContents: function(contents) {
    // If there is an iframe, its got to go
    if ($('lightwindow_iframe')) {
      Element.remove($('lightwindow_iframe'));
    }

    // Stop playing an object if its still around
    if ($('lightwindow_media_primary')) {
      try {
        $('lightwindow_media_primary').Stop();
      } catch (e) { }
      Element.remove($('lightwindow_media_primary'));
    }

    // Stop playing an object if its still around		
    if ($('lightwindow_media_secondary')) {
      try {
        $('lightwindow_media_secondary').Stop();
      } catch (e) { }
      Element.remove($('lightwindow_media_secondary'));
    }

    this.activeGallery = false;
    this._handleNavigation(this.activeGallery);

    if (contents) {
      // Empty the contents
      $('lightwindow_contents').innerHTML = '';

      // Reset the scroll bars
      $('lightwindow_contents').setStyle({
        overflow: 'hidden'
      });

      if (!this.windowActive) {
        $('lightwindow_data_slide_inner').setStyle({
          display: 'none'
        });

        $('lightwindow_title_bar_title').innerHTML = '';
      }

      // Because of browser differences and to maintain flexible captions we need to reset this height at close
      $('lightwindow_data_slide').setStyle({
        height: 'auto'
      });
    }

    this.resizeTo.height = null;
    this.resizeTo.width = null;
  },
  //
  //	Set the status of our animation to keep things from getting clunky
  //
  _setStatus: function(status) {
    this.animating = status;
    if (status) {
      Element.show('lightwindow_loading');
    }
    if (!(/MSIE 6./i.test(navigator.userAgent))) {
      this._fixedWindow(status);
    }
  },
  //
  //  Make this window Fixed
  //
  _fixedWindow: function(status) {
    if (status) {
      if (this.windowActive) {
        this._getScroll();
        $('lightwindow').setStyle({
          position: 'absolute',
          top: parseFloat($('lightwindow').getStyle('top')) + this.pagePosition.y + 'px',
          left: parseFloat($('lightwindow').getStyle('left')) + this.pagePosition.x + 'px'
        });
      } else {
        $('lightwindow').setStyle({
          position: 'absolute'
        });
      }
    } else {
      if (this.windowActive) {
        this._getScroll();
        $('lightwindow').setStyle({
          position: 'fixed',
          top: parseFloat($('lightwindow').getStyle('top')) - this.pagePosition.y + 'px',
          left: parseFloat($('lightwindow').getStyle('left')) - this.pagePosition.x + 'px'
        });
      } else {
        if ($('lightwindow_iframe')) {
          // Ideally here we would set a 50% value for top and left, but Safari rears it ugly head again and we need to do it by pixels
          this._browserDimensions();
        }
        $('lightwindow').setStyle({
          position: 'fixed',
          top: (parseFloat(this._getParameter('lightwindow_top')) ? parseFloat(this._getParameter('lightwindow_top')) + 'px' : this.dimensions.viewport.height / 2 + 'px'),
          left: (parseFloat(this._getParameter('lightwindow_left')) ? parseFloat(this._getParameter('lightwindow_left')) + 'px' : this.dimensions.viewport.width / 2 + 'px')
        });
      }
    }
  },
  //
  //	Prepare the window for IE.
  //
  _prepareIE: function(setup) {
    if (Prototype.Browser.IE) {
      var height, overflowX, overflowY;
      if (setup) {
        var height = '100%';
      } else {
        var height = 'auto';
      }
      var body = document.getElementsByTagName('body')[0];
      var html = document.getElementsByTagName('html')[0];
      html.style.height = body.style.height = height;
    }
  },
  _stopScrolling: function(e) {
    if (this.animating) {
      if (e.preventDefault) {
        e.preventDefault();
      }
      e.returnValue = false;
    }
  },
  //
  //	Get the scroll for the page.
  //
  _getScroll: function() {
    if (typeof (window.pageYOffset) == 'number') {
      this.pagePosition.x = window.pageXOffset;
      this.pagePosition.y = window.pageYOffset;
    } else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
      this.pagePosition.x = document.body.scrollLeft;
      this.pagePosition.y = document.body.scrollTop;
    } else if (document.documentElement) {
      this.pagePosition.x = document.documentElement.scrollLeft;
      this.pagePosition.y = document.documentElement.scrollTop;
    }
  },
  //
  //	Reset the scroll.
  //
  _setScroll: function(x, y) {
    document.documentElement.scrollLeft = x;
    document.documentElement.scrollTop = y;
  },
  //
  //	Hide Selects from the page because of IE.
  //     We could use iframe shims instead here but why add all the extra markup for one browser when this is much easier and cleaner
  //
  _toggleTroubleElements: function(visibility, content) {

    if (content) {
      var selects = $('lightwindow_contents').getElementsByTagName('select');
    } else {
      var selects = document.getElementsByTagName('select');
    }

    for (var i = 0; i < selects.length; i++) {
      selects[i].style.visibility = visibility;
    }

    if (!content) {
      if (this.options.hideFlash) {
        var objects = document.getElementsByTagName('object');
        for (i = 0; i != objects.length; i++) {
          objects[i].style.visibility = visibility;
        }
        var embeds = document.getElementsByTagName('embed');
        for (i = 0; i != embeds.length; i++) {
          embeds[i].style.visibility = visibility;
        }
      }
      var iframes = document.getElementsByTagName('iframe');
      for (i = 0; i != iframes.length; i++) {
        iframes[i].style.visibility = visibility;
      }
    }
  },
  // 
  //  Get the actual page size
  //
  _getPageDimensions: function() {
    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) {
      xScroll = document.body.scrollWidth;
      yScroll = document.body.scrollHeight;
    } else {
      xScroll = document.body.offsetWidth;
      yScroll = document.body.offsetHeight;
    }

    var windowWidth, windowHeight;
    if (self.innerHeight) {
      windowWidth = self.innerWidth;
      windowHeight = self.innerHeight;
    } else if (document.documentElement && document.documentElement.clientHeight) {
      windowWidth = document.documentElement.clientWidth;
      windowHeight = document.documentElement.clientHeight;
    } else if (document.body) {
      windowWidth = document.body.clientWidth;
      windowHeight = document.body.clientHeight;
    }

    if (yScroll < windowHeight) {
      this.pageDimensions.height = windowHeight;
    } else {
      this.pageDimensions.height = yScroll;
    }

    if (xScroll < windowWidth) {
      this.pageDimensions.width = windowWidth;
    } else {
      this.pageDimensions.width = xScroll;
    }
  },
  //
  //	Display the lightWindow.
  //
  _displayLightWindow: function(display, visibility) {
    $('lightwindow_overlay').style.display = $('lightwindow').style.display = $('lightwindow_container').style.display = display;
    $('lightwindow_overlay').style.visibility = $('lightwindow').style.visibility = $('lightwindow_container').style.visibility = visibility;
  },
  //
  //	Setup Dimensions of lightwindow.

  //
  _setupDimensions: function() {

    var originalHeight, originalWidth;
    switch (this.windowType) {
      case 'page':
        originalHeight = this.options.dimensions.page.height;
        originalWidth = this.options.dimensions.page.width;
        break;

      case 'image':
        originalHeight = this.options.dimensions.image.height;
        originalWidth = this.options.dimensions.image.width;
        break;

      case 'media':
        originalHeight = this.options.dimensions.media.height;
        originalWidth = this.options.dimensions.media.width;
        break;

      case 'external':
        originalHeight = this.options.dimensions.external.height;
        originalWidth = this.options.dimensions.external.width;
        break;

      case 'inline':
        originalHeight = this.options.dimensions.inline.height;
        originalWidth = this.options.dimensions.inline.width;
        break;

      default:
        originalHeight = this.options.dimensions.page.height;
        originalWidth = this.options.dimensions.page.width;
        break;

    }

    var offsetHeight = this._getParameter('lightwindow_top') ? parseFloat(this._getParameter('lightwindow_top')) + this.pagePosition.y : this.dimensions.viewport.height / 2 + this.pagePosition.y;
    var offsetWidth = this._getParameter('lightwindow_left') ? parseFloat(this._getParameter('lightwindow_left')) + this.pagePosition.x : this.dimensions.viewport.width / 2 + this.pagePosition.x;

    // So if a theme has say shadowed edges, they should be consistant and take care of in the contentOffset
    $('lightwindow').setStyle({
      top: offsetHeight + 'px',
      left: offsetWidth + 'px'
    });

    $('lightwindow_container').setStyle({
      height: originalHeight + 'px',
      width: originalWidth + 'px',
      left: -(originalWidth / 2) + 'px',
      top: -(originalHeight / 2) + 'px'
    });

    $('lightwindow_contents').setStyle({
      height: originalHeight + 'px',
      width: originalWidth + 'px'
    });
  },
  //
  //	Get the type of file.
  //
  _fileType: function(url) {
    var image = new RegExp("[^\.]\.(" + this.options.fileTypes.image.join('|') + ")\s*$", "i");
    if (image.test(url)) return 'image';
    if (url.indexOf('#') > -1 && (document.domain == this._getDomain(url))) return 'inline';
    if (url.indexOf('?') > -1) url = url.substring(0, url.indexOf('?'));
    var type = 'unknown';
    var page = new RegExp("[^\.]\.(" + this.options.fileTypes.page.join('|') + ")\s*$", "i");
    var media = new RegExp("[^\.]\.(" + this.options.fileTypes.media.join('|') + ")\s*$", "i");
    if (document.domain != this._getDomain(url)) type = 'external';
    if (media.test(url)) type = 'media';
    if (type == 'external' || type == 'media') return type;
    if (page.test(url) || url.substr((url.length - 1), url.length) == '/') type = 'page';
    return type;
  },
  //
  //  Get file Extension
  //
  _fileExtension: function(url) {
    if (url.indexOf('?') > -1) {
      url = url.substring(0, url.indexOf('?'));
    }
    var extenstion = '';
    for (var x = (url.length - 1); x > -1; x--) {
      if (url.charAt(x) == '.') {
        return extenstion;
      }
      extenstion = url.charAt(x) + extenstion;
    }
  },
  //
  //	Monitor the keyboard while this lightwindow is up
  //
  _monitorKeyboard: function(status) {
    if (status) document.onkeydown = this._eventKeypress.bind(this);
    else document.onkeydown = '';
  },
  //
  //  Perform keyboard actions
  //
  _eventKeypress: function(e) {
    if (e == null) {
      var keycode = event.keyCode;
    } else {
      var keycode = e.which;
    }

    switch (keycode) {
      case 27:
        this.deactivate();
        break;

      case 13:
        return;

      default:
        break;
    }

    // Gotta stop those quick fingers
    if (this.animating) {
      return false;
    }

    switch (String.fromCharCode(keycode).toLowerCase()) {
      case 'p':
        if (this.navigationObservers.previous) {
          this.navigateWindow('previous');
        }
        break;

      case 'n':
        if (this.navigationObservers.next) {
          this.navigateWindow('next');
        }
        break;

      default:
        break;
    }
  },
  //
  //	Get Gallery Information
  //
  _getGalleryInfo: function(rel) {
    if (!rel) return false;
    if (rel.indexOf('[') > -1) {
      return new Array(escape(rel.substring(0, rel.indexOf('['))), escape(rel.substring(rel.indexOf('[') + 1, rel.indexOf(']'))));
    } else {
      return false;
    }
  },
  //
  //	Get the domain from a string.
  //
  _getDomain: function(url) {
    var leadSlashes = url.indexOf('//');
    var domainStart = leadSlashes + 2;
    var withoutResource = url.substring(domainStart, url.length);
    var nextSlash = withoutResource.indexOf('/');
    var domain = withoutResource.substring(0, nextSlash);
    if (domain.indexOf(':') > -1) {
      var portColon = domain.indexOf(':');
      domain = domain.substring(0, portColon);
    }
    return domain + '/';
  },
  //
  //	Get the value from the params attribute string.
  //
  _getParameter: function(parameter, parameters) {
    if (!this.element) return false;
    if (parameter == 'lightwindow_top' && this.element.top) {
      return unescape(this.element.top);
    } else if (parameter == 'lightwindow_left' && this.element.left) {
      return unescape(this.element.left);
    } else if (parameter == 'lightwindow_type' && this.element.type) {
      return unescape(this.element.type);
    } else if (parameter == 'lightwindow_show_images' && this.element.showImages) {
      return unescape(this.element.showImages);
    } else if (parameter == 'lightwindow_height' && this.element.height) {
      return unescape(this.element.height);
    } else if (parameter == 'lightwindow_width' && this.element.width) {
      return unescape(this.element.width);
    } else if (parameter == 'lightwindow_loading_animation' && this.element.loadingAnimation) {
      return unescape(this.element.loadingAnimation);
    } else if (parameter == 'lightwindow_iframe_embed' && this.element.iframeEmbed) {
      return unescape(this.element.iframeEmbed);
    } else if (parameter == 'lightwindow_form' && this.element.form) {
      return unescape(this.element.form);
    } else {
      if (!parameters) {
        if (this.element.params) parameters = this.element.params;
        else return;
      }
      var value;
      var parameterArray = parameters.split(',');
      var compareString = parameter + '=';
      var compareLength = compareString.length;
      for (var i = 0; i < parameterArray.length; i++) {
        if (parameterArray[i].substr(0, compareLength) == compareString) {
          var currentParameter = parameterArray[i].split('=');
          value = currentParameter[1];
          break;
        }
      }
      if (!value) return false;
      else return unescape(value);
    }
  },
  //
  //  Get the Browser Viewport Dimensions
  //
  _browserDimensions: function() {
    if (Prototype.Browser.IE) {
      this.dimensions.viewport.height = document.documentElement.clientHeight;
      this.dimensions.viewport.width = document.documentElement.clientWidth;
    } else {
      this.dimensions.viewport.height = window.innerHeight;
      this.dimensions.viewport.width = document.width || document.body.offsetWidth;
    }
  },
  //
  //  Get the scrollbar offset, I don't like this method but there is really no other way I can find.
  //
  _getScrollerWidth: function() {
    var scrollDiv = Element.extend(document.createElement('div'));
    scrollDiv.setAttribute('id', 'lightwindow_scroll_div');
    scrollDiv.setStyle({
      position: 'absolute',
      top: '-10000px',
      left: '-10000px',
      width: '100px',
      height: '100px',
      overflow: 'hidden'
    });



    var contentDiv = Element.extend(document.createElement('div'));
    contentDiv.setAttribute('id', 'lightwindow_content_scroll_div');
    contentDiv.setStyle({
      width: '100%',
      height: '200px'
    });

    scrollDiv.appendChild(contentDiv);

    var body = document.getElementsByTagName('body')[0];
    body.appendChild(scrollDiv);

    var noScroll = $('lightwindow_content_scroll_div').offsetWidth;
    scrollDiv.style.overflow = 'auto';
    var withScroll = $('lightwindow_content_scroll_div').offsetWidth;

    Element.remove($('lightwindow_scroll_div'));

    this.scrollbarOffset = noScroll - withScroll;
  },


  //
  //  Add a param to an object dynamically created
  //
  _addParamToObject: function(name, value, object, id) {
    var param = document.createElement('param');
    param.setAttribute('value', value);
    param.setAttribute('name', name);
    if (id) {
      param.setAttribute('id', id);
    }
    object.appendChild(param);
    return object;
  },
  //
  //  Get the outer HTML of an object CROSS BROWSER
  //
  _outerHTML: function(object) {
    if (Prototype.Browser.IE) {
      return object.outerHTML;
    } else {
      var clone = object.cloneNode(true);
      var cloneDiv = document.createElement('div');
      cloneDiv.appendChild(clone);
      return cloneDiv.innerHTML;
    }
  },
  //
  //  Convert an object to markup
  //
  _convertToMarkup: function(object, closeTag) {
    var markup = this._outerHTML(object).replace('</' + closeTag + '>', '');
    if (Prototype.Browser.IE) {
      for (var i = 0; i < object.childNodes.length; i++) {
        markup += this._outerHTML(object.childNodes[i]);
      }
      markup += '</' + closeTag + '>';
    }
    return markup;
  },
  //
  //  Depending what type of browser it is we have to append the object differently... DAMN YOU IE!!
  //
  _appendObject: function(object, closeTag, appendTo) {
    if (Prototype.Browser.IE) {
      appendTo.innerHTML += this._convertToMarkup(object, closeTag);

      // Fix the Eolas activate thing but only for specified media, for example doing this to a quicktime film breaks it.
      if (this.options.EOLASFix.indexOf(this._fileType(this.element.href)) > -1) {
        var objectElements = document.getElementsByTagName('object');
        for (var i = 0; i < objectElements.length; i++) {
          if (objectElements[i].getAttribute("data")) objectElements[i].removeAttribute('data');
          objectElements[i].outerHTML = objectElements[i].outerHTML;
          objectElements[i].style.visibility = "visible";
        }
      }
    } else {
      appendTo.appendChild(object);
    }
  },
  //
  //  Add in iframe
  //
  _appendIframe: function(scroll) {
    var iframe = document.createElement('iframe');
    iframe.setAttribute('id', 'lightwindow_iframe');
    iframe.setAttribute('name', 'lightwindow_iframe');
    iframe.setAttribute('src', 'about:blank');
    iframe.setAttribute('height', '100%');
    iframe.setAttribute('width', '100%');
    iframe.setAttribute('frameborder', '0');
    iframe.setAttribute('marginwidth', '0');
    iframe.setAttribute('marginheight', '0');
    iframe.setAttribute('scrolling', scroll);

    this._appendObject(iframe, 'iframe', $('lightwindow_contents'));
  },
  //
  //  Write Content to the iframe using the skin
  //
  _writeToIframe: function(content) {
    var template = this.options.skin.iframe;
    template = template.replace('{body_replace}', content);
    if ($('lightwindow_iframe').contentWindow) {
      $('lightwindow_iframe').contentWindow.document.open();
      $('lightwindow_iframe').contentWindow.document.write(template);
      $('lightwindow_iframe').contentWindow.document.close();
    } else {
      $('lightwindow_iframe').contentDocument.open();
      $('lightwindow_iframe').contentDocument.write(template);
      $('lightwindow_iframe').contentDocument.close();
    }
  },
  //
  //  Load the window Information
  //  
  _loadWindow: function() {
    switch (this.windowType) {
      case 'image':

        var current = 0;
        var images = [];
        this.checkImage = [];
        this.resizeTo.height = this.resizeTo.width = 0;
        this.imageCount = this._getParameter('lightwindow_show_images') ? parseInt(this._getParameter('lightwindow_show_images')) : 1;

        // If there is a gallery get it
        if (gallery = this._getGalleryInfo(this.element.rel)) {
          for (current = 0; current < this.galleries[gallery[0]][gallery[1]].length; current++) {
            if (this.contentToFetch.indexOf(this.galleries[gallery[0]][gallery[1]][current].href) > -1) {
              break;
            }
          }
          if (this.galleries[gallery[0]][gallery[1]][current - this.imageCount]) {
            this.navigationObservers.previous = this.galleries[gallery[0]][gallery[1]][current - this.imageCount];
          } else {
            this.navigationObservers.previous = false;
          }
          if (this.galleries[gallery[0]][gallery[1]][current + this.imageCount]) {
            this.navigationObservers.next = this.galleries[gallery[0]][gallery[1]][current + this.imageCount];
          } else {
            this.navigationObservers.next = false;
          }

          this.activeGallery = true;
        } else {
          this.navigationObservers.previous = false;
          this.navigationObservers.next = false;

          this.activeGallery = false;
        }

        for (var i = current; i < (current + this.imageCount); i++) {

          if (gallery && this.galleries[gallery[0]][gallery[1]][i]) {
            this.contentToFetch = this.galleries[gallery[0]][gallery[1]][i].href;

            this.galleryLocation = { current: (i + 1) / this.imageCount, total: (this.galleries[gallery[0]][gallery[1]].length) / this.imageCount };

            if (!this.galleries[gallery[0]][gallery[1]][i + this.imageCount]) {
              $('lightwindow_next').setStyle({
                display: 'none'
              });
            } else {
              $('lightwindow_next').setStyle({
                display: 'block'
              });
              $('lightwindow_next_title').innerHTML = this.galleries[gallery[0]][gallery[1]][i + this.imageCount].title;
            }

            if (!this.galleries[gallery[0]][gallery[1]][i - this.imageCount]) {
              $('lightwindow_previous').setStyle({
                display: 'none'
              });
            } else {
              $('lightwindow_previous').setStyle({
                display: 'block'
              });
              $('lightwindow_previous_title').innerHTML = this.galleries[gallery[0]][gallery[1]][i - this.imageCount].title;
            }
          }

          images[i] = document.createElement('img');
          images[i].setAttribute('id', 'lightwindow_image_' + i);
          images[i].setAttribute('border', '0');
          images[i].setAttribute('src', this.contentToFetch);
          $('lightwindow_contents').appendChild(images[i]);

          // We have to do this instead of .onload 
          this.checkImage[i] = new PeriodicalExecuter(function(i) {
            if (!(typeof $('lightwindow_image_' + i).naturalWidth != "undefined" && $('lightwindow_image_' + i).naturalWidth == 0)) {

              this.checkImage[i].stop();

              var imageHeight = $('lightwindow_image_' + i).getHeight();
              if (imageHeight > this.resizeTo.height) {
                this.resizeTo.height = imageHeight;
              }
              this.resizeTo.width += $('lightwindow_image_' + i).getWidth();
              this.imageCount--;

              $('lightwindow_image_' + i).setStyle({
                height: '100%'
              });

              if (this.imageCount == 0) {
                this._processWindow();
              }
            }

          } .bind(this, i), 1);
        }


        break;

      case 'media':

        var current = 0;
        this.resizeTo.height = this.resizeTo.width = 0;

        // If there is a gallery get it
        if (gallery = this._getGalleryInfo(this.element.rel)) {
          for (current = 0; current < this.galleries[gallery[0]][gallery[1]].length; current++) {
            if (this.contentToFetch.indexOf(this.galleries[gallery[0]][gallery[1]][current].href) > -1) {
              break;
            }
          }

          if (this.galleries[gallery[0]][gallery[1]][current - 1]) {
            this.navigationObservers.previous = this.galleries[gallery[0]][gallery[1]][current - 1];
          } else {
            this.navigationObservers.previous = false;
          }
          if (this.galleries[gallery[0]][gallery[1]][current + 1]) {
            this.navigationObservers.next = this.galleries[gallery[0]][gallery[1]][current + 1];
          } else {
            this.navigationObservers.next = false;
          }

          this.activeGallery = true;
        } else {
          this.navigationObservers.previous = false;
          this.navigationObservers.next = false;

          this.activeGallery = false;
        }


        if (gallery && this.galleries[gallery[0]][gallery[1]][current]) {
          this.contentToFetch = this.galleries[gallery[0]][gallery[1]][current].href;

          this.galleryLocation = { current: current + 1, total: this.galleries[gallery[0]][gallery[1]].length };

          if (!this.galleries[gallery[0]][gallery[1]][current + 1]) {
            $('lightwindow_next').setStyle({
              display: 'none'
            });
          } else {
            $('lightwindow_next').setStyle({
              display: 'block'
            });
            $('lightwindow_next_title').innerHTML = this.galleries[gallery[0]][gallery[1]][current + 1].title;
          }

          if (!this.galleries[gallery[0]][gallery[1]][current - 1]) {
            $('lightwindow_previous').setStyle({
              display: 'none'
            });
          } else {
            $('lightwindow_previous').setStyle({
              display: 'block'
            });
            $('lightwindow_previous_title').innerHTML = this.galleries[gallery[0]][gallery[1]][current - 1].title;
          }
        }

        if (this._getParameter('lightwindow_iframe_embed')) {
          this.resizeTo.height = this.dimensions.viewport.height;
          this.resizeTo.width = this.dimensions.viewport.width;
        } else {
          this.resizeTo.height = this._getParameter('lightwindow_height');
          this.resizeTo.width = this._getParameter('lightwindow_width');
        }

        this._processWindow();

        break;

      case 'external':

        this._appendIframe('auto');

        this.resizeTo.height = this.dimensions.viewport.height;
        this.resizeTo.width = this.dimensions.viewport.width;

        this._processWindow();

        break;

      case 'page':

        var newAJAX = new Ajax.Request(
				this.contentToFetch, {
				  method: 'get',
				  parameters: '',
				  onComplete: function(response) {
				    $('lightwindow_contents').innerHTML += response.responseText;
				    this.resizeTo.height = $('lightwindow_contents').scrollHeight + (this.options.contentOffset.height);
				    this.resizeTo.width = $('lightwindow_contents').scrollWidth + (this.options.contentOffset.width);
				    this._processWindow();
				  } .bind(this)
				}
			);

        break;

      case 'inline':

        var content = this.contentToFetch;
        if (content.indexOf('?') > -1) {
          content = content.substring(0, content.indexOf('?'));
        }
        content = content.substring(content.indexOf('#') + 1);

        new Insertion.Top($('lightwindow_contents'), $(content).innerHTML);

        this.resizeTo.height = $('lightwindow_contents').scrollHeight + (this.options.contentOffset.height);
        this.resizeTo.width = $('lightwindow_contents').scrollWidth + (this.options.contentOffset.width);

        this._toggleTroubleElements('hidden', true);
        this._processWindow();

        break;

      default:
        throw ("Page Type could not be determined, please amend this lightwindow URL " + this.contentToFetch);
        break;
    }
  },
  //
  //  Resize the Window to fit the viewport if necessary
  //
  _resizeWindowToFit: function() {
    if (this.resizeTo.height + this.dimensions.cruft.height > this.dimensions.viewport.height) {
      var heightRatio = this.resizeTo.height / this.resizeTo.width;
      this.resizeTo.height = this.dimensions.viewport.height - this.dimensions.cruft.height - (2 * this.options.viewportPadding);
      // We only care about ratio's with this window type			
      if (this.windowType == 'image' || (this.windowType == 'media' && !this._getParameter('lightwindow_iframe_embed'))) {
        this.resizeTo.width = this.resizeTo.height / heightRatio;
        $('lightwindow_data_slide_inner').setStyle({
          width: this.resizeTo.width + 'px'
        });
      }
    }
    if (this.resizeTo.width + this.dimensions.cruft.width > this.dimensions.viewport.width) {
      var widthRatio = this.resizeTo.width / this.resizeTo.height;
      this.resizeTo.width = this.dimensions.viewport.width - 2 * this.dimensions.cruft.width - (2 * this.options.viewportPadding);
      // We only care about ratio's with this window type
      if (this.windowType == 'image' || (this.windowType == 'media' && !this._getParameter('lightwindow_iframe_embed'))) {
        this.resizeTo.height = this.resizeTo.width / widthRatio;
        $('lightwindow_data_slide_inner').setStyle({
          height: this.resizeTo.height + 'px'
        });
      }
    }

  },
  //
  //  Set the Window to a preset size
  //
  _presetWindowSize: function() {
    if (this._getParameter('lightwindow_height')) {
      this.resizeTo.height = parseFloat(this._getParameter('lightwindow_height'));
    }
    if (this._getParameter('lightwindow_width')) {
      this.resizeTo.width = parseFloat(this._getParameter('lightwindow_width'));
    }
  },
  //
  //  Process the Window
  //
  _processWindow: function() {
    // Clean out our effects
    this.dimensions.dataEffects = [];

    // Set up the data-slide if we have caption information
    if (this.element.caption || this.element.author || (this.activeGallery && this.options.showGalleryCount)) {
      if (this.element.caption) {
        $('lightwindow_data_caption').innerHTML = this.element.caption;
        $('lightwindow_data_caption').setStyle({
          display: 'block'
        });
      } else {
        $('lightwindow_data_caption').setStyle({
          display: 'none'
        });
      }
      if (this.element.author) {
        $('lightwindow_data_author').innerHTML = this.element.author;
        $('lightwindow_data_author_container').setStyle({
          display: 'block'
        });
      } else {
        $('lightwindow_data_author_container').setStyle({
          display: 'none'
        });
      }
      if (this.activeGallery && this.options.showGalleryCount) {
        $('lightwindow_data_gallery_current').innerHTML = this.galleryLocation.current;
        $('lightwindow_data_gallery_total').innerHTML = this.galleryLocation.total;
        $('lightwindow_data_gallery_container').setStyle({
          display: 'block'
        });
      } else {
        $('lightwindow_data_gallery_container').setStyle({
          display: 'none'
        });
      }

      $('lightwindow_data_slide_inner').setStyle({
        width: this.resizeTo.width + 'px',
        height: 'auto',
        visibility: 'visible',
        display: 'block'
      });
      $('lightwindow_data_slide').setStyle({
        height: $('lightwindow_data_slide').getHeight() + 'px',
        width: '1px',
        overflow: 'hidden',
        display: 'block'
      });
    } else {
      $('lightwindow_data_slide').setStyle({
        display: 'none',
        width: 'auto'
      });
      $('lightwindow_data_slide_inner').setStyle({
        display: 'none',
        visibility: 'hidden',
        width: this.resizeTo.width + 'px',
        height: '0px'
      });
    }

    if (this.element.title != 'null') {
      $('lightwindow_title_bar_title').innerHTML = this.element.title;
    } else {
      $('lightwindow_title_bar_title').innerHTML = '';
    }

    var originalContainerDimensions = { height: $('lightwindow_container').getHeight(), width: $('lightwindow_container').getWidth() };
    // Position the window
    $('lightwindow_container').setStyle({
      height: 'auto',
      // We need to set the width to a px not auto as opera has problems with it
      width: $('lightwindow_container').getWidth() + this.options.contentOffset.width - (this.windowActive ? this.options.contentOffset.width : 0) + 'px'
    });
    var newContainerDimensions = { height: $('lightwindow_container').getHeight(), width: $('lightwindow_container').getWidth() };

    // We need to record the container dimension changes
    this.containerChange = { height: originalContainerDimensions.height - newContainerDimensions.height, width: originalContainerDimensions.width - newContainerDimensions.width };

    // Get out general dimensions
    this.dimensions.container = { height: $('lightwindow_container').getHeight(), width: $('lightwindow_container').getWidth() };
    this.dimensions.cruft = { height: this.dimensions.container.height - $('lightwindow_contents').getHeight() + this.options.contentOffset.height, width: this.dimensions.container.width - $('lightwindow_contents').getWidth() + this.options.contentOffset.width };

    // Set Sizes if we need too
    this._presetWindowSize();
    this._resizeWindowToFit(); // Even if the window is preset we still don't want it to go outside of the viewport

    if (!this.windowActive) {
      // Position the window
      $('lightwindow_container').setStyle({
        left: -(this.dimensions.container.width / 2) + 'px',
        top: -(this.dimensions.container.height / 2) + 'px'
      });
    }
    $('lightwindow_container').setStyle({
      height: this.dimensions.container.height + 'px',
      width: this.dimensions.container.width + 'px'
    });

    // We are ready, lets show this puppy off!
    this._displayLightWindow('block', 'visible');
    this._animateLightWindow();
  },
  //
  //  Fire off our animation handler
  //
  _animateLightWindow: function() {
    if (this.options.animationHandler) {
      this.options.animationHandler().bind(this);
    } else {
      this._defaultAnimationHandler();
    }
  },
  //
  //  Fire off our transition handler
  //
  _handleNavigation: function(display) {
    if (this.options.navigationHandler) {
      this.options.navigationHandler().bind(this, display);
    } else {
      this._defaultDisplayNavigation(display);
    }
  },
  //
  //  Fire off our transition handler
  //
  _handleTransition: function() {
    if (this.options.transitionHandler) {
      this.options.transitionHandler().bind(this);
    } else {
      this._defaultTransitionHandler();
    }
  },
  //
  //  Handle the finish of the window animation
  // 
  _handleFinalWindowAnimation: function(delay) {
    if (this.options.finalAnimationHandler) {
      this.options.finalAnimationHandler().bind(this, delay);
    } else {
      this._defaultfinalWindowAnimationHandler(delay);
    }
  },
  //
  //  Handle the gallery Animation
  // 
  _handleGalleryAnimation: function(list) {
    if (this.options.galleryAnimationHandler) {
      this.options.galleryAnimationHandler().bind(this, list);
    } else {
      this._defaultGalleryAnimationHandler(list);
    }
  },
  //
  //  Display the navigation 
  //
  _defaultDisplayNavigation: function(display) {
    if (display) {
      $('lightwindow_navigation').setStyle({
        display: 'block',
        height: $('lightwindow_contents').getHeight() + 'px',
        width: '100%',
        marginTop: this.options.dimensions.titleHeight + 'px'
      });
    } else {
      $('lightwindow_navigation').setStyle({
        display: 'none',
        height: 'auto',
        width: 'auto'
      });
    }
  },
  //
  //  This is the default animation handler for LightWindow
  //
  _defaultAnimationHandler: function() {
    // Now that we have figures out the cruft lets make the caption go away and add its effects
    if (this.element.caption || this.element.author || (this.activeGallery && this.options.showGalleryCount)) {
      $('lightwindow_data_slide').setStyle({
        display: 'none',
        width: 'auto'
      });
      this.dimensions.dataEffects.push(
				new Effect.SlideDown('lightwindow_data_slide', { sync: true }),
				new Effect.Appear('lightwindow_data_slide', { sync: true, from: 0.0, to: 1.0 })
			);
    }

    // Set up the Title if we have one
    $('lightwindow_title_bar_inner').setStyle({
      height: '0px',
      marginTop: this.options.dimensions.titleHeight + 'px'
    });

    // We always want the title bar as well
    this.dimensions.dataEffects.push(
			new Effect.Morph('lightwindow_title_bar_inner', { sync: true, style: { height: this.options.dimensions.titleHeight + 'px', marginTop: '0px'} }),
		 	new Effect.Appear('lightwindow_title_bar_inner', { sync: true, from: 0.0, to: 1.0 })
		);

    if (!this.options.hideGalleryTab) {
      this._handleGalleryAnimation(false);
      if ($('lightwindow_galleries_tab_container').getHeight() == 0) {
        this.dimensions.dataEffects.push(
					new Effect.Morph('lightwindow_galleries_tab_container', { sync: true, style: { height: '20px', marginTop: '0px'} })
				);
        $('lightwindow_galleries').setStyle({
          width: '0px'
        });
      }
    }

    var resized = false;
    var ratio = this.dimensions.container.width - $('lightwindow_contents').getWidth() + this.resizeTo.width + this.options.contentOffset.width;
    if (ratio != $('lightwindow_container').getWidth()) {
      new Effect.Parallel([
					new Effect.Scale('lightwindow_contents', 100 * (this.resizeTo.width / $('lightwindow_contents').getWidth()), { scaleFrom: 100 * ($('lightwindow_contents').getWidth() / ($('lightwindow_contents').getWidth() + (this.options.contentOffset.width))), sync: true, scaleY: false, scaleContent: false }),
					new Effect.Scale('lightwindow_container', 100 * (ratio / (this.dimensions.container.width)), { sync: true, scaleY: false, scaleFromCenter: true, scaleContent: false })
				], {
				  duration: this.duration,
				  delay: 0.25,
				  queue: { position: 'end', scope: 'lightwindowAnimation' }
				}
			);
    }

    ratio = this.dimensions.container.height - $('lightwindow_contents').getHeight() + this.resizeTo.height + this.options.contentOffset.height;
    if (ratio != $('lightwindow_container').getHeight()) {
      new Effect.Parallel([
					new Effect.Scale('lightwindow_contents', 100 * (this.resizeTo.height / $('lightwindow_contents').getHeight()), { scaleFrom: 100 * ($('lightwindow_contents').getHeight() / ($('lightwindow_contents').getHeight() + (this.options.contentOffset.height))), sync: true, scaleX: false, scaleContent: false }),
					new Effect.Scale('lightwindow_container', 100 * (ratio / (this.dimensions.container.height)), { sync: true, scaleX: false, scaleFromCenter: true, scaleContent: false })
				], {
				  duration: this.duration,
				  afterFinish: function() {
				    if (this.dimensions.dataEffects.length > 0) {
				      if (!this.options.hideGalleryTab) {
				        $('lightwindow_galleries').setStyle({
				          width: this.resizeTo.width + 'px'
				        });
				      }
				      new Effect.Parallel(this.dimensions.dataEffects, {
				        duration: this.duration,
				        afterFinish: function() {
				          this._finishWindow();
				        } .bind(this),
				        queue: { position: 'end', scope: 'lightwindowAnimation' }
				      }
							);
				    }
				  } .bind(this),
				  queue: { position: 'end', scope: 'lightwindowAnimation' }
				}
			);
      resized = true;
    }

    // We need to do our data effect since there was no resizing
    if (!resized && this.dimensions.dataEffects.length > 0) {
      new Effect.Parallel(this.dimensions.dataEffects, {
        duration: this.duration,
        beforeStart: function() {
          if (!this.options.hideGalleryTab) {
            $('lightwindow_galleries').setStyle({
              width: this.resizeTo.width + 'px'
            });
          }
          if (this.containerChange.height != 0 || this.containerChange.width != 0) {
            new Effect.MoveBy('lightwindow_container', this.containerChange.height, this.containerChange.width, { transition: Effect.Transitions.sinoidal });
          }
        } .bind(this),
        afterFinish: function() {
          this._finishWindow();
        } .bind(this),
        queue: { position: 'end', scope: 'lightwindowAnimation' }
      }
			);
    }

  },
  //
  //  Finish up Window Animation
  //
  _defaultfinalWindowAnimationHandler: function(delay) {
    if (this.windowType == 'media' || this._getParameter('lightwindow_loading_animation')) {
      // Because of major flickering with the overlay we just hide it in this case
      Element.hide('lightwindow_loading');
      this._handleNavigation(this.activeGallery);
      this._setStatus(false);
    } else {
      Effect.Fade('lightwindow_loading', {
        duration: 0.75,
        delay: 1.0,
        afterFinish: function() {
          // Just in case we need some scroll goodness (this also avoids the swiss cheese effect)
          if (this.windowType != 'image' && this.windowType != 'media' && this.windowType != 'external') {
            $('lightwindow_contents').setStyle({
              overflow: 'auto'
            });
          }
          this._handleNavigation(this.activeGallery);
          this._defaultGalleryAnimationHandler();
          this._setStatus(false);
        } .bind(this),
        queue: { position: 'end', scope: 'lightwindowAnimation' }
      });
    }
  },
  //
  //  Handle the gallery Animation
  //
  _defaultGalleryAnimationHandler: function(list) {
    if (this.activeGallery) {
      $('lightwindow_galleries').setStyle({
        display: 'block',
        marginBottom: $('lightwindow_data_slide').getHeight() + this.options.contentOffset.height / 2 + 'px'
      });
      $('lightwindow_navigation').setStyle({
        height: $('lightwindow_contents').getHeight() - 20 + 'px'
      });
    } else {
      $('lightwindow_galleries').setStyle({
        display: 'none'
      });
      $('lightwindow_galleries_tab_container').setStyle({
        height: '0px',
        marginTop: '20px'
      });
      $('lightwindow_galleries_list').setStyle({
        height: '0px'
      });
      return false;
    }

    if (list) {
      if ($('lightwindow_galleries_list').getHeight() == 0) {
        var height = $('lightwindow_contents').getHeight() * 0.80;
        $('lightwindow_galleries_tab_span').className = 'down';
      } else {
        var height = 0;
        $('lightwindow_galleries_tab_span').className = 'up';
      }

      new Effect.Morph('lightwindow_galleries_list', {
        duration: this.duration,
        transition: Effect.Transitions.sinoidal,
        style: { height: height + 'px' },
        beforeStart: function() {
          $('lightwindow_galleries_list').setStyle({
            overflow: 'hidden'
          });
        },
        afterFinish: function() {
          $('lightwindow_galleries_list').setStyle({
            overflow: 'auto'
          });
        },
        queue: { position: 'end', scope: 'lightwindowAnimation' }
      });
    }


  },
  //
  //  Default Transition Handler
  //
  _defaultTransitionHandler: function() {
    // Clean out our effects
    this.dimensions.dataEffects = [];

    // Now that we have figures out the cruft lets make the caption go away and add its effects
    if ($('lightwindow_data_slide').getStyle('display') != 'none') {
      this.dimensions.dataEffects.push(
				new Effect.SlideUp('lightwindow_data_slide', { sync: true }),
				new Effect.Fade('lightwindow_data_slide', { sync: true, from: 1.0, to: 0.0 })
			);
    }

    if (!this.options.hideGalleryTab) {
      if ($('lightwindow_galleries').getHeight() != 0 && !this.options.hideGalleryTab) {
        this.dimensions.dataEffects.push(
					new Effect.Morph('lightwindow_galleries_tab_container', { sync: true, style: { height: '0px', marginTop: '20px'} })
				);
      }

      if ($('lightwindow_galleries_list').getHeight() != 0) {
        $('lightwindow_galleries_tab_span').className = 'up';
        this.dimensions.dataEffects.push(
					new Effect.Morph('lightwindow_galleries_list', {
					  sync: true,
					  style: { height: '0px' },
					  transition: Effect.Transitions.sinoidal,
					  beforeStart: function() {
					    $('lightwindow_galleries_list').setStyle({
					      overflow: 'hidden'
					    });
					  },
					  afterFinish: function() {
					    $('lightwindow_galleries_list').setStyle({
					      overflow: 'auto'
					    });
					  }
					})
				);
      }
    }

    // We always want the title bar as well
    this.dimensions.dataEffects.push(
			new Effect.Morph('lightwindow_title_bar_inner', { sync: true, style: { height: '0px', marginTop: this.options.dimensions.titleHeight + 'px'} }),
		 	new Effect.Fade('lightwindow_title_bar_inner', { sync: true, from: 1.0, to: 0.0 })
		);

    new Effect.Parallel(this.dimensions.dataEffects, {
      duration: this.duration,
      afterFinish: function() {
        this._loadWindow();
      } .bind(this),
      queue: { position: 'end', scope: 'lightwindowAnimation' }
    }
		);
  },
  //
  //	Default Form handler for LightWindow
  //
  _defaultFormHandler: function(e) {
    var element = Event.element(e).parentNode;
    var parameterString = Form.serialize(this._getParameter('lightwindow_form', element.getAttribute('params')));
    if (this.options.formMethod == 'post') {
      var newAJAX = new Ajax.Request(element.href, {
        method: 'post',
        postBody: parameterString,
        onComplete: this.openWindow.bind(this, element)
      });
    } else if (this.options.formMethod == 'get') {
      var newAJAX = new Ajax.Request(element.href, {
        method: 'get',
        parameters: parameterString,
        onComplete: this.openWindow.bind(this, element)
      });
    }
  },
  // 
  //  Wrap everything up
  //
  _finishWindow: function() {
    if (this.windowType == 'external') {
      // We set the externals source here because it allows for a much smoother animation
      $('lightwindow_iframe').setAttribute('src', this.element.href);
      this._handleFinalWindowAnimation(1);
    } else if (this.windowType == 'media') {

      var outerObject = document.createElement('object');
      outerObject.setAttribute('classid', this.options.classids[this._fileExtension(this.contentToFetch)]);
      outerObject.setAttribute('codebase', this.options.codebases[this._fileExtension(this.contentToFetch)]);
      outerObject.setAttribute('id', 'lightwindow_media_primary');
      outerObject.setAttribute('name', 'lightwindow_media_primary');
      outerObject.setAttribute('width', this.resizeTo.width);
      outerObject.setAttribute('height', this.resizeTo.height);
      outerObject = this._addParamToObject('movie', this.contentToFetch, outerObject);
      outerObject = this._addParamToObject('src', this.contentToFetch, outerObject);
      outerObject = this._addParamToObject('controller', 'true', outerObject);
      outerObject = this._addParamToObject('wmode', 'transparent', outerObject);
      outerObject = this._addParamToObject('cache', 'false', outerObject);
      outerObject = this._addParamToObject('quality', 'high', outerObject);

      if (!Prototype.Browser.IE) {
        var innerObject = document.createElement('object');
        innerObject.setAttribute('type', this.options.mimeTypes[this._fileExtension(this.contentToFetch)]);
        innerObject.setAttribute('data', this.contentToFetch);
        innerObject.setAttribute('id', 'lightwindow_media_secondary');
        innerObject.setAttribute('name', 'lightwindow_media_secondary');
        innerObject.setAttribute('width', this.resizeTo.width);
        innerObject.setAttribute('height', this.resizeTo.height);
        innerObject = this._addParamToObject('controller', 'true', innerObject);
        innerObject = this._addParamToObject('wmode', 'transparent', innerObject);
        innerObject = this._addParamToObject('cache', 'false', innerObject);
        innerObject = this._addParamToObject('quality', 'high', innerObject);

        outerObject.appendChild(innerObject);
      }

      if (this._getParameter('lightwindow_iframe_embed')) {
        this._appendIframe('no');
        this._writeToIframe(this._convertToMarkup(outerObject, 'object'));
      } else {
        this._appendObject(outerObject, 'object', $('lightwindow_contents'));
      }

      this._handleFinalWindowAnimation(0);
    } else {
      this._handleFinalWindowAnimation(0);
    }

    // Initialize any actions
    this._setupActions();
  }
}

/*-----------------------------------------------------------------------------------------------*/

Event.observe(window, 'load', lightwindowInit, false);

//
//	Set up all of our links
//
var myLightWindow = null;
function lightwindowInit() {
  myLightWindow = new lightwindow();
}