// 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 : 200, width : 200},
                page : {height : 200, width : 200},
                inline : {height : 200, width : 200},
                media : {height : 200, width : 200},
                external : {height : 200, width : 200},
                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 : 'video/quicktime',
                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" class="lightwindow_container" >' +

                        '<div id="lightwindow_stage" >' +

                        '<div id="lightwindow_contents" >' +
                        '</div>' + '<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" ></a>' +
                        '</div>' +
                        '</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="loading" />' +
                        '<span>Loading or <a href="javascript: myLightWindow.deactivate();">Cancel</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 : true,
            hideGalleryTab : true,
            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,
            widthin : 'px',
            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;
            };
        }

        if ($('lightwindow_title_bar_close_link2')) {

            Event.observe('lightwindow_title_bar_close_link2', 'click', this.deactivate.bindAsEventListener(this));
            $('lightwindow_title_bar_close_link2').onclick = function() {
                return false;
            };
        }

        if ($('lightwindow_title_bar_close_link3')) {
            //alert('x');
            Event.observe('lightwindow_title_bar_close_link3', 'click', this.deactivate.bindAsEventListener(this));
            $('lightwindow_title_bar_close_link3').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) {
                $('lightwindow').setStyle({
                    position: 'absolute',
                    top: parseFloat($('lightwindow').getStyle('top')) + this.pagePosition.y + this.widthin,
                    left: parseFloat($('lightwindow').getStyle('left')) + this.pagePosition.x + this.widthin
                });
            } else {
                $('lightwindow').setStyle({
                    position: 'absolute'
                });
            }
        } else {

            if (this.windowActive) {
                this._getScroll();
                $('lightwindow').setStyle({
                    position: 'fixed',
                    top: parseFloat($('lightwindow').getStyle('top')) - this.pagePosition.y + this.widthin,
                    left: parseFloat($('lightwindow').getStyle('left')) - this.pagePosition.x + this.widthin
                });
            } 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')) + this.widthin : this.dimensions.viewport.height / 2 + 'px'),
                    left: (parseFloat(this._getParameter('lightwindow_left')) ? parseFloat(this._getParameter('lightwindow_left')) + this.widthin : 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;

        if (this._getParameter('lightwindow_widthin')) {
            this.widthin = this._getParameter('lightwindow_widthin');
        } else {
            this.widthin = 'px';
        }
        //alert(this.widthin);
        // 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 + this.widthin
        });

        $('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('style', 'float:left;margin:20px; border:1px solid red;');
        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 + 2;//+(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'
        });
        $('lightwindow_contents').setStyle({
            height: 'auto',
            // We need to set the width to a px not auto as opera has problems with it
            width: $('lightwindow_contents').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() {
    if (myLightWindow == null) {
        myLightWindow = new lightwindow();
    }
    else {
        myLightWindow._setupLinks();
    }
} 
