function debug(text) {
    ((window.console && console.log) ||
   (window.opera && opera.postError) ||
   window.alert).call(this, text);
}

/* jquery.wst.album.js (wstAlbumPopup & wstAlbum)
* Created by Aaron Silvas
* Copyright (c) 2009 GoDaddy.com
*/
;(function($) {

    /* TODO!!!
    IMPORTANT! This plugin is not ready for public consumption, still very much a work in progress.
    * Add support for any number of callers to wstAlbumPopup
    */

    $.fn.wstAlbumPopup = function(uri, options) {
        var defaults = {
            frameWidth: 15,
            autoShow: false,
            showClose: true /* close button */
        };

        var picsToLoad = null;
        if (options != null) {
            picsToLoad = options.picsToLoad;
            options.picsToLoad = null;
        }
        var settings = $.extend(true, defaults, options);
        if (options != null) {
            options.picsToLoad = picsToLoad;
        }
        settings.picsToLoad = picsToLoad;

        var root = $(this);
        var links = [];
        var viewWidth;
        var viewHeight;

        var overlayDom = $('#wst_album_popup_overlay', document);
        if (overlayDom.length == 0) {
            overlayDom = $(document.createElement('div'))
                .attr('id', 'wst_album_popup_overlay')
                .hide()
                .css({ 'height': screen.height + 'px' })
            ;

            $('body', document)
                .append(overlayDom)
            ;
        }
        var slideShowDom = $('#wst_album_popup', document);
        if (slideShowDom.length == 0) {
            slideShowDom = $(document.createElement('div'))
                .attr('id', 'wst_album_popup')
                .css({ /* 'height': (window.innerHeight != undefined ? window.innerHeight : document.body.clientHeight) + 'px', */'margin': settings.frameWidth + 'px'/*, 'overflow': 'visible'*/ })
                .hide()
            ;

            $('body', document)
                .append(slideShowDom)
            ;
        }
        if ($.browser.msie == true && $.browser.version <= 6) {
            // IE6 hack since it does not support fixed positioning. allowing the user to scroll is better than not working at all.
            overlayDom.css('position', 'absolute');
            slideShowDom.css('position', 'absolute');
        }

        function hidePopup() {
            slideShowDom.hide();
        }

        function showPopup(idx) {
            slideShowDom
                .show()
            ;

            overlayDom
                .show()
            ;

            var picsToLoad = null;
            picsToLoad = settings.picsToLoad;
            settings.picsToLoad = null;
            var revisedSettings = $.extend(true, {}, settings,
                {
                    imageHeight: null
                    , hideMenusDelay: 1000
                    , loadFullImages: true
                    , columns: 1
                    , moveFx: null
                    , shuffle: false
                    , slideShowContinuous: false
                    , imageClickBehavior: 'next'
                    , imagePadding: 0
                    , overlayMode: true
                    , thumbnails: false
                    , sliderBar: false
                    , menuPosition: 'bottom'
                    , menuCompact: false
                    , menuOffset: '0'
                    , bindKeys: true
                }
            );
            revisedSettings.picsToLoad = settings.picsToLoad = picsToLoad;

            if (settings.picIndexToSelect == null)
                revisedSettings.picIndexToSelect = idx;
            slideShowDom.wstAlbum(uri, revisedSettings);

            slideShowDom.focus();
        }

        if (settings.autoShow == true) {
            showPopup();
        }
        else {
            root.each(function() {
                var me = $(this);
                me.data('idx', links.length);
                links.push(links.length);
                var a = me.filter('a');
                if (a.length > 0)
                    a.attr('href', '#');

                me
                    .unbind('.wst_album_popup')
                    .bind('click.wst_album_popup', function(evt) {
                        showPopup(me.data('idx'));
                        evt.stopPropagation();
                        return false;
                    })
                ;
            })
            ;
        }
    }

    /* TODO!!!
    * BUG - Thumbnails in opera are not loading properly.
    * BUG - Delay effects based on diff between moveTime and fxTime. This will make more of the effect visible.
    * BUG - If applying changes to an existing album in client, while slideshow is in progress, it'll continue to consume those previous resources (and http requests). this is a low-priority issue as we do not currently allow reconfiguring on the fly anyway, this was done for demo purposes only.
    * Stylize the navigation, including buttons and whatever other graphics are desired.
    * Add zooming capability. This includes drag/panning of images via mouse. Only two states, normal, and max zoom (when can then be panned). This is enabled by using the option imageClickBehavior with value 'zoom'.
    * Add photo-feed-download-retry - If downloading the feed fails, post status, and continue to retry until available.
    * Add photo-download-retry - If downloading a photo fails, keep periodically retrying until available.
    * BUG - IE only - When navigating, the status does not update the photo index until the next time it shows. pretty big bug. (Low priority as it is currently disabled by default anyway)
    * WONT FIX - Fancybox does not work in IE8, unless in IE7 mode. Low priority due to workaround.
    */

    var runningAlbums = {};

    $.fn.wstAlbum = function(uri, options) {
        var allFx = 'blind, bounce, clip, drop, fold, puff, pulsate, scale, shake';
        var fxOptions = {
            'blind': { direction: 'vertical'} // http://docs.jquery.com/UI/Effects/Blind
            , 'bounce': { direction: 'up', distance: 50, times: 2} // http://docs.jquery.com/UI/Effects/Bounce
            , 'clip': { direction: 'vertical'} // http://docs.jquery.com/UI/Effects/Clip
            , 'drop': { direction: 'up'} // http://docs.jquery.com/UI/Effects/Drop
            , 'explode': { number: 9} // http://docs.jquery.com/UI/Effects/Explode
            , 'fold': {} // http://docs.jquery.com/UI/Effects/Fold
            , 'puff': { percent: 200} // http://docs.jquery.com/UI/Effects/Puff
            , 'pulsate': { times: 1} // http://docs.jquery.com/UI/Effects/Pulsate
            , 'scale': { percent: 100} // http://docs.jquery.com/UI/Effects/Scale
            , 'shake': { direction: 'left', distance: 50, times: 1} // http://docs.jquery.com/UI/Effects/Shake
            , 'slide': {} // http://docs.jquery.com/UI/Effects/Slide
        }

        var defaults = {
            dataType: 'xml', /* default is xml, but json is also supported */
            hideMenusDelay: 1000, /* the time in milliseconds of mouse inactivity before hiding the menus; null to disable */
            menuPosition: 'top', /* position supports 'bottom' or 'top' */
            menuFadeEnabled: true, /* if fade effect is not supported or desired, set to false to disable */
            menuCompact: false, /* set to true if you want to display compact menu instead of full */
            menuOffset: '0', /* offset of menu, if any (i.e. '-70px') */
            menuActivateFromAnywhere: false, /* if true, mouse movement from anywhere in document will activate menu. otherwise only movement within plugin will activate menu */
            fx: 'puff', /* null will use allFx, otherwise specify a comma-delimited string */
            fxShuffle: false, /* shuffles effects from fx selection */
            fxTime: 800, /* the time in milliseconds to complete each effect */
            moveTime: 500, /* the time in milliseconds to move to next location */
            moveFx: null, /* null indicates no effect. options are: slide */
            columns: 2, /* null is auto-fit, otherwise number of images shown at one time */
            imageHeight: 300, /* height, in pixels, of images -- or null to consume view height */
            wrap: true, /* allow wrapping */
            shuffle: false, /* shuffle/randomize image order */
            preload: 3, /* the number of images to preload that are not currently in view, in both directions */
            loadFullImages: false, /* if enabled, the full-sized images will be loaded instead of the 'large' ones */
            showStatus: false, /* shows status (current photo index) */
            titleShow: false, /* if true, a title will be displayed for the currently selected image */
            titlePosition: 'bottom', /* bottom or top */
            slideShowStart: false, /* auto-start slideshow upon load */
            slideShowDelay: 4000, /* delay, in milliseconds, between slides */
            slideShowContinuous: true, /* use continous slideshow, always moving */
            slideShowSpeeds: [{ text: 'Slow', speed: 6000 }, { text: 'Medium', speed: 4000 }, { text: 'Fast', speed: 2000}],
            thumbnails: true, /* show thumbnails for navigation */
            thumbnailsPosition: 'bottom', /* position of thumbnails, bottom or top */
            thumbnailsSize: 90, /* size of each thumbnail, x * x */
            sliderBar: true, /* show slider bar or not for navigation */
            sliderPosition: 'bottom', /* position of slider bar, bottom or top */
            sliderSize: 8, /* size of the sliders height, in pixels */
            borderWidth: 2, /* border width, in pixels */
            xPadding: 3, /* pixel padding between images */
            imagePadding: 2, /* padding around image, in pixels */
            imageClickBehavior: 'popup', /* options include: 'fancybox', 'popup', 'next', 'hide', 'zoom', or null to do nothing */
            overlayMode: false, /* if in overlay mode, certain visuals will be stylized differently for sake of being on top an overlay */
            picsToLoad: null, /* an array of pic objects (url, smallUrl, largeUrl, title) can be passed in if you wish to load raw data instead of async by uri */
            picIndexToSelect: 0, /* this is the initial picture index to select */
            bindKeys: false, /* if true, binds all supported keyboard input (esc=close, left=prev, right=next). */
            menuExtension: null, /* if specified, the given html will be injected into the right-side of the menu, right before the close button (if there is one) */
            menuExtensionPosition: null, /* if null will be attached to existing menu, otherwise will be injected to the desired location (topleft, topright, bottomleft, bottomright) */
            onClose: null, /* optional event handler if the caller wishes to perform an action before the popup is closed. if false is returned from the callback then the action will be halted (no close will take place) */
            afterClose: null, /* optional event handler if the caller wishes to perform an action after the popup is closed */
            onClick: null, /* optional event handler if the caller wishes to perform an action at the time an image is clicked. If false is returned, no further action will be performed. */
            onPlay: null, /* upon slideshow play, this event handler will be called */
            onPause: null, /* upon slideshow pause, this event handler will be called */
            onChange: null, /* optional event handler if the caller wishes to perform an action at the time an image changes. */
            onLoad: null /* once the plugin is fully ready and loaded this callback will be invoked */
        };

        var picsToLoad = null;
        if (options != null) {
            picsToLoad = options.picsToLoad;
            options.picsToLoad = null;
        }
        var settings = $.extend(true, defaults, options);
        if (options != null) {
            options.picsToLoad = picsToLoad;
        }
        settings.picsToLoad = picsToLoad;

        if (typeof settings.fxTime == "string")
            settings.fxTime *= 1; // convert to int
        if (typeof settings.moveTime == "string")
            settings.moveTime *= 1; // convert to int
        if (typeof settings.columns == "string") {
            if (settings.columns.length == 0)
                settings.columns = null;
            else
                settings.columns *= 1; // convert to int
        }
        if (typeof settings.imageHeight == "string")
            settings.imageHeight *= 1; // convert to int
        if (typeof settings.preload == "string")
            settings.preload *= 1; // convert to int
        if (typeof settings.slideShowDelay == "string")
            settings.slideShowDelay *= 1; // convert to int
        if (typeof settings.thumbnailsSize == "string")
            settings.thumbnailsSize *= 1; // convert to int
        if (typeof settings.borderWidth == "string")
            settings.borderWidth *= 1; // convert to int
        if (typeof settings.xPadding == "string")
            settings.xPadding *= 1; // convert to int
        if (typeof settings.imagePadding == "string")
            settings.imagePadding *= 1; // convert to int
        if (settings.fx == null)
            settings.fx = allFx;

        var me = $(this);

        var meId = me.attr('id');
        if (meId == null || meId.length == 0) {
            meId = 'wstAlbum' + Math.round(Math.random() * 65535);
            me.attr('id', meId);
        }

        var locals = runningAlbums[meId];
        if (locals != null) {
            return locals.fn(locals, uri, settings);
        }

        locals = runningAlbums[meId] = { me_this: this, fn: function(locals, uri, settings) {
            locals.me = $(locals.me_this);
            locals.meId = locals.me.attr('id');
            switch (uri.toLowerCase()) {
                case 'play':
                    slideShowStart();
                    return locals.me;
                case 'pause':
                    slideShowStop();
                    return locals.me;
                case 'isplaying':
                    return locals.slideShowPlaying;
                case 'getspeed':
                    return locals.settings.slideShowDelay;
                case 'piccount':
                    return locals.pics.length;
                case 'getpics':
                    return locals.pics;
                case 'goto':
                    if (settings.picIndexToSelect < 0 || settings.picIndexToSelect >= locals.pics.length)
                        return locals.me;
                    locals.picIndex = settings.picIndexToSelect;
                    render();
                    return locals.me;
                case 'dump':
                    return locals;
            };
            destroy(locals);
            if (uri.toLowerCase() == 'destroy') {
                delete runningAlbums[locals.meId];
                return locals.me;
            }

            locals.me = $('#' + locals.meId); // sometimes the older me pointer we hold onto is actually gone due to other software deleting us
            locals.meBody = locals.me.parent('body');
            locals.meParent = locals.me.parent();

            locals.settings = settings;

            locals.pics = [];
            locals.resources = [];
            locals.picsXml = null;
            locals.picIndex = 0;
            locals.lastPic = null;
            locals.fxSpeed = locals.settings.fxTime; // set initial speed
            locals.slideSpeed = locals.settings.moveTime;
            locals.slideShowPlaying = false;
            locals.slideShowTimer = null;
            locals.imageWidth = 1800;
            locals.imageHeight = (locals.settings.imageHeight != null ? locals.settings.imageHeight : 100);
            locals.imagesInView = 3;
            locals.thumbsInView = 10;
            locals.fxIndex = 0;
            locals.fxList = locals.settings.fx.split(',');
            locals.useFullSize = false;
            locals.loadIndex = 0;
            locals.maxWidth;
            locals.innerHeight = 100;
            locals.innerWidth = locals.me.innerWidth();
            locals.thumbsWidth;
            locals.SIG = Math.round(Math.random() * 100);
            locals.isLoaded = false;
            locals.resumeSlideshow = false;
            locals.picsLoading = 0;
            locals.picsLoaded = 0;
            locals.isReady = false;
            locals.sliderWidth = 1;
            locals.sliderViewWidth = 1;
            locals.sliderPxPerPic = 1;
            locals.sliderPos = 0;
            locals.sliderMoving = false;
            locals.imagePadding = locals.settings.imagePadding * 2;
            locals.hideMenusTimer = null;
            locals.menusVisible = false;
            locals.thumbs = null;
            locals.thumbnails = null;

            locals.originalOverflow = locals.meBody.css('overflow');
            locals.originalOverflowX = locals.meBody.css('overflow-x');
            locals.originalOverflowY = locals.meBody.css('overflow-y');

            if (locals.settings.overlayMode == true) {
                locals.meBody.css({ 'overflow': 'hidden', 'overflow-x': 'hidden', 'overflow-y': 'hidden' });
            }

            // initialize container, etc
            locals.container = $(document.createElement('div'))
                    .addClass('container')
                ;
            locals.menu_left = $(document.createElement('div'))
                    .css({ 'height': (locals.imageHeight + locals.settings.borderWidth) + 'px' })
                    .addClass('menu_left')
                ;
            locals.menu_right = $(document.createElement('div'))
                    .css({ 'height': (locals.imageHeight + locals.settings.borderWidth) + 'px' })
                    .addClass('menu_right')
                ;
            locals.menu_width = 0;
            locals.nav_bar_active = false;
            locals.menu = $(document.createElement('div'))
                    .hide()
                    .addClass(locals.settings.menuCompact ? 'menu_sm' : 'menu')
                    .css(locals.settings.menuPosition, locals.settings.menuOffset)
                    .mouseover(function() { locals.nav_bar_active = true; })
                    .mouseout(function() { locals.nav_bar_active = false; })
                ;
            locals.menu_overlay = $(document.createElement('div'))
                    .hide()
                    .addClass(locals.settings.menuCompact ? 'menu_overlay_sm' : 'menu_overlay')
                    .css(locals.settings.menuPosition, locals.settings.menuOffset)
                ;
            locals.container_parent = $(document.createElement('div'))
                    .addClass('container_parent')
                   .append(locals.container)
                ;
            locals.main = $(document.createElement('div'))
                    .addClass('main')
                ;
            locals.statusBar = $(document.createElement('div')).addClass('status');
            locals.slideShowBar = $(document.createElement('span'));
            locals.sliderMouseDown = false;
            locals.sliderMovePos = null;
            locals.sliderMovePicIndex = 0;
            locals.sliderView = (locals.settings.sliderBar == true ? $(document.createElement('div'))
                    .addClass('slider_view')
                    .css('height', locals.settings.sliderSize + 'px')
                    : null)
                ;

            function sliderMovingCallback() {
                preload(true);
            }

            locals.sliderMovingTimer = null;
            locals.sliderBar = (locals.settings.sliderBar == true ? $(document.createElement('div'))
                    .css('height', (locals.settings.sliderSize + 2) + 'px')
                    .append(locals.sliderView)
                    .addClass('slider')
            /*                .css('height', settings.sliderSize + 'px') */
                    .mouseover(function() {
                        $(this).addClass('slider_hover');
                    })
                    .mouseout(function() {
                        $(this).removeClass('slider_hover');
                    })
                    .mousedown(function(e) {
                        locals.sliderMouseDown = true;
                        locals.sliderMovePos = e.clientX;
                        locals.sliderMoving = true;

                        var oleft = $(this).offset().left
                        locals.sliderMovePicIndex = Math.round((e.clientX - oleft) / locals.sliderPxPerPic);
                        if (locals.sliderMovePicIndex < 0)
                            locals.sliderMovePicIndex = 0;
                        else if (locals.sliderMovePicIndex >= (locals.pics.length - 1))
                            locals.sliderMovePicIndex = locals.pics.length - 1;

                        if (locals.sliderMovePicIndex != locals.picIndex) {
                            locals.picIndex = locals.sliderMovePicIndex;
                            render();
                        }

                        if (locals.sliderMovingTimer != null) {
                            clearInterval(locals.sliderMovingTimer);
                        }
                        locals.sliderMovingTimer = setInterval(sliderMovingCallback, 800);

                        function me_mouse_move(e) {
                            if (locals.sliderMouseDown == false)
                                return; // ignore if not dragging
                            if (Math.abs(e.clientX - locals.sliderMovePos) < 2)
                                return; // we require a movement more than the tolerance for sake user "shakyness"
                            // determine new pic index
                            var picOffset = Math.floor((e.pageX - locals.sliderMovePos) / locals.sliderPxPerPic);
                            var newPicIndex = locals.sliderMovePicIndex + picOffset;
                            if (newPicIndex < 0)
                                newPicIndex = 0;
                            else if (newPicIndex >= (locals.pics.length - 1))
                                newPicIndex = locals.pics.length - 1;
                            if (newPicIndex == locals.picIndex)
                                return; // nothing more to do

                            if (locals.sliderMovingTimer != null) {
                                clearInterval(locals.sliderMovingTimer);
                            }
                            locals.sliderMovingTimer = setInterval(sliderMovingCallback, 500);

                            locals.picIndex = newPicIndex;

                            render();
                        }

                        locals.me
                            .mouseup(function() {
                                locals.sliderMouseDown = false;
                                locals.sliderMovePos = null;
                                locals.sliderMoving = false;

                                locals.me.unbind('mouseup').unbind('mousemove', me_mouse_move);

                                if (locals.sliderMovingTimer != null) {
                                    clearInterval(locals.sliderMovingTimer);
                                    locals.sliderMovingTimer = null;
                                }

                                preload();
                            })
                            .mousemove(me_mouse_move)
                        ;
                    })
                    : null)
                ;

            locals.loadingPanel = $(document.createElement('div'))
                    .addClass('loading')
                    .html('Loading...')
                ;

            if (locals.settings.thumbnails == true) {
                locals.thumbs = $(document.createElement('div'))
                        .addClass('thumbs_container')
                        .css({ left: '0px', top: '0px', 'height': (locals.settings.thumbnailsSize + locals.settings.borderWidth + 1) + 'px' })
                    ;
                locals.thumbsParent = $(document.createElement('div'))
                        .addClass('thumbs_container_parent')
                        .css({ 'height': (locals.settings.thumbnailsSize + locals.settings.borderWidth + 1) + 'px' })
                        .append(locals.thumbs)
                    ;
                if (locals.settings.overlayMode == true)
                    locals.thumbsParent.css('background-color', '#000');
            }

            locals.titleBar = (locals.settings.titleShow == true ? $('<div class="title_bar">&nbsp;</div>') : null);

            if (locals.titleBar != null && locals.settings.titlePosition == 'top')
                locals.main.append(locals.titleBar);

            if (locals.sliderBar != null && locals.settings.sliderPosition == 'top')
                locals.main.append(locals.sliderBar);

            if (locals.thumbs != null && locals.settings.thumbnailsPosition == 'top')
                locals.main.append(locals.thumbsParent);

            locals.main
                    .append(locals.loadingPanel)
                    .append(locals.menu)
                    .append(locals.menu_overlay)
                    .append(locals.container_parent)
                ;

            if (locals.thumbs != null && locals.settings.thumbnailsPosition != 'top')
                locals.main.append(locals.thumbsParent);

            if (locals.sliderBar != null && locals.settings.sliderPosition != 'top')
                locals.main.append(locals.sliderBar);

            if (locals.titleBar != null && locals.settings.titlePosition != 'top')
                locals.main.append(locals.titleBar);

            locals.me
                    .empty()
                    .show()
                    .addClass('wst_album')
                    .append(locals.main)
                ;

            function navPrev(forceWrap) {
                if (locals.picIndex > 0)
                    locals.picIndex--;
                else if (locals.settings.wrap == true || forceWrap == true)
                    locals.picIndex = (locals.pics.length - 1);

                render();
            }

            function navNext(forceWrap) {
                if (locals.picIndex < (locals.pics.length - 1))
                    locals.picIndex++;
                else if (locals.settings.wrap == true || forceWrap == true)
                    locals.picIndex = 0;

                render();
            }

            function navFirst() {
                locals.picIndex = 0;

                render();
            }

            function navLast() {
                locals.picIndex = locals.pics.length - 1;

                render();
            }

            function closePopup() {
                if ($.isFunction(locals.settings.onClose) == true) {
                    if (locals.settings.onClose(locals.me) == false)
                        return; // ignore close event if caller does not allow it
                }

                destroy(locals);
                $('#wst_album_popup', document).hide();
                $('#wst_album_popup_overlay', document).hide();
                if ($.isFunction(locals.settings.afterClose) == true)
                    locals.settings.afterClose(locals.me);
            }

            locals.menu
                    .append(
                        $(document.createElement('div'))
                            .addClass(locals.settings.menuCompact ? 'nav_prev_sm' : 'nav_prev')
                            .addClass('nav_opac')
                            .hide()
                            .mouseover(function() {
                                $(this).removeClass('nav_opac');
                            })
                            .mouseout(function() {
                                $(this).addClass('nav_opac');
                            })
                            .click(function() {
                                navPrev();
                            })
                    )
                    .append($(document.createElement('div'))
                        .addClass(locals.settings.menuCompact ? 'nav_play_sm' : 'nav_play')
                        .addClass('nav_opac')
                        .hide()
                        .mouseover(function() {
                            $(this).removeClass('nav_opac');
                        })
                        .mouseout(function() {
                            $(this).addClass('nav_opac');
                        })
                        .click(function() {
                            slideShowStart();
                        })
                    )
                    .append($(document.createElement('div'))
                        .addClass(locals.settings.menuCompact ? 'nav_pause_sm' : 'nav_pause')
                        .addClass('nav_opac')
                        .hide()
                        .mouseover(function() {
                            $(this).removeClass('nav_opac');
                        })
                        .mouseout(function() {
                            $(this).addClass('nav_opac');
                        })
                        .click(function() {
                            slideShowStop();
                        })
                    )
                    .append(
                        $(document.createElement('div'))
                            .addClass(locals.settings.menuCompact ? 'nav_next_sm' : 'nav_next')
                            .addClass('nav_opac')
                            .hide()
                            .mouseover(function() {
                                $(this).removeClass('nav_opac');
                            })
                            .mouseout(function() {
                                $(this).addClass('nav_opac');
                            })
                            .click(function() {
                                navNext();
                            })
                    )
                ;

            locals.menu
                    .append(locals.statusBar)
                ;

            if (locals.menu_left.children().length == 0) {
                //locals.menu_left.css('width', '1px');
                locals.menu_left.remove();
                locals.menu_left = null;
                locals.menu_right.remove();
                locals.menu_right = null;
            }

            function resGet(heightReq, minIndex) {
                if (minIndex == null)
                    minIndex = 0;
                var resI;
                for (resI = minIndex; resI < locals.resources.length; resI++) {
                    var res = locals.resources[resI];
                    if (res.height == null || res.height >= heightReq) { // height is not yet determined or height is of sufficient size
                        if (minIndex > 0 && resI == minIndex) {
                            // if we require a min index, check to see if the previous size was already sufficient
                            var prevRes = locals.resources[minIndex - 1];
                            if (prevRes.height != null && prevRes.height >= heightReq)
                                return null; // previous resource was already of sufficient size
                        }
                        return res;
                    }
                }

                return locals.resources[locals.resources.length - 1];
            }

            function resGetPicUrl(pic, heightReq, minIndex) {
                var res = resGet(heightReq, minIndex);
                if (res == null)
                    return null;
                if (res.index > (pic.res.length - 1))
                    return pic.res[pic.res.length - 1].url;
                return pic.res[res.index].url;
            }

            function resPicFindIndex(pic, url) {
                var resI;
                for (resI = 0; resI < pic.res.length; resI++) {
                    if (pic.res[resI].url == url)
                        return resI;
                }
            }

            function resUpdateCache(resIndex, heightFetched) {
                var res = locals.resources[resIndex];
                if (res == null)
                    return;
                if (res.height == null || res.height < heightFetched) {
                    //debug('res ' + resIndex + ' updated from ' + res.height + ' to ' + heightFetched);
                    res.height = heightFetched;
                }
            }

            function slideShowStop(doNotTriggerEvent) {
                if (locals.slideShowPlaying == true && doNotTriggerEvent != true && $.isFunction(locals.settings.onPause) == true) {
                    locals.settings.onPause(locals.me);
                }

                if (locals.slideShowTimer != null) {
                    clearInterval(locals.slideShowTimer);
                    locals.slideShowTimer = null;
                }

                locals.fxSpeed = locals.settings.fxTime;
                locals.slideSpeed = locals.settings.moveTime;

                $('.nav_pause,.nav_pause_sm', locals.menu).hide();
                $('.nav_play,.nav_play_sm', locals.menu).show();

                locals.container.stop(true, false);
                if (locals.thumbs != null)
                    locals.thumbs.stop(true, false);
                if (locals.sliderView != null)
                    locals.sliderView.stop(true, false);

                locals.slideShowPlaying = false;
            }

            function slideShowCallback() {
                try {
                    var nextPic = 0;
                    if (locals.picIndex < (locals.pics.length - 1))
                        nextPic = locals.picIndex + 1;
                    else if (locals.settings.wrap == true)
                        nextPic = 0;
                    var pic = locals.pics[nextPic];
                    if (pic == null)
                        return;
                    if (pic.imgDomLoad != null) { // still loading
                        if (locals.slideShowPlaying == true && locals.slideShowTimer != null) { // pause slideshow
                            clearInterval(locals.slideShowTimer);
                            locals.slideShowTimer = null;
                        }

                        locals.loadingPanel.show();

                        return;
                    }

                    navNext();
                } catch (e) { // fixes a unique case where 'me' is reset as a new control while slideshow is still going on
                    slideShowStop();
                }
            }

            function slideShowStart(delayMove, doNotTriggerEvent) {
                /*if (menusVisible == true && slideShowTimer == null) {
                menusVisible = false;
                menu.hide();
                menu_overlay.hide();
                }*/

                if (locals.slideShowPlaying == false && doNotTriggerEvent != true && $.isFunction(locals.settings.onPlay) == true) {
                    locals.settings.onPlay(locals.me);
                }

                slideShowStop((locals.slideShowPlaying == true));

                locals.slideShowPlaying = true;

                locals.slideSpeed = locals.settings.slideShowDelay;
                locals.slideShowTimer = setInterval(slideShowCallback, locals.slideSpeed);
                if (delayMove == true) {
                    render();
                }
                else {
                    slideShowCallback();
                }

                $('.nav_play,.nav_play_sm', locals.menu).hide();
                $('.nav_pause,.nav_pause_sm', locals.menu).show();
            }

            locals.speedController = $(document.createElement('div'))
                    .addClass(locals.settings.menuCompact ? 'nav_speed_ctrl_sm' : 'nav_speed_ctrl')
                ;

            locals.speedControllerParent = $(document.createElement('div'))
                    .addClass(locals.settings.menuCompact ? 'nav_speed_ctrl_parent_sm' : 'nav_speed_ctrl_parent')
                    .append($(document.createElement('div'))
                        .addClass(locals.settings.menuCompact ? 'nav_speed_ctrl_left_sm' : 'nav_speed_ctrl_left')
                    )
                    .append(locals.speedController)
                    .append($(document.createElement('div'))
                        .addClass(locals.settings.menuCompact ? 'nav_speed_ctrl_right_sm' : 'nav_speed_ctrl_right')
                    )
                    .hide()
                ;

            locals.menu
                    .append(locals.speedControllerParent)
                ;

            locals.menu_extension = null;
            if (locals.settings.menuExtension != null) {
                locals.menu_extension = $(document.createElement('div'))
                        .addClass(locals.settings.menuCompact ? 'nav_extension_sm' : 'nav_extension')
                        .append(locals.settings.menuExtension)
                    ;

                switch (locals.settings.menuExtensionPosition) {
                    case "topleft":
                        locals.menu_extension
                                .css({ 'position': 'absolute', 'float': 'none', 'left': '0px', 'top': '0px' })
                            ;
                        locals.main
                                .append(locals.menu_extension)
                            ;
                        break;
                    case "topright":
                        locals.menu_extension
                                .css({ 'position': 'absolute', 'float': 'none', 'right': '0px', 'top': '0px' })
                            ;
                        locals.main
                                .append(locals.menu_extension)
                            ;
                        break;
                    case "bottomleft":
                        locals.menu_extension
                                .css({ 'position': 'absolute', 'top': 'auto', 'float': 'none', 'left': '0px', 'bottom': '0px' })
                            ;
                        locals.main
                                .append(locals.menu_extension)
                            ;
                        break;
                    case "bottomright":
                        locals.menu_extension
                                .css({ 'position': 'absolute', 'top': 'auto', 'float': 'none', 'right': '0px', 'bottom': '0px' })
                            ;
                        locals.main
                                .append(locals.menu_extension)
                            ;
                        break;
                    default:
                        locals.menu
                                .append(locals.menu_extension)
                            ;
                        break;
                }
            }

            if (locals.settings.showClose == true) {
                locals.menu
                        .append(
                        $(document.createElement('div'))
                            .addClass(locals.settings.menuCompact ? 'nav_close_sm' : 'nav_close')
                            .addClass('nav_opac')
                            .mouseover(function() {
                                $(this).removeClass('nav_opac');
                            })
                            .mouseout(function() {
                                $(this).addClass('nav_opac');
                            })
                            .click(function(evt) {
                                evt.stopPropagation();
                                closePopup();
                                return false;
                            })
                        )
                    ;
            }

            var first = true;
            for (i = 0; i < locals.settings.slideShowSpeeds.length; i++) {
                locals.speed = locals.settings.slideShowSpeeds[i];
                if (first == true) {
                    first = false;
                }
                else {
                    locals.speedController.append($(document.createElement('div')).text(' ').addClass(locals.settings.menuCompact ? 'nav_speed_seperator_sm' : 'nav_speed_seperator'));
                }
                var ss_item = $(document.createElement('span'))
                        .data('speed', locals.speed)
                        .html(locals.speed.text)
                        .click(function() {
                            var new_speed = $(this).data('speed');
                            locals.settings.slideShowDelay = new_speed.speed;
                            slideShowStart();
                            $('.nav_speed_active_setting,.nav_speed_active_setting_sm', locals.speedController)
                                .removeClass(locals.settings.menuCompact ? 'nav_speed_active_setting_sm' : 'nav_speed_active_setting')
                                .addClass(locals.settings.menuCompact ? 'nav_speed_setting_sm' : 'nav_speed_setting')
                            ;
                            $(this).addClass(locals.settings.menuCompact ? 'nav_speed_active_setting_sm' : 'nav_speed_active_setting');

                            return false;
                        })
                    ;
                if (locals.speed.speed == locals.settings.slideShowDelay) {
                    ss_item.addClass(locals.settings.menuCompact ? 'nav_speed_active_setting_sm' : 'nav_speed_active_setting');
                }
                else {
                    ss_item.addClass(locals.settings.menuCompact ? 'nav_speed_setting_sm' : 'nav_speed_setting');
                }
                locals.speedController.append(ss_item);
            }

            function updatePicImage(data) {
                var pic = data;
                if (pic.imgDom == null)
                    return;

                if (pic.origW == null) {
                    pic.origW = pic.imgDom.width();
                    pic.origH = pic.imgDom.height();
                }
                //debug('updatePicImage: ' + pic.index + ' ' + pic.origW + 'x' + pic.origH);

                // calc new width/height
                var w = pic.origW;
                var h = pic.origH;
                var ar = w / h;
                var arH = h / w;
                if (h > (locals.imageHeight - locals.imagePadding)) {
                    h = (locals.imageHeight - locals.imagePadding);
                    w = Math.round(h * ar);
                }

                //  center the image vertically/horizontally with its parent

                if (locals.settings.columns == null) {
                    if (w > (locals.imageWidth - locals.imagePadding) || locals.imageWidth == 1800) {
                        // adjust all widths
                        locals.imageWidth = w + locals.imagePadding;

                        resizeAsync();
                    }
                }
                else if (w > (locals.imageWidth - locals.imagePadding)) { // width is greater than allowed, resize
                    w = (locals.imageWidth - locals.imagePadding);
                    h = Math.round(w * arH);
                }

                //console.log(SIG + '] preloadCalback index: ' + pic.index + ' ' + w + 'x' + h + ' (Original: ' + pic.origW + 'x' + pic.origH + ')');

                pic.width = w;
                pic.height = h;
                pic.left = Math.floor((locals.imageWidth - (pic.width + locals.imagePadding)) / 2);
                pic.top = Math.floor((locals.imageHeight - (pic.height + locals.imagePadding)) / 2);

                // ok, finally, lets init image
                pic.imgDom
                //                    .css({ 'left': pic.left + 'px', 'top': pic.top + 'px' })
                        .attr({ 'width': pic.width, 'height': pic.height })
                    ;
                pic.frameDom
                        .css({ 'left': pic.left + 'px', 'top': pic.top + 'px', 'width': (pic.width + 0) + 'px', 'height': (pic.height + 0) + 'px' })
                //debug('updatePicImage: ' + pic.index + ' ' + pic.width + 'x' + pic.height + ' END');
                    ;
            }

            function updateMenu(force_update) {
                var newMenuWidth = locals.menu.outerWidth(true);
                if (force_update == true || (locals.innerWidth > 0 && newMenuWidth > 0 && locals.menu_width != newMenuWidth)) {
                    //console.log('updateMenu: menu_width: ' + newMenuWidth + ' (old: ' + menu_width + '), innerWidth: ' + innerWidth);
                    locals.menu_width = newMenuWidth;
                    locals.menu.css('left', Math.round((locals.innerWidth - locals.menu_width) / 2) + 'px');
                    locals.menu_overlay.css({ 'left': Math.round((locals.innerWidth - locals.menu_width) / 2) + 'px', 'width': locals.menu_width + 'px' });
                    //loadingPanel.css({ 'left': Math.round((innerWidth - loadingPanel.outerWidth(true)) / 2) + 'px', 'top': Math.round((innerHeight - loadingPanel.outerHeight(true)) / 2) + 'px' });
                    if (locals.menu_extension != null && $.browser.msie == true && $.browser.version == 6) { // IE6 HACK... IE6 gets confused and forgets to reposition absolute content when its parent changes size
                        locals.menu_extension.attr('style', locals.menu_extension.attr('style'));
                    }
                }
            }

            locals.lastImageWidth = 0;
            function resize() {
                var newInnerWidth = locals.me.innerWidth();
                if (newInnerWidth <= 0 || locals.pics.length == 0) {
                    return; // not yet ready
                }

                var heightChanged = false;
                if (locals.settings.imageHeight == null) { // recalc image height
                    var newImageHeight = /*$(document).height() - */(window.innerHeight != undefined ? window.innerHeight : document.body.clientHeight) - locals.settings.frameWidth/* - imagePadding*/;
                    //console.log('newImageHeight: ' + newImageHeight + ' document.body.clientHeight:' + (window.innerHeight != undefined ? window.innerHeight : document.body.clientHeight));
                    //if (menu_options != null)
                    //newImageHeight -= menu_options.outerHeight(true);
                    //console.log('newImageHeight: ' + newImageHeight + ' document.body.clientHeight:' + (window.innerHeight != undefined ? window.innerHeight : document.body.clientHeight));
                    if (locals.thumbs != null)
                        newImageHeight -= locals.thumbs.outerHeight(true);
                    //console.log('newImageHeight: ' + newImageHeight + ' document.body.clientHeight:' + (window.innerHeight != undefined ? window.innerHeight : document.body.clientHeight));
                    if (locals.sliderBar != null)
                        newImageHeight -= locals.sliderBar.outerHeight(true);
                    if (locals.titleBar != null)
                        newImageHeight -= locals.titleBar.outerHeight(true);
                    //console.log('newImageHeight: ' + newImageHeight + ' document.body.clientHeight:' + (window.innerHeight != undefined ? window.innerHeight : document.body.clientHeight));
                    if (newImageHeight != locals.imageHeight) { // if changed, handle it
                        locals.imageHeight = newImageHeight;
                        for (i = 0; i < locals.pics.length; i++) {
                            var pic = locals.pics[i];
                            pic.dom
                                    .css('height', locals.imageHeight + 'px')
                                ;
                        }

                        heightChanged = true;
                        reload();
                    }
                }

                //newInnerWidth -= (settings.borderWidth + sideMenusWidth);
                if (heightChanged == false && newInnerWidth == locals.innerWidth && lastImageWidth == locals.imageWidth) {
                    updateMenu();
                    return; // nothing more to do
                }

                lastImageWidth = locals.imageWidth;
                locals.innerWidth = newInnerWidth;
                locals.innerHeight = locals.me.innerHeight();
                locals.thumbsWidth = newInnerWidth;

                updateMenu(true);

                if (locals.settings.columns != null) {
                    locals.imageWidth = Math.floor(((newInnerWidth - ((locals.settings.columns - 1) * locals.settings.xPadding)/* - imagePadding*/)) / locals.settings.columns);
                }

                //console.log(SIG + '] resize START innerWidth: ' + innerWidth + ' padding: ' + imagePadding);

                for (i = 0; i < locals.pics.length; i++) {
                    var pic = locals.pics[i];
                    pic.dom.css({ 'left': (i * (locals.imageWidth + locals.settings.xPadding + locals.settings.borderWidth)) + 'px', 'width': locals.imageWidth + 'px' });
                    updatePicImage(pic);
                }

                locals.container_parent
                        .css({ /*'width': innerWidth + 'px', */'height': (locals.imageHeight + locals.settings.borderWidth) + 'px' })
                    ;

                locals.maxWidth = (locals.pics.length * (locals.imageWidth + locals.settings.xPadding + locals.settings.borderWidth));
                locals.container.css('width', locals.maxWidth + 'px');
                if (locals.thumbs != null) {
                    locals.maxThumbWidth = (locals.pics.length * (locals.settings.thumbnailsSize + locals.settings.xPadding + locals.settings.borderWidth));
                    locals.thumbsParent.css('width', locals.thumbsWidth + 'px');
                    locals.thumbs.css('width', locals.maxThumbWidth + 'px');
                }

                //console.log(SIG + '] resize END innerWidth: ' + innerWidth + ' maxWidth: ' + maxWidth);

                if (locals.sliderBar != null) {
                    locals.sliderWidth = locals.sliderBar.width();
                    if (locals.maxWidth > 0)
                        locals.sliderViewWidth = Math.ceil((newInnerWidth / locals.maxWidth) * locals.sliderWidth);
                    else
                        locals.sliderViewWidth = 20;
                    locals.sliderView
                            .css('width', locals.sliderViewWidth + 'px')
                        ;
                    if (locals.pics.length > 0) {
                        locals.sliderPxPerPic = locals.sliderWidth / locals.pics.length;
                    }
                    else {
                        locals.sliderPxPerPic = locals.sliderWidth;
                    }
                }

                if (locals.isReady == false) {
                    locals.isReady = true;

                    locals.loadingPanel
                            .css({ 'margin-left': (Math.round(locals.loadingPanel.outerWidth() / 2) * -1) + 'px', 'margin-top': (Math.round(locals.loadingPanel.outerHeight() / 2) * -1) + 'px' })
                        ;

                    // following commented lines were deemed no longer needed. pending removal unless bug crops up as a result of this change
                    //lastImageWidth = 0; // required to force refresh
                    //resize(); // call one last time
                    //return;
                }

                render();
            }

            locals.resizeAsyncTimer = null;
            function resizeAsync() {
                if (locals.resizeAsyncTimer != null) {
                    clearTimeout(locals.resizeAsyncTimer);
                }

                locals.resizeAsyncTimer = setTimeout(resize, 100);
            }

            function updateStatus(explicitStatus) {
                var pic = locals.pics[locals.picIndex];
                if (pic != null && pic.imgDom == null) {
                    locals.loadingPanel.show();
                }
                else {
                    locals.loadingPanel.hide();
                }

                if (explicitStatus != null) {
                    locals.statusBar.html(explicitStatus);

                    updateMenu();

                    return;
                }

                if (locals.isLoaded == false || locals.pics.length == 0) {
                    updateMenu();

                    return;
                }

                if (locals.settings.showStatus == false)
                    return;

                locals.statusBar.html('Photo ' + (locals.picIndex + 1) + ' of ' + locals.pics.length);

                updateMenu();
            }

            function preloadCallback(evt) {
                var o = null;
                if (evt.target == null)
                    o = evt;
                else
                    o = $(evt.target);

                idx = o.data('pic');
                var pic = locals.pics[idx];
                if (pic == null || pic.imgDomLoad == null) {
                    //debug('preloadCallback FAILED for idx: ' + idx + ' evnt: ' + evt.target);
                    return;
                }

                locals.picsLoaded++;
                locals.picsLoading--;

                if (locals.isLoaded == false && locals.picsLoading == 0) {
                    locals.isLoaded = true;
                    $('.nav_prev,.nav_play,.nav_next,.nav_speed_ctrl_parent,.nav_prev_sm,.nav_play_sm,.nav_next_sm,.nav_speed_ctrl_parent_sm', locals.menu).show();
                    if (locals.settings.showStatus == false) {
                        locals.statusBar.remove();
                    }
                    if (locals.settings.slideShowStart == true) {
                        slideShowStart(true);
                    }

                    if ($.browser.msie == true && $.browser.version < 9) {
                        locals.menu.pngFix();
                    }

                    if ($.isFunction(locals.settings.onLoad) == true) {
                        locals.settings.onLoad(locals.me);
                    }

                    updateMenu(true);

                    showMenu();

                    resizeAsync(); // reformat based on menu updates
                }

                pic.imgDom = pic.imgDomLoad;
                pic.imgDomLoad = null;
                //$('span', pic.dom).remove();
                pic.imgDom.show();
                pic.frameDom.show();

                updatePicImage(pic);

                //debug('preloadCallback: ' + idx + ' (' + pic.origW + 'x' + pic.origH + ') Preloading: ' + picsLoading);
                var resI = resPicFindIndex(pic, pic.imgDom.attr('src'));
                resUpdateCache(resI, pic.origH);
                var new_url = resGetPicUrl(pic, locals.imageHeight);
                if (new_url != pic.imgDom.attr('src')) { // if there is a higher rez image that is more appropriate use that instead
                    pic.origW = null;
                    pic.origH = null;

                    //debug(new_res.index + '(' + new_res.height + ' lines) > ' + resI + ' (' + resources[resI].height + ')');

                    loadPrimaryImage(pic);

                    return;
                }

                //debug(new_res.index + '(' + new_res.height + ' lines) == ' + resI + ' (' + resources[resI].height + ')');

                updateStatus();

                if (locals.picsLoading == 0) {
                    if (locals.slideShowPlaying == true && locals.slideShowTimer == null) { // resume slideshow
                        locals.slideShowTimer = setInterval(slideShowCallback, locals.slideSpeed);
                        navNext();
                    }

                    if (idx == locals.picIndex) {
                        render(true); // render once again now that the in-view image is loaded
                    }
                    else {
                        preload();
                    }
                }

                if (idx == locals.picIndex) {
                    locals.loadingPanel.hide();
                }
            }

            function preloadErrorCallback(evt) {
                var idx = $(this).data('pic');
                var pic = locals.pics[idx];
                if (pic == null || pic.imgDomLoad == null)
                    return;

                pic.imgDomLoad = null;
                locals.picsLoading--;

                if (locals.picsLoading == 0) {
                    locals.loadingPanel.hide();
                }

                //debug('pic: ' + idx + ' failed to load');
            }

            function preloadThumbCallback(evt) {
                var o = null;
                if (evt.target == null)
                    o = evt;
                else
                    o = $(evt.target);

                var pic = locals.pics[o.data('pic')];
                if (pic == null || pic.thumbLoaded == true)
                    return;

                pic.thumbLoaded = true;

                // calc new width/height
                var w = o.width();
                var h = o.height();

                resUpdateCache(resPicFindIndex(pic, o.attr('src')), h);

                var ar = w / h;
                var arH = h / w;
                if (h > locals.settings.thumbnailsSize) {
                    h = locals.settings.thumbnailsSize;
                    w = Math.round(h * ar);
                }

                if (w > locals.settings.thumbnailsSize) { // width is greater than allowed, resize
                    w = locals.settings.thumbnailsSize;
                    h = Math.round(w * arH);
                }

                var l = Math.floor((locals.settings.thumbnailsSize - w) / 2);
                var t = Math.floor((locals.settings.thumbnailsSize - h) / 2);

                // ok, finally, lets init image
                o
                        .css({ 'left': l + 'px', 'top': t + 'px' })
                        .attr({ 'width': w, 'height': h, 'alt': '' })
                        .show()
                    ;
            }

            function reload() {
                for (i = 0; i < locals.pics.length; i++) {
                    var pic = locals.pics[i];
                    if (pic.thumbImgDom != null) {
                        pic.thumbImgDom.attr('src', ''); // cancel load
                        pic.thumbImgDom.remove();
                        pic.thumbImgDom = null;
                    }
                    if (pic.imgDomLoad != null) {
                        pic.imgDomLoad.remove();
                        pic.imgDomLoad.attr('src', ''); // cancel load
                        pic.imgDomLoad = null;
                        locals.picsLoading--;
                    }
                    if (pic.imgDom != null) {
                        pic.imgDom.remove();
                        pic.imgDom.attr('src', ''); // cancel load
                        pic.imgDom = null;
                    }
                    if (pic.frameDom != null) {
                        pic.frameDom.remove();
                        pic.frameDom = null;
                    }
                }

                render();
            }

            function loadPrimaryImage(pic) {
                var resUrl = resGetPicUrl(pic, locals.imageHeight);
                if (resUrl == null)
                    return;

                if (pic.imgDomLoad != null) {
                    pic.imgDomLoad.remove();
                    pic.imgDomLoad.attr('src', ''); // cancel load
                    pic.imgDomLoad = null;
                    locals.picsLoading--;
                }
                if (pic.imgDom != null) {
                    pic.imgDom.remove();
                    pic.imgDom.attr('src', ''); // cancel load
                    pic.imgDom = null;
                }
                if (pic.frameDom != null) {
                    pic.frameDom.remove();
                    pic.frameDom = null;
                }

                locals.picsLoading++;

                pic.imgDomLoad = $(document.createElement('img'))
                        .data('pic', pic.index)
                        .load(preloadCallback)
                        .error(preloadErrorCallback)
                        .hide()
                    ;
                //debug('view dimensions: ' + imageWidth + 'x' + imageHeight);
                pic.frameDom = $(document.createElement('div'))
                        .addClass('full_img_frame')
                        .css({ 'padding': locals.settings.imagePadding + 'px', 'width': locals.imageWidth + 'px', 'height': locals.imageHeight + 'px' })
                        .hide()
                        .append(pic.imgDomLoad)
                    ;
                pic.dom
                        .empty()
                        .append(pic.frameDom)
                    ;

                pic.imgDomLoad
                        .attr('src', resUrl)
                    ;
                //debug(SIG + '] preloading: ' + pic.index + ' picIndex: ' + picIndex + ' imagesInView: ' + imagesInView + (pic.imgDomLoad[0].complete ? ' (Syncronous)' : ' (Asyncronous)' + ' Preloading: ' + picsLoading));

                if (pic.imgDomLoad == null)
                    ; // already loaded
                else if (pic.imgDomLoad[0].complete) {
                    preloadCallback(pic.imgDomLoad);
                }
                //                else {
                //                    pic.frameDom.hide();
                //                }

            }

            function preload(forceLoad) {
                if (locals.isReady == false)
                    return;

                // determine images in view

                if (locals.settings.columns != null) {
                    locals.imagesInView = locals.settings.columns;
                }
                else {
                    locals.imagesInView = Math.ceil(locals.innerWidth / locals.imageWidth);
                }
                locals.thumbsInView = Math.ceil(locals.thumbsWidth / locals.settings.thumbnailsSize);

                if (locals.pics.length == 0)
                    return; // nothing more to do

                // preload images
                locals.loadIndex++;
                locals.preloads = locals.imagesInView + locals.settings.preload;
                //console.log(SIG + '] preloads: ' + preloads + ' pics: ' + pics.length);

                if (locals.sliderMoving == false || forceLoad == true) { // do not pre-load images during slider move
                    // preload CURRENT image before anything else...

                    var pic = locals.pics[locals.picIndex];
                    if (pic != null) {
                        pic.loadIndex = locals.loadIndex;
                        if (pic.imgDom == null && pic.imgDomLoad == null) {
                            loadPrimaryImage(pic);

                            return; // if loading current image in view, do not try to load other images until it has finished
                        }
                        else if (pic.imgDomLoad != null)
                            return; // still loading
                    }
                }

                if (locals.thumbs != null) {
                    // preload thumbnail images

                    locals.preloads = locals.thumbsInView + locals.settings.preload;
                    for (i = (locals.preloads * -1); i < locals.preloads; i++) {
                        idx = (locals.picIndex + i);
                        if (idx < 0)
                            idx += locals.pics.length;
                        idx %= locals.pics.length;
                        var pic = locals.pics[idx];
                        if (pic == null)
                            continue;
                        pic.loadThumbIndex = locals.loadIndex;
                        if (pic.thumbImgDom != null)
                            continue;
                        pic.thumbLoaded = false;
                        pic.thumbImgDom = $(document.createElement('img'))
                                .data('pic', pic.index)
                                .hide()
                                .load(preloadThumbCallback)
                            ;

                        pic.thumbDom
                                .append(pic.thumbImgDom)
                            ;

                        pic.thumbImgDom
                                .attr({ 'alt': 'Loading', 'src': pic.res[0].url })
                            ;

                        if (pic.thumbLoaded == false && pic.thumbImgDom[0].complete) {
                            preloadThumbCallback(pic.thumbImgDom);
                        }
                    }
                }

                if (locals.sliderMoving == false || forceLoad == true) { // do not pre-load images during slider move
                    for (i = 1; i < locals.preloads; i++) {
                        idx = (locals.picIndex + i);
                        if (idx < 0)
                            idx += locals.pics.length;
                        idx %= locals.pics.length;
                        var pic = locals.pics[idx];
                        if (pic == null)
                            continue;
                        pic.loadIndex = locals.loadIndex;
                        if (pic.imgDom == null && pic.imgDomLoad == null) {
                            loadPrimaryImage(pic);

                            return; // do not load anything else
                        }
                        else if (pic.imgDomLoad != null)
                            return; // still loading

                        idx = (locals.picIndex + (i * -1));
                        if (idx < 0)
                            idx += locals.pics.length;
                        idx %= locals.pics.length;
                        pic = locals.pics[idx];
                        if (pic == null)
                            continue;
                        pic.loadIndex = locals.loadIndex;
                        if (pic.imgDom == null && pic.imgDomLoad == null) {
                            loadPrimaryImage(pic);

                            return; // do not load anything else
                        }
                        else if (pic.imgDomLoad != null)
                            return; // still loading
                    }
                }

                // free old cache images that exceed our allowed range

                for (i = 0; i < locals.pics.length; i++) {
                    var pic = locals.pics[i];
                    if (pic.thumbImgDom != null && pic.loadThumbIndex != locals.loadIndex) {
                        pic.thumbLoaded = false;
                        pic.thumbImgDom.remove();
                        pic.thumbImgDom.attr('src', ''); // cancel load
                        pic.thumbImgDom = null;
                    }
                    if (pic.loadIndex == locals.loadIndex)
                        continue; // retain in cache (DOM)
                    if (pic.imgDomLoad != null) {
                        pic.imgDomLoad.remove();
                        pic.imgDomLoad.attr('src', ''); // cancel load
                        pic.imgDomLoad = null;
                        locals.picsLoading--;
                    }
                    if (pic.imgDom != null) {
                        //console.log(SIG + '] purging cache: ' + i + ' imagesInView: ' + imagesInView);
                        pic.imgDom.remove();
                        pic.imgDom.attr('src', ''); // cancel load
                        pic.imgDom = null;
                    }
                    if (pic.frameDom != null) {
                        pic.frameDom.remove();
                        pic.frameDom = null;
                    }
                }

                //console.log(SIG + '] preload END: ' + preloads + ' pics: ' + pics.length);
            }

            function render(forceLoad) {
                if (locals.isReady == false)
                    return;

                preload(forceLoad);

                if (locals.picsLoaded == 0)
                    return; // do not render if we've yet to even load one image. we need this for proper formatting

                var pic = locals.pics[locals.picIndex];
                //debug(SIG + '] render idx: ' + picIndex + ' pic: ' + pic + ' pic.imgDom: ' + (pic ? pic.imgDom : null));
                if (pic == null)
                    return; // should only occur when no pics

                updateStatus();

                if (pic.frameDom != null && pic.imgDom != null)
                    pic.frameDom.stop(false, true);

                var ui_fx = $('.ui-effects-wrapper', pic.dom); // jquery/ui fix
                if (ui_fx.length > 0) {
                    pic.dom.append(ui_fx.children());
                    ui_fx.remove();
                }

                var lastPicIndex = -1;
                if (locals.lastPic != null) {
                    lastPicIndex = locals.lastPic.index;
                    if (locals.lastPic.index != pic.index) {
                        locals.lastPic.dom.removeClass('full_selected');
                        if (locals.lastPic.thumbDom != null)
                            locals.lastPic.thumbDom.removeClass('thumb_selected');
                    }
                }

                locals.lastPic = pic;
                pic.dom.addClass('full_selected');
                if (locals.lastPic.thumbDom != null)
                    locals.lastPic.thumbDom.addClass('thumb_selected');

                var new_left = ((locals.imageWidth + locals.settings.xPadding + locals.settings.borderWidth) * locals.picIndex * -1) + Math.round(locals.innerWidth / 2) - Math.round(locals.imageWidth / 2);
                if (locals.settings.columns != null && (locals.settings.columns % 2) == 0) { // for even-numbered columns, offset to fit all columns
                    new_left -= Math.round(locals.imageWidth / 2);
                }
                if (new_left > 0)
                    new_left = 0;
                else if (new_left < ((locals.maxWidth - locals.innerWidth) * -1))
                    new_left = ((locals.maxWidth - locals.innerWidth) * -1);

                easeType = 'swing';
                //if (slideShowTimer != null && settings.slideShowContinuous == true)
                //    easeType = 'linear';

                var do_not_slide = (lastPicIndex == locals.picIndex) || (lastPicIndex == (locals.pics.length - 1) && pic.index == 0) || (lastPicIndex == 0 && pic.index == (locals.pics.length - 1));
                if (locals.thumbs != null) {
                    locals.thumbLeft = ((locals.settings.thumbnailsSize + locals.settings.xPadding + locals.settings.borderWidth) * locals.picIndex * -1) + Math.round(locals.thumbsWidth / 2) - Math.round(locals.settings.thumbnailsSize / 2);
                    if (locals.maxThumbWidth <= locals.thumbsWidth)
                        locals.thumbLeft = Math.round(locals.thumbsWidth / 2) - Math.round(locals.maxThumbWidth / 2);
                    else if (locals.thumbLeft > 0)
                        locals.thumbLeft = 0;
                    else if (locals.thumbLeft < ((locals.maxThumbWidth - locals.thumbsWidth) * -1))
                        locals.thumbLeft = ((locals.maxThumbWidth - locals.thumbsWidth) * -1);

                    if (do_not_slide == false && ((locals.slideShowTimer == null && locals.settings.moveFx == 'slide') || (locals.slideShowTimer != null && locals.settings.slideShowContinuous == true))) {
                        locals.thumbs
                            .stop(true, false)
                            .animate({ 'left': locals.thumbLeft + 'px' }, locals.slideSpeed, easeType)
                        ;
                    }
                    else {
                        locals.thumbs
                                .css('left', locals.thumbLeft + 'px')
                            ;
                    }
                }

                locals.sliderPos = Math.round((locals.sliderWidth / locals.maxWidth) * Math.abs(new_left));

                if (do_not_slide == false && ((locals.slideShowPlaying == false && locals.settings.moveFx == 'slide') || (locals.slideShowTimer != null && locals.settings.slideShowContinuous == true))) {
                    locals.container
                            .stop(true, false)
                            .animate({ 'left': new_left + 'px' }, locals.slideSpeed, easeType)
                        ;

                    if (locals.sliderBar != null) {
                        locals.sliderView
                                .stop(true, false)
                                .animate({ 'left': locals.sliderPos + 'px' }, locals.slideSpeed, easeType)
                            ;
                    }
                }
                else {
                    locals.container
                            .css('left', new_left + 'px')
                        ;

                    if (locals.sliderBar != null) {
                        locals.sliderView
                                .css('left', locals.sliderPos + 'px')
                            ;
                    }
                }

                if (lastPicIndex == locals.picIndex)
                    return; // do not use fx if index unchanged

                if ($.isFunction(locals.settings.onChange) == true) {
                    locals.settings.onChange(pic, locals.me);
                }

                if (locals.titleBar != null) {
                    locals.titleBar.html(pic.title);
                }

                var fx = 'slide';
                if (locals.settings.fxShuffle == true) {
                    i = Math.floor(Math.random() * locals.fxList.length);
                    fx = locals.fxList[i];
                }
                else {
                    locals.fxIndex = (locals.fxIndex + 1) % locals.fxList.length;
                    fx = locals.fxList[locals.fxIndex];
                }
                fx = fx.replace(' ', '');

                if (fx != 'slide') {
                    //console.log(SIG + '] rendering: ' + pic.index + ' ' + pic.width + 'x' + pic.height + ' imgDom: ' + pic.imgDom);
                    if (pic.width != null && pic.frameDom != null && pic.imgDom != null) {
                        pic.frameDom
                                .removeAttr('style')
                                .css({ 'padding': locals.settings.imagePadding + 'px', 'left': pic.left + 'px', 'top': pic.top + 'px', 'width': pic.width + 'px', 'height': pic.height + 'px' })
                            ;
                        var fxOption = fxOptions[fx];
                        pic.frameDom
                        /*.stop(true, true)*/
                                .show(fx, fxOption, locals.fxSpeed, function() {
                                    var pi = $(this).data('pic');
                                    //console.log(SIG + '] FX CALLBACK: ' + pi);
                                    var pic = locals.pics[pi];
                                    if (pic != null && pic.width != null && pic.frameDom != null) {
                                        var ui_fx = $('.ui-effects-wrapper', pic.dom); // jquery/ui fix
                                        if (ui_fx.length > 0) {
                                            pic.dom.append(ui_fx.children());
                                            ui_fx.remove();
                                        }

                                        pic.frameDom
                                            .removeAttr('style')
                                            .css({ 'padding': locals.settings.imagePadding + 'px', 'left': pic.left + 'px', 'top': pic.top + 'px', 'width': pic.width + 'px', 'height': pic.height + 'px' })
                                        ;
                                    }
                                })
                            ;
                    }
                }
            }

            function imageClick(pic, e) {
                if ($.isFunction(locals.settings.onClick) == true) {
                    if (locals.settings.onClick(pic, locals.me) == false) { // if caller returns false than do not continue
                        if (e) e.stopPropagation();

                        return false;
                    }
                }

                switch (locals.settings.imageClickBehavior) {
                    case 'fancybox': // TODO!!!
                        /*
                        $('a', container)
                        .fancybox({ 'padding': '10', 'imageScale': 'true', 'centerOnScroll': 'true', 'callbackOnStart': function() {
                        if (slideShowPlaying == true) {
                        resumeSlideshow = true;
                        slideShowStop();
                        }
                        }, 'callbackOnShow': function() {
                        var pic = pics[this.itemCurrent];
                        if (pic == null)
                        return;
                        picIndex = pic.index;
                        render();
                        }, 'callbackOnClose': function() {
                        attachWindowResize(); // hack due to fancybox detaching our resize handler
                        if (resumeSlideshow == true) {
                        slideShowStart(true);
                        }
                        }
                        });
                        */
                        break;
                    case 'popup':
                        if (e) e.stopPropagation();

                        var popupSettings = $.extend(true, {}, locals.settings, { autoShow: true, frameWidth: 0, imageClickBehavior: 'next', preload: 1, picIndexToSelect: pic.index });
                        popupSettings.picsToLoad = locals.pics;
                        $(this)
                                .wstAlbumPopup(uri, popupSettings)
                            ;

                        return false;
                    case 'goto':
                        locals.picIndex = pic.index;
                        render();

                        break;
                    case 'next':
                        navNext();

                        break;
                    case 'hide':
                        if (e) e.stopPropagation();
                        closePopup();

                        return false;
                } // settings.imageClickBehavior

                return true;
            }

            locals.loadPicsTmp = null;
            function loadPicsAsync(tmpPics) {
                locals.loadPicsTmp = tmpPics;
                setTimeout(function() { loadPics(tmpPics); }, 100);
            }

            function loadPics(tmpPics) {
                if (locals.settings.shuffle == true) {
                    while (locals.pics.length < tmpPics.length) {
                        var pic = null;
                        while (pic == null) {
                            i = Math.floor(Math.random() * tmpPics.length);
                            pic = tmpPics[i];
                        }
                        locals.pics.push(pic);
                        tmpPics[i] = null;
                    }
                }
                else { // use existing order
                    locals.pics = tmpPics;
                }

                var loc = window.location.href.toLowerCase();
                var isSecure = (loc.indexOf('https') == 0);

                if (locals.pics.length > 0) {
                    pic = locals.pics[0];
                    for (i = 0; i < pic.res.length; i++)
                        locals.resources.push({ index: locals.resources.length, height: null });
                }

                for (i = 0; i < locals.pics.length; i++) {
                    pic = locals.pics[i];
                    pic.index = i * 1; // hack to force integer
                    pic.id = locals.meId + '_' + i;
                    if (isSecure == true) {
                        for (r = 0; r < pic.res.length; r++) {
                            pic.res[r].url = pic.res[r].url.replace('http:', 'https:');
                        }
                    }
                    pic.dom = $(document.createElement('div'))
                            .attr('id', pic.id)
                            .addClass('full_img')
                            .css({ 'left': (i * (locals.imageWidth + locals.settings.xPadding + locals.settings.borderWidth)) + 'px', 'width': locals.imageWidth + 'px', 'height': locals.imageHeight + 'px' })
                        ;
                    pic.dom.data('pic', pic.index);

                    locals.container.append(pic.dom);

                    if (locals.thumbs != null) {
                        pic.thumbDom = $(document.createElement('div'))
                                .data('pic', pic.index)
                                .attr('id', pic.id + 'thumb')
                                .addClass('thumb_img')
                                .css({ 'left': (i * (locals.settings.thumbnailsSize + locals.settings.xPadding + locals.settings.borderWidth)) + 'px', 'width': locals.settings.thumbnailsSize + 'px', 'height': locals.settings.thumbnailsSize + 'px' })
                            ;
                        locals.thumbs.append(pic.thumbDom);
                    }
                }

                // config full_img events
                $('#' + locals.meId + ' .full_img img')
                        .live('click.' + locals.meId, function(evt) {
                            if (evt.button != 0 || evt.ctrlKey || evt.shiftKey || evt.altKey)
                                return true;

                            //debug(SIG + '] click.' + locals.meId + ': ' + $(this).attr('class'));

                            var pic_idx = $(this).closest('.full_img').data('pic');
                            var pic = locals.pics[pic_idx];
                            return imageClick(pic, evt);
                        })
                        .live('mouseover.' + locals.meId, function() {
                            var pic = locals.pics[$(this).closest('.full_img').data('pic')];
                            if (pic == null || pic.dom == null)
                                return;
                            if (locals.settings.columns != 1) {
                                pic.dom
                                    .addClass('full_active')
                                ;
                            }
                            if (pic.thumbDom != null) {
                                pic.thumbDom
                                    .addClass('thumb_active')
                                ;
                            }
                        })
                        .live('mouseout.' + locals.meId, function() {
                            var pic = locals.pics[$(this).closest('.full_img').data('pic')];
                            if (pic == null || pic.dom == null)
                                return;
                            pic.dom
                                .removeClass('full_active')
                            ;
                            if (pic.thumbDom != null) {
                                pic.thumbDom
                                    .removeClass('thumb_active')
                                ;
                            }
                        })
                    ;

                // config thumb_img events
                $('#' + locals.meId + ' .thumb_img')
                        .live('click.' + locals.meId, function(evt) {
                            if (evt.button != 0 || evt.ctrlKey || evt.shiftKey || evt.altKey)
                                return true;

                            var pic = locals.pics[$(this).data('pic')];
                            if (pic == null || pic.dom == null)
                                return;
                            locals.picIndex = pic.index;
                            render();
                        })
                        .live('mouseover.' + locals.meId, function() {
                            var pic = locals.pics[$(this).data('pic')];
                            if (pic == null || pic.dom == null)
                                return;
                            if (locals.settings.columns != 1) {
                                pic.dom
                                    .addClass('full_active')
                                ;
                            }
                            if (pic.thumbDom != null) {
                                pic.thumbDom
                                    .addClass('thumb_active')
                                ;
                            }
                        })
                        .live('mouseout.' + locals.meId, function() {
                            var pic = locals.pics[$(this).data('pic')];
                            if (pic == null || pic.dom == null)
                                return;
                            pic.dom
                                .removeClass('full_active')
                            ;
                            if (pic.thumbDom != null) {
                                pic.thumbDom
                                    .removeClass('thumb_active')
                                ;
                            }
                        })
                    ;

                if (locals.settings.bindKeys == true) { // hook up keyboard shortcuts
                    $(document).bind('keydown.' + locals.meId, function(e) {
                        switch (e.keyCode) {
                            case 27: // esc
                                if (settings.showClose == true) {
                                    //e.stopPropagation();
                                    closePopup();
                                    return false;
                                }
                                break;
                            case 32: // space
                                e.stopPropagation();
                                imageClick(locals.pics[locals.picIndex]);
                                return false;
                            case 37: // left
                                //e.stopPropagation();
                                navPrev();
                                break;
                            case 39: // right
                                //e.stopPropagation();
                                navNext();
                                break;
                        }

                        return true; // allow other binders to process the event too
                    });
                }

                locals.picIndex = locals.settings.picIndexToSelect;
                if (locals.picIndex < 0)
                    locals.picIndex = 0;
                else if (locals.picIndex >= (locals.pics.length - 1))
                    locals.picIndex = locals.pics.length - 1;

                resize();
            }

            if (locals.settings.picsToLoad != null) { // load pics from raw data instead of by uri
                var tmpPics = [];
                for (i = 0; i < locals.settings.picsToLoad.length; i++) {
                    var pic = locals.settings.picsToLoad[i];
                    var newPic = {
                        res: pic.res
                            , title: pic.title
                            , width: null
                            , origW: null
                            , imgDom: null
                    };

                    if (pic.res.length >= 2)
                        tmpPics.push(newPic);
                }

                loadPicsAsync(tmpPics);
            }
            else if (settings.dataType == 'json') { // load pics by uri (json format)
                $.ajax({ type: 'GET', url: uri, cache: false, success: function(data, dataStatus) {
                    var json;
                    if (typeof data == 'string') {
                        json = eval('(' + data + ')');
                    } else {
                        json = data;
                    }

                    var tmpPics = [];

                    for (i = 0; i < json.pics.length; i++) {
                        var tmp = json.pics[i];
                        var pic = {
                            res: []
                                , title: tmp.title
                                , width: null
                                , origW: null
                                , imgDom: null
                        };

                        var prev_url = '';
                        if (tmp.res != null && tmp.res.length > 0) {
                            for (i2 = 0; i2 < tmp.res.length; i2++) {
                                var tmp2 = tmp.res[i2];
                                if (tmp2.url == prev_url)
                                    continue;
                                prev_url = tmp2.url;
                                var res = {
                                    url: tmp2.url
                                };

                                pic.res.push(res);
                            }
                        }

                        if (pic.res.length == 0) { // if no resources, use legacy mechanism to look for direct links
                            if (tmp.smallUrl != null && tmp.smallUrl != prev_url) {
                                prev_url = tmp.smallUrl;
                                pic.res.push({ url: tmp.smallUrl });
                            }
                            if (tmp.largeUrl != null && tmp.largeUrl != prev_url) {
                                prev_url = tmp.largeUrl;
                                pic.res.push({ url: tmp.largeUrl });
                            }
                            if (tmp.url != null && tmp.url != prev_url) {
                                prev_url = tmp.url;
                                pic.res.push({ url: tmp.url });
                            }
                        }

                        if (pic.res.length >= 2)
                            tmpPics.push(pic);
                    }

                    loadPics(tmpPics);
                }
                    , error: function(req, textStatus, err) {
                        // TODO!!! add retry logic
                        updateStatus('Failed to retrieve photo feed, please try again in a few moments.');
                    }
                });
            }
            else { // load pics by uri (xml format)
                $.ajax({ type: 'GET', url: uri, dataType: ($.browser.msie) ? 'text' : 'xml', cache: false, success: function(data, dataStatus) {
                    var xml;
                    if (typeof data == 'string') {
                        xml = new ActiveXObject('Microsoft.XMLDOM');
                        xml.async = false;
                        xml.loadXML(data);
                    } else {
                        xml = data;
                    }

                    var tmpPics = [];

                    picsXml = $('pic', xml);

                    picsXml
                            .each(function() {
                                var picElement = $(this);
                                var pic = {
                                    res: []
                                    , title: picElement.children('title').text()
                                    , width: null
                                    , origW: null
                                    , imgDom: null
                                };

                                var prev_url = '';

                                picElement.children('res')
                                    .each(function() {
                                        var res = { url: $(this).children('url').text() };
                                        if (res.url == prev_url)
                                            return;
                                        prev_url = res.url;
                                        if (res.url != null)
                                            pic.res.push(res);
                                    })
                                ;

                                if (pic.res.length == 0) { // if no resources, use legacy mechanism to look for direct links
                                    var tmp = {
                                        url: picElement.children('url').text()
                                        , smallUrl: picElement.children('smallUrl').text()
                                        , largeUrl: picElement.children('largeUrl').text()
                                    };

                                    if (tmp.smallUrl != null && tmp.smallUrl != prev_url) {
                                        prev_url = tmp.smallUrl;
                                        pic.res.push({ url: tmp.smallUrl });
                                    }
                                    if (tmp.largeUrl != null && tmp.largeUrl != prev_url) {
                                        prev_url = tmp.largeUrl;
                                        pic.res.push({ url: tmp.largeUrl });
                                    }
                                    if (tmp.url != null && tmp.url != prev_url) {
                                        prev_url = tmp.url;
                                        pic.res.push({ url: tmp.url });
                                    }
                                }

                                if (pic.res.length >= 2)
                                    tmpPics.push(pic);
                            })
                        ;

                    loadPics(tmpPics);
                }
                    , error: function(req, textStatus, err) {
                        // TODO!!! add retry logic
                        updateStatus('Failed to retrieve photo feed, please try again in a few moments.');
                    }
                });
            }

            function attachWindowResize() {
                $(window)
                        .unbind('resize.' + locals.meId)
                        .bind('resize.' + locals.meId, resize)
                    ;
            }

            function destroy(locals) {
                if (locals.slideShowTimer != null) {
                    clearInterval(locals.slideShowTimer);
                    locals.slideShowTimer = null;
                }
                if (locals.resizeCheckTimer != null) {
                    clearInterval(locals.resizeCheckTimer);
                    locals.resizeCheckTimer = null;
                }
                if (locals.isReadyTimer != null) {
                    clearInterval(locals.isReadyTimer);
                    locals.isReadyTimer = null;
                }
                if (locals.hideMenusTimer != null) {
                    clearInterval(locals.hideMenusTimer);
                    locals.hideMenusTimer = null;
                }
                if (locals.sliderMovingTimer != null) {
                    clearInterval(locals.sliderMovingTimer);
                    locals.sliderMovingTimer = null;
                }

                $('object', locals.me).hide().remove(); // IE bug fix, removing me from DOM was not unloading flash objects; must remove explictly

                $(document).unbind('.' + locals.meId);
                $(window).unbind('.' + locals.meId);
                $('*', locals.me).unbind(); // kill events for all children
                locals.me.die('.' + locals.meId); // only kill living events for our id

                if (locals.settings && locals.settings.overlayMode == true) { // restore previous overflow settings
                    if (locals.originalOverflow != null && locals.originalOverflow != undefined)
                        locals.meBody.css('overflow', locals.originalOverflow);
                    else
                        locals.meBody.css('overflow', 'visible');
                    if (locals.originalOverflowX != null && locals.originalOverflowX != undefined)
                        locals.meBody.css('overflow-x', locals.originalOverflowX);
                    else
                        locals.meBody.css('overflow-x', 'visible');
                    if (locals.originalOverflowY != null && locals.originalOverflowY != undefined)
                        locals.meBody.css('overflow-y', locals.originalOverflowY);
                    else
                        locals.meBody.css('overflow-y', 'visible');
                }

                locals.me.stop(true, false);

                // TODO!!! stop all timers, etc. free everything

                locals.me.empty().hide();
            }

            // perform initial startup actions
            updateStatus();

            attachWindowResize();

            locals.resizeCheckTimer;
            locals.isReadyTimer = null;
            function isReadyCheck() {
                if (locals.isReady == true && locals.picsLoaded > 0) {
                    clearInterval(locals.isReadyTimer);
                    locals.isReadyTimer = null;
                    locals.resizeCheckTimer = setInterval(resize, 1000);
                    lastImageWidth = 0; // required to force refresh
                }
                resize();
            }
            if (locals.isReady == false) { // special case where we are not yet ready (due to unrelated dynamic workings on the page)
                locals.isReadyTimer = setInterval(isReadyCheck, 500);
            }

            function hideMenusCallback() {
                if (locals.nav_bar_active == true || locals.picsLoaded == 0)
                    return;

                if (locals.hideMenusTimer != null) {
                    clearInterval(locals.hideMenusTimer);
                    locals.hideMenusTimer = null;
                }

                if (locals.menusVisible == true) {
                    locals.menusVisible = false;
                    if (locals.settings.menuFadeEnabled == false || ($.browser.msie == true && $.browser.version < 6)) {
                        locals.menu
                                .hide()
                            ;
                        locals.menu_overlay
                                .hide()
                            ;
                    }
                    else {
                        locals.menu
                                .stop(true, false)
                                .fadeOut(1000)
                            ;
                        locals.menu_overlay
                                .stop(true, false)
                                .fadeOut(1000)
                            ;
                    }
                }
            }

            function showMenu() {
                if (locals.hideMenusTimer != null) {
                    clearInterval(locals.hideMenusTimer);
                }

                if (locals.settings.hideMenusDelay != null) {
                    locals.hideMenusTimer = setInterval(hideMenusCallback, locals.settings.hideMenusDelay);
                }

                if (locals.menusVisible == true) {
                    return;
                }

                locals.menusVisible = true;
                if (locals.settings.menuFadeEnabled == false || ($.browser.msie == true && $.browser.version < 6)) {
                    locals.menu.show();
                    locals.menu_overlay.show();
                }
                else { // standard
                    locals.menu
                            .stop(true, false)
                            .removeAttr('style')
                            .css(locals.settings.menuPosition, locals.settings.menuOffset)
                            .css({ 'left': Math.round((locals.innerWidth - locals.menu_width) / 2) + 'px' })
                            .fadeIn(100, function() {
                                $(this)
                                    .removeAttr('style')
                                    .css(locals.settings.menuPosition, locals.settings.menuOffset)
                                    .css({ 'left': Math.round((locals.innerWidth - locals.menu_width) / 2) + 'px' })
                                ;
                            })
                        ;
                    locals.menu_overlay
                            .stop(true, false)
                            .removeAttr('style')
                            .css(locals.settings.menuPosition, locals.settings.menuOffset)
                            .css({ 'left': Math.round((locals.innerWidth - locals.menu_width) / 2) + 'px', 'width': locals.menu_width + 'px' })
                            .fadeIn(100, function() {
                                $(this)
                                    .removeAttr('style')
                                    .css(locals.settings.menuPosition, locals.settings.menuOffset)
                                    .css({ 'left': Math.round((locals.innerWidth - locals.menu_width) / 2) + 'px', 'width': locals.menu_width + 'px' })
                                ;
                            })
                        ;
                }
            }

            // init hideMenusTimer
            if (locals.settings.hideMenusDelay != null) {
                var lastMouseMove = null;
                locals.hideMenusTimer = setInterval(hideMenusCallback, locals.settings.hideMenusDelay);
                var activator_context = locals.settings.menuActivateFromAnywhere ? $(document) : locals.me;
                activator_context.bind('mousemove.' + locals.meId, function(e) {
                    if (lastMouseMove != null) {
                        if (Math.abs(e.clientX - lastMouseMove.clientX) <= 3 &&
                            Math.abs(e.clientY - lastMouseMove.clientY) <= 3)
                            return; // we require greater movement to bring menu up
                    }

                    lastMouseMove = e;

                    showMenu();
                });
            }

            updateMenu(true);

            // prevent cursor selection
            var myEl = $(locals.me_this).get(0);
            if (typeof myEl.onselectstart != "undefined") //IE route
                myEl.onselectstart = function() { return false; };
            else if (typeof myEl.style.MozUserSelect != "undefined") //Firefox route
                myEl.style.MozUserSelect = "none";
            else //All other route (ie: Opera)
                myEl.onmousedown = function() { return false; };
            myEl.style.cursor = "default";

            return locals.me;
        }
        }; // locals = runningAlbums[meId] = { me_this: this, fn: function(locals, uri, settings) {

        return locals.fn(locals, uri, settings);
    };

})(jQuery);


/**
* --------------------------------------------------------------------
* jQuery-Plugin "pngFix"
* Version: 1.2, 09.03.2009
* by Andreas Eberhard, andreas.eberhard@gmail.com
*                      http://jquery.andreaseberhard.de/
*
* Copyright (c) 2007 Andreas Eberhard
* Licensed under GPL (http://www.opensource.org/licenses/gpl-license.php)
*
* Changelog:
*    09.03.2009 Version 1.2
*    - Update for jQuery 1.3.x, removed @ from selectors
*    11.09.2007 Version 1.1
*    - removed noConflict
*    - added png-support for input type=image
*    - 01.08.2007 CSS background-image support extension added by Scott Jehl, scott@filamentgroup.com, http://www.filamentgroup.com
*    31.05.2007 initial Version 1.0
* --------------------------------------------------------------------
* @example $(function(){$(document).pngFix();});
* @desc Fixes all PNG's in the document on document.ready
*
* jQuery(function(){jQuery(document).pngFix();});
* @desc Fixes all PNG's in the document on document.ready when using noConflict
*
* @example $(function(){$('div.examples').pngFix();});
* @desc Fixes all PNG's within div with class examples
*
* @example $(function(){$('div.examples').pngFix( { blankgif:'ext.gif' } );});
* @desc Fixes all PNG's within div with class examples, provides blank gif for input with png
* --------------------------------------------------------------------
*/

(function($) {

    jQuery.fn.pngFix = function(settings) {

        // Settings
        settings = jQuery.extend({
            blankgif: 'blank.gif'
        }, settings);

        var ie55 = (navigator.appName == "Microsoft Internet Explorer" && parseInt(navigator.appVersion) == 4 && navigator.appVersion.indexOf("MSIE 5.5") != -1);
        var ie6 = (navigator.appName == "Microsoft Internet Explorer" && parseInt(navigator.appVersion) == 4 && navigator.appVersion.indexOf("MSIE 6.0") != -1);

        if (jQuery.browser.msie/* && (ie55 || ie6)*/) {

            //fix images with png-source
            jQuery(this).find("img[src$=.png]").each(function() {

                jQuery(this).attr('width', jQuery(this).width());
                jQuery(this).attr('height', jQuery(this).height());

                var prevStyle = '';
                var strNewHTML = '';
                var imgId = (jQuery(this).attr('id')) ? 'id="' + jQuery(this).attr('id') + '" ' : '';
                var imgClass = (jQuery(this).attr('class')) ? 'class="' + jQuery(this).attr('class') + '" ' : '';
                var imgTitle = (jQuery(this).attr('title')) ? 'title="' + jQuery(this).attr('title') + '" ' : '';
                var imgAlt = (jQuery(this).attr('alt')) ? 'alt="' + jQuery(this).attr('alt') + '" ' : '';
                var imgAlign = (jQuery(this).attr('align')) ? 'float:' + jQuery(this).attr('align') + ';' : '';
                var imgHand = (jQuery(this).parent().attr('href')) ? 'cursor:hand;' : '';
                if (this.style.border) {
                    prevStyle += 'border:' + this.style.border + ';';
                    this.style.border = '';
                }
                if (this.style.padding) {
                    prevStyle += 'padding:' + this.style.padding + ';';
                    this.style.padding = '';
                }
                if (this.style.margin) {
                    prevStyle += 'margin:' + this.style.margin + ';';
                    this.style.margin = '';
                }
                var imgStyle = (this.style.cssText);

                strNewHTML += '<span ' + imgId + imgClass + imgTitle + imgAlt;
                strNewHTML += 'style="position:relative;white-space:pre-line;display:inline-block;background:transparent;' + imgAlign + imgHand;
                strNewHTML += 'width:' + jQuery(this).width() + 'px;' + 'height:' + jQuery(this).height() + 'px;';
                strNewHTML += 'filter:progid:DXImageTransform.Microsoft.AlphaImageLoader' + '(src=\'' + jQuery(this).attr('src') + '\', sizingMethod=\'scale\');';
                strNewHTML += imgStyle + '"></span>';
                if (prevStyle != '') {
                    strNewHTML = '<span style="position:relative;display:inline-block;' + prevStyle + imgHand + 'width:' + jQuery(this).width() + 'px;' + 'height:' + jQuery(this).height() + 'px;' + '">' + strNewHTML + '</span>';
                }

                jQuery(this).hide();
                jQuery(this).after(strNewHTML);

            });

            // fix css background pngs
            jQuery(this).find("*").each(function() {
                var bgIMG = jQuery(this).css('background-image');
                if (bgIMG.indexOf(".png") != -1) {
                    var iebg = bgIMG.split('url("')[1].split('")')[0];
                    jQuery(this).css('background-image', 'none');
                    jQuery(this).get(0).runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + iebg + "',sizingMethod='scale')";
                }
            });

            //fix input with png-source
            jQuery(this).find("input[src$=.png]").each(function() {
                var bgIMG = jQuery(this).attr('src');
                jQuery(this).get(0).runtimeStyle.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader' + '(src=\'' + bgIMG + '\', sizingMethod=\'scale\');';
                jQuery(this).attr('src', settings.blankgif)
            });

        }

        return jQuery;

    };

})(jQuery);
