// 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 : 'http://i025.radikal.ru/0905/5c/7354f7b2b09d.png',
            presetImage : 'http://s41.radikal.ru/i093/0905/0a/fa6942d94e79.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" >cerrar</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="http://i081.radikal.ru/0905/01/8b77b6ae094a.gif" alt="loading" />'+
                        '<span>Actualmente cargando, o <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();
}
