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 */
            popupVideoHeight: 400, //these are used to size videos in popup mode.
            popupVideoWidth: 535
        };

        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
                    , uiFadeEnabled: true
                    , uiFadeDelay: 2000
                    , loadFullImages: true
                    , columns: 1
                    , moveFx: null
                    , shuffle: false
                    , slideShowContinuous: false
                    , imageClickBehavior: 'next'
                    , imagePadding: 0
                    , overlayMode: true
                    , thumbnails: settings.thumbnails
                    , thumbnailsSize: 65
                    , sliderBar: settings.sliderBar
                    , menuPosition: 'below'
                    , menuCompact: true
                    , menuOffset: '0'
                    , bindKeys: true
                    , menuVisible: true
                    , menuActivateFromAnywhere: true
                    , zoomToFit: false
                }
            );
            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.
    * 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 */
            uiFadeEnabled: true, /* if fade effect is not supported or desired, set to false to disable */
            uiFadeDelay: 2000, /* the time in milliseconds of mouse inactivity before hiding ui components; null to disable */
            //menuFadeEnabled: true, /* OBSOLETE: Use uiFadeEnabled */
            //hideMenusDelay: 1000, /* OBSOLETE: Use uiFadeDelay */
            menuPosition: 'top', /* position supports 'bottom' or 'top' */
            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 */
            notesShow: false, /* if true, notes will be displayed for the currently selected image */
            notesPosition: '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 */
            thumbnailNav: true, /* show nav on thumbnails or not */
            //the thumbnail from PA is not always big enough for the large thumbnail. Changing to use the large image
            thumbnailIndex: 1, /* index of fixed resource */
            thumbnailBorder: 3, /* pixels to reserve around thumbnail border */
            thumbnailSpacing: 5, /* pixels between each thumbnail */
            thumbnailTooltip: true, /* show tooltip on hover if true */
            sliderBar: false, /* show slider bar or not for navigation */
            sliderPosition: 'bottom', /* position of slider bar, bottom or top */
            sliderSize: 14, /* size of the sliders height, in pixels */
            borderWidth: 2, /* border width, in pixels */
            xPadding: 3, /* pixel padding between images */
            moduleSpacing: 10, /* pixels between modules */
            resources: [{height: 90},{height: 300},{height: 1200}], /* optionally define heights of the various resources */
            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) */
            emptyAlbumHtml: 'Album Empty', /* text or html to render if album is empty, or null to display nothing */
            aspect: { x: 4, y: 3 }, /* aspect ratio for rendering purposes. 4:3 is standard landscape mode */
            aspectThumbs: { x: 4, y: 3 }, /* aspect ratio for rendering purposes. 4:3 is standard landscape mode */
            zoomToFit: false, /* fill area with image if true. will NOT stretch, however */
            zoomToFitThumbs: false, /* fill area with image if true. will NOT stretch, however */
            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 */
            menuVisible: true, /*show menu */
            originalAlbumId: null, /* this is used to display the original slideshow after viewing in the full screen mode */
            videoClick: '', /* optional event handler if the caller wishes to perform an action after the clicking the video */
            videoPlay: '', /* optional event handler if the caller wishes to perform an action after the video play */
            videoPause: '', /* optional event handler if the caller wishes to perform an action after the pausing the video */
            videoEnd: '', /* optional event handler if the caller wishes to perform an action after the end of the video */
            disableRightClick: false /* optional if the caller wishes to turn off the context menu */
        };

        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 (typeof settings.menuFadeEnabled != "undefined" && settings.menuFadeEnabled !== null)
            settings.uiFadeEnabled = settings.menuFadeEnabled;
        if (typeof settings.hideMenusDelay != "undefined" && settings.hideMenusDelay !== null)
            settings.uiFadeDelay = settings.hideMenusDelay;

        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, destroyed: true, 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 'getsettings':
                    return locals.settings;
                case 'picindex':
                    return locals.picIndex;
                case 'render':
                    render();
                    return locals.me;
                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;
                case 'next':
                    navNext();
                    return locals.me;
                case 'prev':
                    navPrev();
                    return locals.me;
                case 'start':
                    slideShowStart();
                    return locals.me;
                case 'imageclick':
                    if (settings.picIndex < locals.pics.length)
                        imageClick(locals.pics[settings.picIndex], null);
                    return locals.me;
            };
            destroy(locals);
            if (uri.toLowerCase() == 'destroy') {
                delete runningAlbums[locals.meId];
                return locals.me;
            }

            locals.destroyed = false;
            locals.animation = null;
            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.uri = uri;
            settings.aspect.xRatio = settings.aspect.x / settings.aspect.y;
            settings.aspect.yRatio = settings.aspect.y / settings.aspect.x;
            settings.aspectThumbs.xRatio = settings.aspectThumbs.x / settings.aspectThumbs.y;
            settings.aspectThumbs.yRatio = settings.aspectThumbs.y / settings.aspectThumbs.x;
            settings.thumbnailsHeight = settings.thumbnailsSize;
            settings.thumbnailsWidth = settings.thumbnailsHeight * settings.aspectThumbs.xRatio;
            locals.settings = settings;
            if (locals.settings.thumbnails == true) {
                locals.settings.sliderBar = true; // force on for thumbs
                locals.settings.sliderPosition = locals.settings.thumbnailsPosition;
            }

            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.loadCalled = 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.thumbsTooltip = 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' });
                locals.meBody.parent('html').css({ 'height':'100%'});
            }

            // 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.ui_active = false;

            locals.menu = $(document.createElement('div'))
                .css('visibility', 'hidden')
                .addClass(locals.settings.menuCompact ? 'menu_sm' : 'menu')
                .mouseover(function() { locals.ui_active = true; })
                .mouseout(function() { locals.ui_active = false; })
            ;

            locals.menu_overlay = $(document.createElement('div'))
                .css('visibility', 'hidden')
                .addClass(locals.settings.menuCompact ? 'menu_overlay_sm' : 'menu_overlay')
            ;
            
            locals.menu_placeholder = null;
            
            switch (locals.settings.menuPosition)
            {
                case 'above':
                    //locals.settings.uiFadeDelay = null;
                    locals.menu_placeholder = $(document.createElement('div'))
                        .css('height', (locals.settings.menuCompact ? 40 : 70) + 'px');
                case 'top':
                    locals.menu.css('top', locals.settings.menuOffset);
                    locals.menu_overlay.css('top', locals.settings.menuOffset);
                break;
                case 'below':
                    //locals.settings.uiFadeDelay = null;
                    locals.menu_placeholder = $(document.createElement('div'))
                        .css('height', (locals.settings.menuCompact ? 40 : 70) + 'px');
                default:
                    locals.menu.css('bottom', locals.settings.menuOffset);
                    locals.menu_overlay.css('bottom', locals.settings.menuOffset);
                break;
            }

            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 - 6) + 'px', 'top': '3px'})
                    .mouseover(function() { locals.ui_active = true; })
                    .mouseout(function() { locals.ui_active = false; })
                    : null)
                ;
            if (locals.sliderView != null)
                locals.sliderView.append('<div class="slider_handle"></div>');

            function sliderMovingCallback() {
                preload(true);
            }

            locals.sliderMovingTimer = null;
            locals.sliderBar = (locals.settings.sliderBar == true ? $(document.createElement('div'))
                    .css('height', locals.settings.sliderSize + 'px')
                    .append(locals.sliderView)
                    .addClass('slider')
            /*                .css('height', settings.sliderSize + 'px') */
                    .mouseover(function() {
                        $(this).addClass('slider_hover');
                        locals.ui_active = true;
                    })
                    .mouseout(function() {
                        $(this).removeClass('slider_hover');
                        locals.ui_active = false;
                    })
                    .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;
                            thumbnailTooltipShow(locals.pics[locals.picIndex]); // must show before render
                            render();
                        } else {
                            thumbnailTooltipShow(locals.pics[locals.picIndex]);
                        }

                        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;

                            thumbnailTooltipShow(locals.pics[locals.picIndex]); // must show before render
                            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();

                                thumbnailTooltipHide();
                            })
                            .mousemove(me_mouse_move)
                        ;
                    })
                    : null)
                ;

            locals.loadingPanel = $(document.createElement('div'))
                .addClass('loading')
                .html('Loading...')
            ;
            if (locals.settings.thumbnails == true) {
                locals.thumbsHeight = (locals.settings.thumbnailsHeight + locals.settings.borderWidth + locals.settings.thumbnailBorder + locals.settings.thumbnailBorder);
                locals.thumbs = $(document.createElement('div'))
                    .addClass('thumbs_container')
                    .css({ left: '0px', top: '0px', 'height': locals.thumbsHeight + 'px' })
                ;
                locals.thumbsTooltipImg = $('<div class="thumbs_tooltip_img" />').css('border-width', locals.settings.thumbnailBorder);
                if (locals.settings.thumbnailsPosition == 'top')
                    locals.thumbsTooltip = $('<div />')
                        .addClass('thumbs_tooltip')
                        .hide()
                        .append('<div class="thumbs_tooltip_arrow_up" />')
                        .append(locals.thumbsTooltipImg)
                    ;
                else
                    locals.thumbsTooltip = $('<div />')
                        .addClass('thumbs_tooltip')
                        .hide()
                        .append(locals.thumbsTooltipImg)
                        .append('<div class="thumbs_tooltip_arrow_down" />')
                    ;
                locals.thumbsParent = $(document.createElement('div'))
                    .addClass('thumbs_container_parent')
                    .css({ 'height': locals.thumbsHeight + 'px' })
                    .append(locals.thumbs)
                    .mouseover(function() { locals.ui_active = true; })
                    .mouseout(function() { locals.ui_active = false; })
                ;
                locals.thumbsSection = $('<div />')
                    .addClass('thumbs_section')
                    .css({ 'height': locals.thumbsHeight + 'px' })
                    .append(locals.thumbsParent)
                    .append(locals.thumbsTooltip)
                ;
                if (locals.settings.overlayMode == true)
                    locals.thumbsSection.css('background-color', '#000');
                if (locals.settings.thumbnailNav == true) {
                    locals.thumbsNavLeft = $('<div />')
                        .addClass('thumbs_nav')
                        .css({'left': locals.settings.thumbnailSpacing + 'px', 'height': locals.thumbsHeight + 'px'})
                        .append($('<div />').addClass('thumbs_nav_left_btn').css({ 'margin-top': ((locals.thumbsHeight / 2) - 12) + 'px' }))
                        .mouseover(function() { locals.ui_active = true; $(this).addClass('thumbs_nav_hover');  })
                        .mouseout(function() { locals.ui_active = false; $(this).removeClass('thumbs_nav_hover');  })
                        .click(function() {
                            stopVideo(locals.pics[locals.picIndex]);
                            if (locals.picIndex == 0)
                                locals.picIndex = locals.pics.length - 1;
                            else {
                                locals.picIndex -= parseInt(Math.floor(locals.thumbsParent.width() / (locals.settings.thumbnailsSize + locals.settings.thumbnailSpacing + locals.settings.thumbnailBorder + locals.settings.thumbnailBorder)));
                                if (locals.picIndex < 0)
                                    locals.picIndex = 0;
                            }
                            render();
                        })
                    ;
                    locals.thumbsNavRight = $('<div />')
                        .addClass('thumbs_nav')
                        .css({'right': locals.settings.thumbnailSpacing + 'px', 'height': locals.thumbsHeight + 'px' })
                        .append($('<div />').addClass('thumbs_nav_right_btn').css({ 'margin-top': ((locals.thumbsHeight / 2) - 12) + 'px' }))
                        .mouseover(function() { locals.ui_active = true; $(this).addClass('thumbs_nav_hover');  })
                        .mouseout(function() { locals.ui_active = false; $(this).removeClass('thumbs_nav_hover');  })
                        .click(function() {
                            stopVideo(locals.pics[locals.picIndex]);
                            if (locals.picIndex >= (locals.pics.length - 1))
                                locals.picIndex = 0;
                            else {
                                locals.picIndex += parseInt(Math.floor(locals.thumbsParent.width() / (locals.settings.thumbnailsSize + locals.settings.thumbnailSpacing + locals.settings.thumbnailBorder + locals.settings.thumbnailBorder)));
                                if (locals.picIndex > (locals.pics.length - 1))
                                    locals.picIndex = (locals.pics.length - 1);
                            }
                            render();
                        })
                    ;
                    locals.thumbsSection.append(locals.thumbsNavLeft).append(locals.thumbsNavRight);
                }
            }

            locals.titleBar = (locals.settings.titleShow == true ? $('<div class="title_bar">&nbsp;</div>') : null);

            if (locals.menu_placeholder != null && locals.settings.menuPosition == 'above')
                locals.main.append(locals.menu_placeholder.css('margin-top', ((locals.main.children().length > 0) ? locals.settings.moduleSpacing : '0') + 'px'));

            if (locals.sliderBar != null && locals.settings.sliderPosition == 'top')
                locals.main.append(locals.sliderBar.css('margin-top', ((locals.main.children().length > 0) ? locals.settings.moduleSpacing : '0') + 'px'));

            if (locals.thumbs != null && locals.settings.thumbnailsPosition == 'top')
                locals.main.append(locals.thumbsSection.css('margin-top', ((locals.main.children().length > 0) ? locals.settings.moduleSpacing : '0') + 'px'));

            if (locals.titleBar != null && locals.settings.titlePosition == 'top')
                locals.main.append(locals.titleBar.css('margin-top', ((locals.main.children().length > 0) ? locals.settings.moduleSpacing : '0') + 'px'));

            locals.notes = (locals.settings.notesShow == true ? $('<div class="notes">&nbsp;</div>') : null);

            if (locals.notes != null && locals.settings.notesPosition == 'top')
                locals.main.append(locals.notes.css('margin-top', ((locals.main.children().length > 0) ? locals.settings.moduleSpacing : '0') + 'px'));

            locals.container_parent.css('margin-top', ((locals.main.children().length > 0) ? locals.settings.moduleSpacing : '0') + 'px');

            locals.main
                    .append(locals.loadingPanel)
                    .append(locals.menu)
                    .append(locals.menu_overlay)
                    .append(locals.container_parent)
                ;

            if (locals.titleBar != null && locals.settings.titlePosition != 'top')
                locals.main.append(locals.titleBar.css('margin-top', locals.settings.moduleSpacing + 'px'));

            if (locals.notes != null && locals.settings.notesPosition != 'top')
                locals.main.append(locals.notes.css('margin-top', locals.settings.moduleSpacing + 'px'));

            if (locals.thumbs != null && locals.settings.thumbnailsPosition != 'top')
                locals.main.append(locals.thumbsSection.css('margin-top', locals.settings.moduleSpacing + 'px'));

            if (locals.sliderBar != null && locals.settings.sliderPosition != 'top')
                locals.main.append(locals.sliderBar.css('margin-top', locals.settings.moduleSpacing + 'px'));

            if (locals.menu_placeholder != null && locals.settings.menuPosition != 'above')
                locals.main.append(locals.menu_placeholder.css('margin-top', locals.settings.moduleSpacing + 'px'));

            locals.me
                    .empty()
                    .show()
                    .addClass('wst_album')
                    .append(locals.main)
                ;

            function stopVideo(pic) {
                if (typeof (locals.pics) == 'undefined')
                    return;
                resetInterval();
                if (typeof(pic) == 'undefined')
                {
                    pic = locals.pics[locals.picIndex];
                }
                if (pic != null) {
                    if (pic.mediaType == 'video' && pic.frameDom != null) {
                        pic.frameDom.empty();
                        loadPrimaryImage(pic);
                    }
                }
            }

            function hideBlockingNodes(){
                try{
                    $('.fullscreen-hide').each(function(index, node){
                    
                        if($(node).is("iframe")){

                            if ( node.style ) {
					            var visibility = jQuery.css( node, "visibility" );

					            if ( visibility !== "hidden" && !jQuery.data( node, "prevvisibility" ) ) {
						            jQuery.data( node, "prevvisibility", visibility );
					            }
				            }
                            $(node).css("visibility", "hidden");
                        }
                        else{
                            $(node).hide();
                        }
                    });
                }catch(e){
                    //this happens when an iFrame is from a different domain.
                }
            }

            function showBlockingNodes(){
                try{
                    
                    $('.fullscreen-hide').each(function(index, node){
                        
                        if($(node).is("iframe")){
                            
                            var visibility = jQuery.data( node, "prevvisibility");
                            
                            if(visibility){
                                $(node).css("visibility", visibility);
                            }
                            
                        }
                        else{
                            $(node).show();
                        }
                    });

                }catch(e){
                    //When an iframe is embeded from another domain (youtube etc)
                    //get a cross domain error on accessing the style
                }
            }

            function navPrev(forceWrap, preventWrap) {
                var pic = locals.pics[locals.picIndex];
                if (locals.picIndex > 0)
                    locals.picIndex--;
                else if (preventWrap != true && (locals.settings.wrap == true || forceWrap == true))
                    locals.picIndex = (locals.pics.length - 1);
                stopVideo(pic);

                render();
            }

            function navNext(forceWrap, preventWrap) {
                var pic = locals.pics[locals.picIndex];
                if (locals.picIndex < (locals.pics.length - 1))
                    locals.picIndex++;
                else if (preventWrap != true && (locals.settings.wrap == true || forceWrap == true))
                    locals.picIndex = 0;
                stopVideo(pic);

                render();
            }

            function navFirst() {
                var pic = locals.pics[locals.picIndex];
                locals.picIndex = 0;
                stopVideo(pic);

                render();
            }

            function navLast() {
                var pic = locals.pics[locals.picIndex];
                locals.picIndex = locals.pics.length - 1;
                stopVideo(pic);

                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);
                showBlockingNodes();
                $('#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() {
                                slideShowStop();
                                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() { 
                            var pic = locals.pics[locals.picIndex];
                            if (pic != null && pic.mediaType == 'video')
                            {   
                                if (locals.slideShowPlaying != true)
                                {
                                    $('.nav_play,.nav_play_sm', locals.menu).hide();
                                    $('.nav_pause,.nav_pause_sm', locals.menu).show();
                                    locals.slideShowPlaying = true;
                                    navNext();
                                }
                            }
                            else
                            {
                                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() {
                                slideShowStop();
                                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
                        }
                        //console.log('resGet: heightReq: ' + heightReq + ' minIndex: ' + minIndex + ' res[' + resI + '].height: ' + res.height);
                        return res;
                    }
                }

                //console.log('resGet LAST: heightReq: ' + heightReq + ' minIndex: ' + minIndex + ' res[' + (locals.resources.length - 1) + '].height: ' + locals.resources[locals.resources.length - 1].height);
                return locals.resources[locals.resources.length - 1];
            }

            function resGetPicUrl(pic, heightReq, minIndex) {
                var res = resGet(heightReq, minIndex);
                if (res == null)
                    return null;

                if (pic.mediaType == 'video') {
                    if (pic.res.length > 2) {
                        return pic.res[1].url;
                    }
                }

                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;

                var pic = locals.pics[locals.picIndex];
                if (pic != null) {
                    $('.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 resetInterval() {
                if (locals.slideShowTimer == null && locals.slideShowPlaying == true) { // resume
                    locals.slideSpeed = locals.settings.slideShowDelay;
                    locals.slideShowTimer = setInterval(slideShowCallback, locals.slideSpeed);
                }
            }

            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 it's a video, clear the timer. At the end of the video perform navNext
                    var oldPic = locals.pics[locals.picIndex];
                    if (oldPic != null) {
                        if (oldPic.mediaType == 'video' && locals.slideShowTimer != null) { // pause slideshow
                            clearInterval(locals.slideShowTimer);
                            locals.slideShowTimer = 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 embedVideo(pic) {
                var fullScreenState = ($('#wst_album_popup:visible').length != 0);

                //console.log('embedVideo.index=' + pic.index);
                // Get the latest paplayerSlideShow.swf from the TFS:/Charlie/FlashGroupSources/PhotoAlbum/SlideShow/SlideShowPlayer
                var viewEndCallbackFunction = "function(){}";

                if (locals.slideShowPlaying == true) {
                    viewEndCallbackFunction = "function() { $('#" + locals.meId + "').wstAlbum('Next'); }";
                }
                var videoClickCallbackFunction = "function() { $('#" + locals.meId + "').wstAlbum('ImageClick', { picIndex: " + pic.index + "}); }";
                var videoPauseCallbackFunction = "function(){}";
                //var fullScreenState = ($('#wst_album_popup:visible').length != 0)
                var videoPlayCallbackFunction = locals.settings.videoPlay
                /*if (fullScreenState) {
                    videoClickCallbackFunction = locals.settings.videoEnd;
                }*/

                var videoHeight = locals.settings.popupVideoHeight && fullScreenState ? locals.settings.popupVideoHeight : locals.imageHeight;
                var videoWidth  = locals.settings.popupVideoWidth && fullScreenState ? locals.settings.popupVideoWidth : locals.imageWidth;

                              
                if (pic.res.length < 3)
                    return;
               
                var flashvars = {
                    theVid: pic.res[2].url,
                    doPlay: 1,
                    doLogo: 0,
                    Width: videoWidth - 2,
                    Height: videoHeight - 2,
                    viewEndCallback: viewEndCallbackFunction,
                    videoClickCallback: videoClickCallbackFunction,
                    videoPauseCallback: videoPauseCallbackFunction,
                    videoPlayCallback: videoPlayCallbackFunction
                };


                var params = {
                    quality: "high",
                    allowfullscreen: "true",
                    allowscriptaccess: "samedomain",
                    id: "movie_" + pic.id,
                    wmode: "opaque"
                };
                var attributes = {
                    id: "paplayer_" + pic.id,
                    name: "paplayer_" + pic.id
                };

                var videoContainerID = pic.id + 'containerVideo';
                var newVideoDiv = $(document.createElement('div'))
						.attr('id', videoContainerID)
						.addClass('full_img')
						//.css({ 'left': (i * (locals.imageWidth + settings.xPadding + settings.borderWidth)) + 'px', 'width': locals.imageWidth + 'px', 'height': locals.imageHeight + 'px' })
						.css({ 'left': '0px', 'width': videoWidth + 'px', 'height': videoHeight + 'px' })
						;

                //Find the image element and remove it (if any). 
                /*var mainDiv = $("#" + pic.id).find(".full_img_frame")[0];
                if (mainDiv != null) {
                    if (mainDiv.childNodes.length != 0)
                        var removeImage = mainDiv.removeChild(mainDiv.firstChild);
                }*/
                if (pic.frameDom != null)
                {
                    pic.frameDom.empty();

                    if(!fullScreenState){
                        pic.frameDom.css({left: 0, top: 0})
                    }
                    else{
                        
                        //recenter based on the popupVideo size attributes if we are in popup mode
                        var left = Math.floor((locals.imageWidth - (videoWidth + locals.imagePadding)) / 2);
                        var top = Math.floor((locals.imageHeight - (videoHeight + locals.imagePadding)) / 2);
                        pic.frameDom.css({left: left, top: top});

                    }

                }

                //Append the video to the parent DIV	
                newVideoDiv.appendTo(pic.frameDom);

                //  Check whether video is HTML5 compatible in the browser
                var videoElementSupport = false;
                try 
                {
                    //videoElementSupport = !!document.createElement('video').canPlayType('video/mp4; codecs="avc1.58A01E, mp4a.40.2"');
                    var agent = navigator.userAgent.toLowerCase();
                    videoElementSupport = (agent.indexOf('iphone') != -1 || agent.indexOf('ipad') != -1)
                }
                catch(e)
                {
                    // ignore the error
                }

                if (videoElementSupport)
                {
                    var html5Video = $(document.createElement('video'))
                    .attr('controls', 'controls')
                    .attr('autoplay', 'true')
                    .attr('width', locals.imageWidth)
                    .attr('height', locals.imageHeight)
                    .attr('id', 'paplayer_' + pic.id)

                    var source = $(document.createElement('source'))
                    .attr('src',  pic.res[2].url)
                    .attr('type','video/mp4')

                    source.appendTo(html5Video);
                    html5Video.appendTo($("#" + pic.id).find(".full_img_frame"));
                }
                else
                {
                     swfobject.embedSWF(locals.settings.paplayer_path, videoContainerID, videoWidth-2/*locals.videoObjectWidth*/, videoHeight-2/*locals.videoObjectHeight*/, "9.0.115", "expressInstall.swf", flashvars, params, attributes);
                }
            } 

            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() {
                            //  As long as we're not currently disabled (like for a video) ...
                            if(!$(this).hasClass('disabled'))
                            {
                                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);
                }

                if (locals.settings.zoomToFit == true) { // zoomToFit
                    var wDiff = (locals.imageWidth - w);
                    var hDiff = (locals.imageHeight - h);
                    if (wDiff > hDiff) { // try to increase width
                        w = (locals.imageWidth);
                        if (w > pic.origW)
                            w = pic.origW;
                        h = Math.round(w * arH);
                    } else if (hDiff > wDiff) { // try to increase height
                        h = (locals.imageHeight);
                        if (h > pic.origH)
                            h = pic.origH;
                        w = Math.round(h * ar);
                    }

                    if (w > pic.origW) { // stretch prevention
                        w = pic.origW;
                        h = Math.round(w * arH);
                    }
                    if (h > pic.origH) { // stretch prevention
                        h = pic.origH;
                        w = Math.round(h * ar);
                    }
                }

                //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
                    .attr({ 'width': pic.width, 'height': pic.height })
                ;
                pic.frameDom
                    .css({ 'width': (pic.width + 0) + 'px', 'height': (pic.height + 0) + 'px' })
                ;

                //  center the video with it's parent 
                if (pic.mediaType != 'video' || pic.index != locals.picIndex) {
                    pic.frameDom
                        .css({ 'left': pic.left + 'px', 'top': pic.top + 'px' })
                    ;
                }
                else
                {
                    
                    pic.frameDom
                        .css({ 'left': '0', 'top': '0' })
                    ;
                }
            }

            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'));
                    }
                }
            }

            // used to determine if the current collection is in the background. used primarily for optimizations
            function isInBackground() {
                return ($('#wst_album_popup:visible').length != 0) && locals.meId != "wst_album_popup";
            }

            locals.lastImageWidth = 0;
            locals.lastResize = new Date().getTime() - 5000;
            function resize() {
                var newInnerWidth = locals.me.innerWidth();
                if (newInnerWidth <= 0 || locals.pics.length == 0) {
                    return; // not yet ready
                }

                var lastResize = new Date().getTime();
                var lastResizeDiff = lastResize - locals.lastResize;
                if (lastResizeDiff < 2000 && isInBackground() == true) { // we only support lazy-loader logic for background (non-visible) collections for optimization purposes
                    resizeAsync(lastResizeDiff + 50); // try again, later
                    return;
                }

                locals.lastResize = lastResize;

                if (locals.resizeAsyncTimer != null) { // if resize is being performed, make sure a timer is not going to tick again
                    try { clearTimeout(locals.resizeAsyncTimer); } catch(e) {}
                    locals.resizeAsyncTimer = null;
                }

                var heightChanged = false;
                if (locals.settings.imageHeight == null) { // recalc image height
                    var newImageHeight = (window.innerHeight != undefined ? window.innerHeight : document.documentElement.clientHeight != undefined ? document.documentElement.clientHeight : document.body.clientHeight) - locals.settings.frameWidth/* - imagePadding*/;
                    //console.log('newImageHeight: ' + newImageHeight + ' document.body.clientHeight:' + (window.innerHeight != undefined ? window.innerHeight : document.documentElement.clientHeight != undefined ? document.documentElement.clientHeight : 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) {
                        //console.log('thumbs height: ' + locals.thumbsSection.outerHeight(true));
                        newImageHeight -= locals.thumbsSection.outerHeight(true);
                    }
                    //console.log('newImageHeight: ' + newImageHeight + ' document.body.clientHeight:' + (window.innerHeight != undefined ? window.innerHeight : document.body.clientHeight));
                    if (locals.sliderBar != null) {
                        //console.log('sliderBar height: ' + locals.sliderBar.outerHeight(true));
                        newImageHeight -= locals.sliderBar.outerHeight(true);
                    }
                    if (locals.titleBar != null) {
                        //console.log('titleBar height: ' + locals.titleBar.outerHeight(true));
                        newImageHeight -= locals.titleBar.outerHeight(true);
                    }
                    if (locals.notes != null) {
                        //console.log('notes height: ' + locals.notes.outerHeight(true));
                        newImageHeight -= locals.notes.outerHeight(true);
                    }
                    if (locals.menu_placeholder != null) {
                        //console.log('menu_placeholder height: ' + locals.menu_placeholder.outerHeight(true));
                        newImageHeight -= locals.menu_placeholder.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 && locals.lastImageWidth == locals.imageWidth) {
                    updateMenu();
                    return; // nothing more to do
                }

                //console.log(locals.meId + '] resize START heightChanged: ' + heightChanged + ' newInnerWidth: ' + newInnerWidth + ' innerWidth: ' + locals.innerWidth + ' lastImageWidth: ' + locals.lastImageWidth + ' imageWidth: ' + locals.imageWidth);

                locals.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);
                } else {
                    locals.imageWidth = Math.ceil(locals.imageHeight * locals.settings.aspect.xRatio); // custom aspect
                }

                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.thumbnailsWidth + locals.settings.thumbnailSpacing + locals.settings.thumbnailBorder + locals.settings.thumbnailBorder));
                    if (locals.settings.thumbnailNav == true) {
                        if (locals.maxThumbWidth <= locals.thumbsWidth) { // if only one page is available, no need to show navs
                            locals.thumbsNavLeft.hide();
                            locals.thumbsNavRight.hide();
                        } else {
                            locals.thumbsWidth -= ((locals.settings.thumbnailSpacing * 4) + (locals.thumbsNavLeft.width() * 2));
                            locals.thumbsNavLeft.show();
                            locals.thumbsNavRight.show();
                        }
                    }
                    locals.thumbsParent.css('width', locals.thumbsWidth + 'px');
                    locals.thumbs.css('width', locals.maxThumbWidth + 'px');
                }

                //console.log(locals.meId + '] resize END innerWidth: ' + locals.innerWidth + ' maxWidth: ' + locals.maxWidth);

                if (locals.sliderBar != null) {
                    locals.sliderWidth = locals.sliderBar.width();
                    if (locals.thumbs != null && locals.settings.thumbnailNav == true)
                        locals.sliderWidth = locals.thumbsWidth;
                    if (locals.maxWidth > 0)
                        locals.sliderViewWidth = Math.ceil((newInnerWidth / locals.maxWidth) * locals.sliderWidth);
                    else
                        locals.sliderViewWidth = 15;
                    if (locals.sliderViewWidth < 15)
                        locals.sliderViewWidth = 15;
                    locals.sliderBar
                        .css('width', locals.sliderWidth + 'px')
                    ;
                    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(timeout) {
                if (locals.resizeAsyncTimer != null) {
                    clearTimeout(locals.resizeAsyncTimer);
                }

                locals.resizeAsyncTimer = setTimeout(resize, typeof timeout != 'undefined' ? timeout : 100);
            }

            function updateStatus(explicitStatus) {
                var pic = locals.pics[locals.picIndex];
                if (locals.loadCalled == true) {
                    if (locals.pics.length == 0) {
                        if (locals.settings.emptyAlbumHtml)
                            locals.loadingPanel.show().html(locals.settings.emptyAlbumHtml);
                        else
                            locals.me.hide();
                        return;
                    }
                }

                if (pic != null && pic.imgDom == null) {
                    locals.loadingPanel.show();
                }
                else if (locals.loadCalled == true) {
                    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 && pic.mediaType == 'image') {
                    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();
                var origW = w;
                var origH = h;
                pic.origThumbW = origW;
                pic.origThumbH = origH;

                // QC112320 - Animated Slideshow disappears after first load in IE7 and IE8
                // This code is 100% valid, however, in IE7/8 with thumbnails enabled and more than 15
                // or so items in gallery, causes the javascript engine to stop functioning through
                // subsequent page loads. In other words, we're somehow crashing javascript. The ACTUAL
                // line causing the failure is simply updating res.height to the new value... This is
                // a bug in IE (though I could not track down an article that mentions this vulnerability).
                // Disabling the optimization is the fix, and should impact performance very little if any during loads.
                //resUpdateCache(resPicFindIndex(pic, o.attr('src')), h);

                var ar = w / h;
                var arH = h / w;
                if (h > locals.settings.thumbnailsHeight) {
                    h = locals.settings.thumbnailsHeight;
                    w = Math.round(h * ar);
                }

                if (w > locals.settings.thumbnailsWidth) { // width is greater than allowed, resize
                    w = locals.settings.thumbnailsWidth;
                    h = Math.round(w * arH);
                }

                if (locals.settings.zoomToFitThumbs == true) { // zoomToFit
                    var wDiff = (locals.settings.thumbnailsWidth - w);
                    var hDiff = (locals.settings.thumbnailsHeight - h);
                    if (wDiff > hDiff) { // try to increase width
                        w = (locals.settings.thumbnailsWidth);
                        if (w > origW)
                            w = origW;
                        h = Math.round(w * arH);
                    } else if (hDiff > wDiff) { // try to increase height
                        h = (locals.settings.thumbnailsHeight);
                        if (h > origH)
                            h = origH;
                        w = Math.round(h * ar);
                    }

                    if (w > origW) { // stretch prevention
                        w = origW;
                        h = Math.round(w * arH);
                    }
                    if (h > origH) { // stretch prevention
                        h = origH;
                        w = Math.round(h * ar);
                    }
                }

                var l = Math.floor((locals.settings.thumbnailsWidth - w) / 2);
                var t = Math.floor((locals.settings.thumbnailsHeight - 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;
                }

                if (pic.mediaType != 'video' || pic.index != locals.picIndex) {
                    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' })
                ;
                if (pic.mediaType != 'video' || pic.index != locals.picIndex) {
                    pic.frameDom
                        .hide()
                        .append(pic.imgDomLoad)
                    ;
                }
                else {
                    pic.imgDom = pic.frameDom;
                }
                pic.dom
                    .empty()
                    .append(pic.frameDom)
                ;

                if (pic.mediaType != 'video' || pic.index != locals.picIndex) {
                    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);
                    }
                }
            }

            function preload(forceLoad) {
                
                //Suffix to use for each video thumbnail. This forms the css class for the "play" image
                var playClassSuffix = {'50': 'small', '65': 'med', '75': 'med', '100': 'large'};

                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.thumbnailsWidth);

                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[locals.settings.thumbnailIndex < pic.res.length ? locals.settings.thumbnailIndex : (pic.res.length - 1)].url })
                            ;

                        if(pic.mediaType == "video"){
                            var playImg = $(document.createElement("span"));
                            //playimg is the div for the play arrow. depending on the thumbnail size, the css class is different
                            playImg.addClass('play_img_' + playClassSuffix[locals.settings.thumbnailsHeight] );
                            pic.thumbDom.append(playImg);

                        }
                        

                        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];
                //console.log(locals.meId + '] render idx: ' + locals.picIndex + ' pic: ' + pic + ' pic.imgDom: ' + (pic ? pic.imgDom : null));
                if (pic == null)
                    return; // should only occur when no pics

                updateStatus();
                
                if (locals.animation != null)
                    locals.animation.stop(true, true);
                    
                var ui_fx = $('.ui-effects-wrapper', pic.dom); // jquery/ui fix
                if (ui_fx.length > 0) {
                    var children = ui_fx.children();
                    children.remove();
                    pic.frameDom.append(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';

                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) {
                    var oldLeft = 0;
                    if (typeof locals.thumbLeft != 'undefined')
                        oldLeft = locals.thumbLeft;
                    locals.thumbLeft = ((locals.settings.thumbnailsWidth + locals.settings.xPadding + locals.settings.borderWidth) * locals.picIndex * -1) + Math.round(locals.thumbsWidth / 2) - Math.round(locals.settings.thumbnailsWidth / 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)
                        ;
                        if (locals.settings.thumbnailTooltip == true && locals.thumbsTooltip.is(':visible') == true) {
                            var tipleft = (locals.thumbsTooltip.position().left + (locals.thumbLeft - oldLeft));
                            locals.thumbsTooltip
                                .stop(true, true)
                                .animate({'left': tipleft + 'px'}, locals.slideSpeed, easeType)
                            ;
                        }
                    }
                    else {
                        locals.thumbs
                            .stop(true, false)
                            .css('left', locals.thumbLeft + 'px')
                        ;
                        if (locals.settings.thumbnailTooltip == true && locals.thumbsTooltip.is(':visible') == true) {
                            var tipleft = (locals.thumbsTooltip.position().left + (locals.thumbLeft - oldLeft));
                            locals.thumbsTooltip
                                .stop(true, false)
                                .css({'left': tipleft + '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
                        .stop(true, false)
                        .css('left', new_left + 'px')
                    ;

                    if (locals.sliderBar != null) {
                        locals.sliderView
                            .stop(true, false)
                            .css('left', locals.sliderPos + 'px')
                        ;
                    }
                }

                //var fullScreenState = ($('#wst_album_popup:visible').length != 0);
                //Embed video file (if any)
                if (pic.mediaType == 'video') {
                    embedVideo(pic);
                }

                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).attr('title', pic.title);
                }

                if (locals.notes != null) {
                    locals.notes.html(pic.notes).attr('title', pic.notes);
                }

                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' && fx.length > 0) {
                    //console.log(locals.meId + '] rendering: ' + pic.index + ' ' + pic.width + 'x' + pic.height + ' imgDom: ' + pic.imgDom + ' frameDom: ' + pic.frameDom);
                    if (pic.mediaType != 'video' && pic.width != null && pic.frameDom != null && pic.imgDom != null) {
                        pic.frameDom
                            .removeAttr('style')
                            .css({ 'background-color': 'transparent', 'padding': locals.settings.imagePadding + 'px', 'left': pic.left + 'px', 'top': pic.top + 'px', 'width': pic.width + 'px', 'height': pic.height + 'px' })
                        ;
                        if (pic.imgDom.parent().attr('class') != 'full_img_frame') { // jquery/ui fix
                            pic.imgDom.remove();
                            pic.frameDom.append(pic.imgDom);
                        }
                        
                        locals.animation = pic.imgDom;

                        var fxOption = fxOptions[fx];
                        pic.imgDom
                            .show(fx, fxOption, locals.fxSpeed, function() {
                                if (locals.destroyed == true)
                                    return;

                                //var pi = $(this).data('pic');
                                //console.log('] 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) {
                                        var children = ui_fx.children();
                                        children.remove();
                                        pic.frameDom.append(children);
                                        ui_fx.remove();
                                    }

                                    pic.imgDom
                                        .removeAttr('style')
                                    ;

                                    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' })
                                    ;

                                    if (pic.imgDom.parent().attr('class') != 'full_img_frame') { // jquery/ui fix
                                        pic.imgDom.remove();
                                        pic.frameDom.append(pic.imgDom);
                                    }
                                }
                            })
                        ;
                    }
                }

                //  Determine the media type:
                switch (pic.mediaType) 
                {
                    case "video":
                        //  If it's currently a video, disable the speed selection:
                        me.find(".nav_speed_setting, .nav_speed_setting_sm, .nav_speed_active_setting, .nav_speed_active_setting_sm").addClass('disabled');
                        break;
                    default:
                        //  Otherwise, enable the speed selection:
                        me.find(".nav_speed_setting, .nav_speed_setting_sm, .nav_speed_active_setting, .nav_speed_active_setting_sm").removeClass('disabled');
                        break;
                }
            }

            function imageClick(pic, e) {
                stopVideo();

                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':
                        // Hide the original non full screen view
                        var originalAlbumId = '#' + locals.meId;

                        if (e) e.stopPropagation();
                        
                        var popupSettings = $.extend(true, {}, locals.settings, { autoShow: true, frameWidth: 0, imageClickBehavior: 'next', preload: 1, picIndexToSelect: pic.index, originalAlbumId: originalAlbumId, afterClose: function() { render(); } });
                        popupSettings.picsToLoad = locals.pics;
                        locals.me
                            .wstAlbumPopup(locals.uri, popupSettings)
                        ;
                        hideBlockingNodes();
                        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;
            }

            function thumbnailTooltipShow(pic) {
                if (locals.settings.thumbnails == false || locals.settings.thumbnailTooltip == false || typeof pic.origThumbW == 'undefined')
                    return;

                var w = pic.origThumbW;
                var h = pic.origThumbH;
                var ar = w / h;
                var arH = h / w;
                if (w > 160) {
                    w = 160;
                    h = Math.round(w * arH);
                }
                if (h > 120) {
                    h = 120;
                    w = Math.round(h * ar);
                }
                //var pl = locals.thumbsParent.position().left; // doesn't calc margin properly in all browsers... jQuery bug!!!
                var pl = (locals.settings.thumbnailNav == true && locals.thumbsNavLeft.is(':visible') == true) ? ((locals.settings.thumbnailSpacing * 2) + 20) : 0;
                var l = pl + pic.thumbDom.position().left + locals.thumbs.position().left + locals.settings.thumbnailSpacing + Math.round((locals.settings.thumbnailsSize / 2) - (w / 2)) - locals.settings.thumbnailSpacing;
                if (l < 0)
                    l = 0;
                if (l > (locals.innerWidth - w))
                    l = (locals.innerWidth - w);
                var t = 0 - h - locals.settings.thumbnailSpacing - locals.settings.thumbnailSpacing - 7;
                if (locals.settings.thumbnailsPosition == 'top')
                    t = locals.thumbsHeight;

                var img = $('<img border="0" />')
                    .attr('src', pic.thumbDom.children('img').attr('src'))
                    .css({'width': w + 'px', 'height': h + 'px'})
                ;
                locals.thumbsTooltipImg
                    .empty()
                    .append(img)
                ;
                locals.thumbsTooltip
                    .stop(true, false)
                    .css({'left': l + 'px', 'top': t + 'px'})
                    .show()
                ;
                if ($.browser.msie && $.browser.version <= 7)
                    locals.thumbsTooltip
                        .css('width', (w + locals.settings.thumbnailSpacing + 1) + 'px')
                    ;
            }

            function thumbnailTooltipHide() {
                if (locals.settings.thumbnails == false || locals.settings.thumbnailTooltip == false)
                    return;

                locals.thumbsTooltip.hide();
            }

            locals.loadPicsTmp = null;
            function loadPicsAsync(tmpPics) {
                locals.loadPicsTmp = tmpPics;
                setTimeout(function() { loadPics(tmpPics); }, 100);
            }

            function loadPics(tmpPics) {
                locals.loadCalled = true;
                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++) {
                        var res = { index: locals.resources.length, height: null };
                        if (settings.resources != null && settings.resources.length > locals.resources.length)
                            res.height = settings.resources[locals.resources.length].height;
                        locals.resources.push(res);
                    }
                }

                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({ 'border-width': locals.settings.thumbnailBorder + 'px', 'left': (i * (locals.settings.thumbnailsWidth + locals.settings.thumbnailBorder + locals.settings.thumbnailBorder + locals.settings.thumbnailSpacing)) + 'px', 'width': locals.settings.thumbnailsWidth + 'px', 'height': locals.settings.thumbnailsHeight + 'px' })
                            ;

                        
                        locals.thumbs.append(pic.thumbDom);
                    }
                }

                // config full_img_frame events
                $('#' + locals.meId + ' .full_img_frame 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;

                            slideShowStop();

                            var pic = locals.pics[$(this).data('pic')];
                            if (pic == null || pic.dom == null)
                                return;
                            var oldPic = locals.pics[locals.picIndex];
                            locals.picIndex = pic.index;
                            stopVideo(oldPic);
                            slideShowStop();
                            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')
                                ;

                                thumbnailTooltipShow(pic);
                            }
                        })
                        .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')
                                ;

                                thumbnailTooltipHide();
                            }
                        })
                    ;

				if(locals.settings != null)
				{
					//Check if we need to disable.
					if(locals.settings.disableRightClick == true)
					{
						//Only stop the right clicking of the images the plugin provides.  Using namespace and scope.
						$('#' + locals.meId + ' .thumb_img, #' + locals.meId + ' .full_img_frame')
							.live("contextmenu." + locals.meId , function (e) {
								return false;
							});
					}
				}
				
                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;

                updateStatus();

                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
                            , notes: pic.notes
                            , width: null
                            , origW: null
                            , imgDom: null
                            , mediaType: pic.mediaType
                    };

                    if (pic.res.length > 0)
                        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.media.length; i++) {
                        var tmp = json.media[i];
                        var pic = {
                            res: []
                                , title: (tmp.title != null ? tmp.title : '')
                                , notes: (tmp.notes != null ? tmp.notes : '')
                                , width: null
                                , origW: null
                                , imgDom: null
								, mediaType: (tmp.mediaType != null ? tmp.mediaType : 'image')
                        };

                        var prev_url = '';
                        if (tmp.res != null && tmp.res.length > 0) {
                            for (i2 = 0; i2 < tmp.res.length; i2++) {
                                var tmp2 = tmp.res[i2];
                                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) {
                                prev_url = tmp.smallUrl;
                                pic.res.push({ url: tmp.smallUrl });
                            }
                            if (tmp.largeUrl != null) {
                                prev_url = tmp.largeUrl;
                                pic.res.push({ url: tmp.largeUrl });
                            }
                            if (tmp.url != null) {
                                prev_url = tmp.url;
                                pic.res.push({ url: tmp.url });
                            }
                        }

                        if (pic.res.length > 0)
                            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 = [];

                    var picsRoot = $('pics', xml);
                    if (picsRoot.attr('allowDownload') == 'false')
                        locals.settings.disableRightClick = true;
                    var picsXml = $('pic', xml);

                    picsXml
                            .each(function() {
                                var picElement = $(this);
                                var pic = {
                                    res: []
                                    , title: picElement.children('title').text()
                                    , notes: picElement.children('notes').text()
                                    , width: null
                                    , origW: null
                                    , imgDom: null
									, mediaType: picElement.children('mediaType').text()
                                };

                                if (pic.title == null)
                                    pic.title = '';
                                if (pic.notes == null)
                                    pic.notes = '';
                                if (!pic.mediaType)
                                    pic.mediaType = 'image';

                                var prev_url = '';

                                picElement.children('res')
                                    .each(function() {
                                        var res = { url: $(this).children('url').text() };
                                        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) {
                                        prev_url = tmp.smallUrl;
                                        pic.res.push({ url: tmp.smallUrl });
                                    }
                                    if (tmp.largeUrl != null) {
                                        prev_url = tmp.largeUrl;
                                        pic.res.push({ url: tmp.largeUrl });
                                    }
                                    if (tmp.url != null) {
                                        prev_url = tmp.url;
                                        pic.res.push({ url: tmp.url });
                                    }
                                }

                                if (pic.res.length > 0)
                                    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.destroyed == true)
                    return;
                locals.destroyed = true;

                stopVideo();

                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;
                }
                
                // kill animations
                if (locals.animation != null)
                    locals.animation.stop(true, true);
                if (locals.thumbs != null)
                    locals.thumbs.stop(true, false);
                if (locals.container != null)
                    locals.container.stop(true, false);
                if (locals.sliderBar != null)
                    locals.sliderView.stop(true, false);

                $('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
                $('.full_img_frame img').die('click.' + locals.meId).die('mouseover.' + locals.meId).die('mouseout.' + locals.meId).die("contextmenu." + locals.meId);
                $('.thumb_img').die('click.' + locals.meId).die('mouseover.' + locals.meId).die('mouseout.' + locals.meId).die("contextmenu." + locals.meId);

                if (locals.settings && locals.settings.overlayMode == true) { // restore previous overflow settings
                    locals.meBody.parent('html').css({ 'height':''});
                    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.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.ui_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.uiFadeEnabled == false || ($.browser.msie == true && $.browser.version < 6)) {
                        if (locals.thumbs != null)
                            locals.thumbsSection.css('visibility', 'hidden');
                        if (locals.sliderBar != null)
                            locals.sliderBar.css('visibility', 'hidden');
                        locals.menu
                                .css('visibility', 'hidden');
                            ;
                        locals.menu_overlay
                                .css('visibility', 'hidden');
                            ;
                    /*}
                    else {
                        if (locals.thumbs != null)
                            locals.thumbsSection
                                .stop(true, false)
                                .fadeOut(1000)
                            ;
                        if (locals.sliderBar != null)
                            locals.sliderBar
                                .stop(true, false)
                                .fadeOut(1000)
                            ;
                        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.loadCalled == true && locals.pics.length == 0) {
                    locals.menu.css('visibility', 'hidden');
                    if (locals.sliderBar != null)
                        locals.sliderBar.css('visibility', 'hidden');
                    return;
                }

                if (locals.settings.uiFadeDelay != null) {
                    locals.hideMenusTimer = setInterval(hideMenusCallback, locals.settings.uiFadeDelay);
                }

                if (locals.menusVisible == true) {
                    return;
                }

                locals.menusVisible = true;
                //if (locals.settings.uiFadeEnabled == false || ($.browser.msie == true && $.browser.version < 6)) {
                    if (locals.thumbs != null)
                        locals.thumbsSection.css('visibility', 'visible');
                    if (locals.sliderBar != null)
                        locals.sliderBar.css('visibility', 'visible');
                    locals.menu.css('visibility', 'visible');
                    locals.menu_overlay.css('visibility', 'visible');
                /*}
                else { // standard
                    if (locals.thumbs != null)
                        locals.thumbsSection
                            .stop(true, false)
                            .fadeIn(1000)
                        ;
                    if (locals.sliderBar != null)
                        locals.sliderBar
                            .stop(true, false)
                            .fadeIn(1000)
                        ;
                    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.uiFadeDelay != null) {
                var lastMouseMove = null;
                locals.hideMenusTimer = setInterval(hideMenusCallback, locals.settings.uiFadeDelay);
                var activator_context = locals.settings.menuActivateFromAnywhere ? $(document) : locals.me;
                activator_context.bind('mousemove.' + locals.meId, function(e) {
                    //console.log('e.client: ' + e.clientX + 'x' + e.clientY);
                    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;

                    if (locals.settings.menuVisible || locals.settings.thumbnails)
                    {
                        showMenu();
                    }
                });
            }

            updateMenu(true);

            if (!(locals.settings.menuVisible))
            {
                locals.menu.empty();
                locals.menu.removeClass();
                locals.menu_overlay.empty();
                locals.menu_overlay.removeClass();
            }

            // 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);


/* jquery.photoviewer.js (jQuery PhotoViewer)
* Created by Aaron Silvas
* Copyright (c) 2010 GoDaddy.com
*/
; (function($) {

    /* TODO!!!

    * (LP) Switching between auto/scroll/page in IE8 (probably others) does not recalc height properly under all situations
    
    */

    $.fn.PhotoViewer = function(uri, options) {
        var defaults = {
            dataType: 'xml', /* default is xml, but json is also supported */

            imageSize: { width: 260, height: 200 }, /* { width: 260, height: 200 } in pixels. ImageSize and/or rows REQUIRED. */
            rows: null, /* vertical rows, or null if auto. Ignored if navigation is set to 'auto'. */
            columns: null, /* horizontal columns, or null if auto. If specified, imageSize will be adjusted accordingly */
            shuffle: false, /* shuffle/randomize image order */
            show: { filename: false, title: false, dimensions: false, notes: false }, /* information to show */
            navigation: { flow: 'auto', pagesToShow: 5 }, /* flow: 'auto' (grow to fit), 'scroll', 'page' */
            resourceIndex: 1, /* index of resource url to use in feed */
            resourceLoadCount: 2, /* number of resources that can load at a time -- should be 1-3 */
            resources: [{height: 90},{height: 300},{height: 1200}], /* optionally define heights of the various resources */
            prefetchRows: 1, /* number of rows to prefetch beyond visible range */

            imagePadding: 2, /* padding around image, in pixels */
            imageClickBehavior: 'popup', /* options include: 'popup', or null to do nothing */

            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 */

            menu: { height: 27 }, /* menu.height is in pixels */

            emptyAlbumHtml: 'Album Empty', /* text or html to render if album is empty, or null to display nothing */

            popupSettings: {}, /* extensions for popup */

            aspect: { x: 4, y: 3 }, /* aspect ratio for rendering purposes. 4:3 is standard landscape mode */
            zoomToFit: false, /* fill area with image if true. will NOT stretch, however */

            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. */
            onLoad: null, /* once the plugin is fully ready and loaded this callback will be invoked */
            disableRightClick: false
        };

        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 me = $(this);

        var meId = me.attr('id');
        if (meId == null || meId.length == 0) {
            meId = 'pv' + Math.round(Math.random() * 65535);
            me.attr('id', meId);
        }

        var locals = $.fn.PhotoViewer.instances[meId];
        if (locals != null) {
            return locals.fn(locals, uri, settings);
        }

        locals = $.fn.PhotoViewer.instances[meId] = { me_this: this, fn: function(locals, uri, settings) {
            locals.me = $(locals.me_this);
            locals.meId = locals.me.attr('id');
            switch (uri.toLowerCase()) {
                case 'piccount':
                    return locals.pics.length;
                case 'getpics':
                    return locals.pics;
                case 'dump':
                    return locals;
                case 'destroy':
                    destroy(locals);
                    delete $.fn.PhotoViewer.instances[locals.meId];
                    return locals.me;
            };
            if (locals.me.is('.pviewer') == true) {
                destroy(locals);
                //return locals;
            }

            locals.me = $('#' + locals.meId); // sometimes the older me pointer we hold onto is actually gone due to other software deleting us
            locals.meBody = $('body:first');
            locals.meParent = locals.me.parent();

            settings.aspect.xRatio = settings.aspect.x / settings.aspect.y;
            settings.aspect.yRatio = settings.aspect.y / settings.aspect.x;
            locals.settings = settings;

            locals.SIG = Math.round(Math.random() * 100);
            locals.pics = [];
            locals.resources = [];
            locals.picsXml = null;
            locals.picIndex = 0;
            locals.lastPic = null;
            locals.loadIndex = 0;
            locals.isLoaded = false;
            locals.picsLoading = 0;
            locals.picsLoaded = 0;
            locals.isReady = false;
            locals.imagePadding = locals.settings.imagePadding * 2;
            locals.show = (locals.settings.show && (locals.settings.show.filename || locals.settings.show.title || locals.settings.show.dimensions || locals.settings.show.notes)) ? true : false;
            locals.pageWidth = locals.pageHeight = 0;

            $(window)
                .bind('scroll.' + locals.meId, function() { smartLoader(); updateMenu(); })
            ;

            // initialize container, etc
            locals.container = $(document.createElement('div'))
                .addClass('pv-container')
            ;
            locals.container_parent = $(document.createElement('div'))
                .addClass('pv-containerp')
                .append(locals.container)
                .bind('scroll.' + locals.meId, function() { smartLoader(); updateMenu(); })
            ;
            locals.main = $(document.createElement('div'))
                .addClass('pv-main')
            ;

            locals.menuContent = $(document.createElement('div'))
                .addClass('pv-menu-content')
                .css('height', locals.settings.menu.height + 'px')
                .append('<span class="pv-loading">Loading...</span>')
            ;
            locals.menu = $(document.createElement('div'))
                .addClass('pv-menu')
                .css('height', locals.settings.menu.height + 'px')
                .append(locals.menuContent)
                .append($('<div class="pv-menu-overlay">&nbsp;</div>').css('height', locals.settings.menu.height + 'px'))
            ;

            locals.main
                .append(locals.container_parent)
                .append(locals.menu)
            ;

            locals.me
                .empty()
                .show()
                .addClass('pviewer')
                .append(locals.main)
            ;
            $('.pv-menu-page')
                .live('click.' + locals.meId, function(e) {
                    var me = $(this);
                    if (me.closest('.pviewer').attr('id') != locals.meId)
                        return;
                    var pg_clicked = parseInt(me.text());

                    var newTop = ((pg_clicked - 1) * ((locals.imageSize.height + locals.imagePadding) * locals.rows));

                    locals.container_parent[0].scrollTop = newTop;

                    updateMenu();

                    smartLoader();
                })
            ;

            function resGet(pic) {
                var i = pic.res.length - 1 - locals.settings.resourceIndex;
                if (i < 0)
                    i = 0;
                else if (i >= pic.res.length)
                    i = pic.res.length - 1;
                return pic.res[i];
            }

            function resGetUrl(pic) {
                var res = resGet(pic);
                if (res == null || res.url == null)
                    return '';
                return res.url;
            }

            function resPicFindIndex(pic, url) {
                var resI;
                for (resI = 0; resI < pic.res.length; resI++) {
                    if (pic.res[resI].url == url)
                        return resI;
                }
            }

            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();
                }

                // calc new width/height
                var w = pic.origW;
                var h = pic.origH;
                var ar = w / h;
                var arH = h / w;

                if (h > (locals.imageSize.height)) {
                    h = (locals.imageSize.height);
                    w = Math.round(h * ar);
                }

                if (w > (locals.imageSize.width)) { // width is greater than allowed, resize
                    w = (locals.imageSize.width);
                    h = Math.round(w * arH);
                }

                if (locals.settings.zoomToFit == true) { // zoomToFit
                    var wDiff = (locals.imageSize.width - w);
                    var hDiff = (locals.imageSize.height - h);
                    if (wDiff > hDiff) { // try to increase width
                        w = (locals.imageSize.width);
                        if (w > pic.origW)
                            w = pic.origW;
                        h = Math.round(w * arH);
                    } else if (hDiff > wDiff) { // try to increase height
                        h = (locals.imageSize.height);
                        if (h > pic.origH)
                            h = pic.origH;
                        w = Math.round(h * ar);
                    }

                    if (w > pic.origW) { // stretch prevention
                        w = pic.origW;
                        h = Math.round(w * arH);
                    }
                    if (h > pic.origH) { // stretch prevention
                        h = pic.origH;
                        w = Math.round(h * ar);
                    }
                }

                //  center the image vertically/horizontally with its parent

                pic.width = w;
                pic.height = h;

                pic.left = Math.floor((locals.imageSize.width - (pic.width)) / 2);
                pic.top = Math.floor((locals.imageSize.height - (pic.height)) / 2);

                // ok, finally, lets init image
                pic.imgDom
                    .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' })
                ;

                //console.log('updatePicImage[' + pic.index + '] size: ' + pic.width + 'x' + pic.height + ' pos: ' + pic.left + 'x' + pic.top);
            }

            function updateMenu() {
                if (locals.isReady == false || locals.isLoaded == false)
                    return;

                if (locals.pics.length == 0) {
                    if (locals.settings.emptyAlbumHtml == null)
                        locals.menu.hide();
                    else
                        locals.menuContent.children('.pv-loading').html(locals.settings.emptyAlbumHtml);
                    return;
                }

                if (locals.settings.navigation.flow == 'auto') {
                    locals.menu.hide();
                    return;
                }

                // .position() fails in IE6 only, and only after the plugin is re-initialized a 2nd time...
                try {
                    var pg = Math.ceil((Math.abs(locals.container.position().top) - 10) / ((locals.imageSize.height + locals.imagePadding) * locals.rows)) + 1;
                    var pg_count = Math.ceil(locals.container.height() / ((locals.imageSize.height + locals.imagePadding) * locals.rows));
                } catch (e) {
                    return;
                }

                if (pg_count <= 1) {
                    locals.menu.hide();
                    return;
                }
                else
                {
                    locals.menu.show();
                }

                var pagesShown = 0;

                // temporary until workaround to hide selection in firefox can be implemented
                locals.menuContent.empty();

                var low_pg = pg - Math.floor((locals.settings.navigation.pagesToShow - 1) / 2);
                var high_pg = 1;
                for (var i = low_pg; pagesShown < locals.settings.navigation.pagesToShow && i <= pg_count; i++) {
                    if (i < 1)
                        continue;
                    var el = locals.menuContent.find('a:eq(' + pagesShown + ')'); // flicker-reduction code (re-use existing)
                    if (el.length == 0) {
                        el = $('<a href="#" onclick="return false;"></a>');
                        locals.menuContent.append(el);
                    }
                    if (i == pg) { // current page
                        el.attr('class', 'pv-menu-page-cur').text(i);
                    }
                    else {
                        el.attr('class', 'pv-menu-page').text(i);
                    }
                    pagesShown++;
                    high_pg = i;
                }

                for (var i = pagesShown; i < locals.settings.navigation.pagesToShow; i++) {
                    locals.menuContent.find('a:eq(' + pagesShown + ')').remove();
                }

                if (low_pg > 1) {
                    if (low_pg > 2)
                        locals.menuContent.prepend('...');
                    locals.menuContent.prepend('<a href="#" onclick="return false;" class="pv-menu-page">1</a>');
                }

                if (high_pg < pg_count) {
                    if (high_pg < (pg_count - 1))
                        locals.menuContent.append('...');
                    locals.menuContent.append('<a href="#" onclick="return false;" class="pv-menu-page">' + pg_count + '</a>');
                }
            }

            function resizeWindow() {
                if (typeof (window.innerHeight) == 'number') {
                    locals.pageWidth = window.innerWidth;
                    locals.pageHeight = window.innerHeight;
                } else if (document.documentElement && (document.documentElement.clientHeight)) {
                    locals.pageWidth = document.documentElement.clientWidth;
                    locals.pageHeight = document.documentElement.clientHeight;
                } else if (document.body && (document.body.clientHeight)) {
                    locals.pageWidth = document.body.clientWidth;
                    locals.pageHeight = document.body.clientHeight;
                }
            }

            function resize() {
                if (locals.isLoaded == false)
                    return; // nothing to do
                if (locals.pics.length == 0) {
                    locals.main.css('height', '');
                    locals.container_parent.css('height', '');
                    locals.isReady = true;
                    updateMenu();
                    return;
                }
                var popup = $('body > #wst_album_popup:first');
                if ((popup.length > 0 && popup.css('display') != 'none'))
                    return; // ignore resize events while popup is showing, otherwise causes reloading
                var newInnerWidth = locals.me.innerWidth();
                var newInnerHeight = locals.me.innerHeight();
                if (newInnerWidth <= 0) {
                    return; // not yet ready
                }
                if (locals.settings.imageSize == null && newInnerHeight < 200) {
                    // auto-height requires a default image size
                    locals.settings.imageSize = { width: 260, height: 200 };
                }

                if (newInnerWidth == locals.innerWidth && locals.innerHeight != null && newInnerHeight == locals.innerHeight) {
                    return; // nothing more to do
                }

                locals.innerWidth = newInnerWidth;
                locals.innerHeight = newInnerHeight;

                for (var i = 0; i < locals.pics.length; i++) {
                    var pic = locals.pics[i];
                    if (pic == null)
                        continue; // ignore
                    pic.position = null; // reset
                }

                if (locals.isReady == true) { // reload if needed
                    if (locals.settings.columns == null)
                        return; // columns not explicit, do not reload

                    reload();
                    locals.container_parent[0].scrollTop = 0;
                }

                locals.imageSize = locals.settings.imageSize;
                locals.columns = null;
                locals.rows = null;
                if (locals.imageSize == null) {
                    if (locals.settings.columns == null && locals.settings.rows == null)
                    // use preset
                        locals.settings.columns = locals.settings.rows = 3;
                    else if (locals.settings.columns == null)
                    // use same as rows
                        locals.settings.columns = locals.settings.rows;
                    else if (locals.settings.rows == null)
                    // use same as columns
                        locals.settings.rows = locals.settings.columns;
                }
                if (locals.settings.columns != null) { // 1st priority
                    locals.columns = locals.settings.columns;
                    if (locals.imageSize == null) locals.imageSize = { width: 0, height: 0 };

                    locals.imageSize.width = Math.floor((locals.innerWidth - 1 - (locals.columns * locals.imagePadding) - (locals.settings.navigation.flow == 'scroll' ? 25 : 0) /* possible scrollbar */) / locals.columns);
                    locals.imageSize.height = Math.round(locals.imageSize.width * locals.settings.aspect.yRatio); // 4:3 aspect is default
                }
                if (locals.settings.rows != null) { // 2nd priority
                    locals.rows = locals.settings.rows;

                    if (locals.imageSize == null) locals.imageSize = { width: 0, height: 0 };
                    else locals.innerHeight = (locals.rows * (locals.imageSize.height + locals.imagePadding)) + locals.settings.menu.height;

                    locals.imageSize.height = Math.floor((locals.innerHeight - (locals.rows * locals.imagePadding) - locals.settings.menu.height) / locals.rows);
                }
                if (locals.imageSize == null) {
                    return; // should never be possible at this point
                }

                if (locals.columns == null) { // auto-detect columns
                    locals.columns = 0;
                    var x = (locals.settings.navigation.flow == 'scroll' ? 25 : 0) /* possible scrollbar */;
                    while (x < locals.innerWidth - (locals.imageSize.width + locals.imagePadding)) {
                        locals.columns++;
                        x += (locals.imageSize.width + locals.imagePadding);
                    }
                }
                if (locals.rows == null) { // auto-detect rows
                    locals.rows = 0;
                    var y = locals.settings.menu.height;
                    while (y < locals.innerHeight - (locals.imageSize.height + locals.imagePadding)) {
                        locals.rows++;
                        y += (locals.imageSize.height + locals.imagePadding);
                    }
                    if (locals.rows < 1)
                        locals.rows = 1;
                }

                if (locals.settings.navigation.flow != 'scroll') {
                    locals.menu.css('margin-right', (locals.innerWidth - (locals.columns * locals.imageSize.width) - ((locals.columns - 1) * locals.imagePadding)) + 'px');
                }

                render();

                if (locals.isReady == false) {
                    locals.isReady = true;

                    locals.imgInfo = $('body > .pv-img_info:first');
                    if (locals.imgInfo.length == 0) { // add new
                        locals.imgInfo = $('<div class="pv-img_info">&nbsp;</div>');
                        locals.meBody.append(locals.imgInfo);
                    }
                    locals.imgInfoOverlay = $('body > .pv-img_info_overlay:first');
                    if (locals.imgInfoOverlay.length == 0) { // add new
                        locals.imgInfoOverlay = $('<div class="pv-img_info_overlay">&nbsp;</div>');
                        locals.meBody.append(locals.imgInfoOverlay);
                    }

                    updateMenu();
                }

                smartLoader(true);
            }

            function resizeAsync() {
                if (locals.resizeAsyncTimer != null) {
                    clearTimeout(locals.resizeAsyncTimer);
                }

                locals.resizeAsyncTimer = setTimeout(resize, 30);
            }

            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) {
                    return;
                }

                locals.picsLoaded++;
                locals.picsLoading--;

                pic.dom.children('.pv-full_img_loading').remove();

                pic.imgDom = pic.imgDomLoad;
                pic.imgDomLoad = null;
                pic.imgDom.show();
                pic.frameDom.show();

                updatePicImage(pic);
                smartLoader(true);
            }

            function preloadErrorCallback(evt) {
                var idx = $(this).data('pic');
                var pic = locals.pics[idx];
                if (pic == null || pic.imgDomLoad == null)
                    return;

                pic.imgDomLoad.remove();
                pic.imgDomLoad = null;
                locals.picsLoading--;

                pic.dom.children('.pv-full_img_loading').text('Load failed');

                smartLoader(true);
            }

            function reload() {
                for (i = 0; i < locals.pics.length; i++) {
                    var pic = locals.pics[i];
                    pic.loading = false;
                    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;
                    }
                }
            }

            function loadPrimaryImageAsync(pic) {
                setTimeout(function() { loadPrimaryImage(pic); }, 30);
            }

            function loadPrimaryImage(pic) {
                var resUrl = resGetUrl(pic);

                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()
                    .bind('click.' + locals.meId, function(evt) {
                        if (evt.button != 0 || evt.ctrlKey || evt.shiftKey || evt.altKey)
                            return true;

                        var pic_idx = $(evt.target).data('pic');
                        var pic = locals.pics[pic_idx];
                        return imageClick(pic, evt);
                    })
                ;
                pic.frameDom = $(document.createElement('div'))
                    .addClass('pv-full_img_frame')
                    .css({ 'width': locals.imageSize.width + 'px', 'height': locals.imageSize.height + 'px' })
                    .hide()
                    .append(pic.imgDomLoad)
                    .bind('mouseover.' + locals.meId, function(e) { // show & update text
                        var div = $(e.target).closest('img');
                        if (div.length == 0)
                            return;
                        div.addClass('pv-img_over');
                        if (locals.show != true)
                            return;
                        var pic = locals.pics[div.data('pic')];
                        if (pic == null)
                            return;
                        var info = '';
                        if (locals.settings.show.filename == true) {
                            var url = resGetUrl(pic);
                            var i = url.lastIndexOf('/');
                            if (i > 0)
                                url = url.substr(i + 1);
                            info += '&nbsp;<font style="text-decoration:underline">' + url + '</font><br />';
                        }
                        if (locals.settings.show.title == true && pic.title != null && pic.title.length > 0) {
                            info += '&nbsp;<font style="">' + pic.title + '</font><br />';
                        }
                        if (locals.settings.show.dimensions == true) {
                            info += '&nbsp;<font style="">' + pic.origW + 'x' + pic.origH + '</font><br />';
                        }
                        if (locals.settings.show.notes == true && pic.notes != null && pic.notes.length > 0) {
                            info += pic.notes;
                        }
                        if (info.length == 0) {
                            locals.imgInfo.css('display', 'none');
                            locals.imgInfoOverlay.css('display', 'none');
                            locals.imgInfoSize = { Width: 0, Height: 0 };
                        }
                        else {
                            var left = locals.imgInfo.css('left');
                            locals.imgInfo.css({'display': 'block', 'left': '0', 'width': ''}).html(info);
                            locals.imgInfoOverlay.css({'display': 'block'});
                            locals.imgInfoSize = { Width: parseInt(locals.imgInfo.outerWidth()), Height: parseInt(locals.imgInfo.outerHeight()) };
                            if (locals.imgInfoSize.Width > (locals.pageWidth - 100)) {
                                locals.imgInfo.css('width', (locals.pageWidth - 100) + 'px');
                                locals.imgInfoSize = { Width: parseInt(locals.imgInfo.outerWidth()), Height: parseInt(locals.imgInfo.outerHeight()) };
                            }
                            showTooltip(e);
                        }
                    })
                    .bind('mouseout.' + locals.meId, function(e) { // hide
                        var div = $(e.target).closest('img');
                        if (div.length == 0)
                            return;
                        div.removeClass('pv-img_over');
                        if (locals.show != true)
                            return;
                        locals.imgInfo.css('display', 'none');
                        locals.imgInfoOverlay.css('display', 'none');
                    })
                ;
                if(options != null)
				{
					//Check if we need to disable.
					if(options.disableRightClick == true)
					{
						//Only stop the right clicking of the images the plugin provides.  Using namespace and scope.
						$('#' + locals.meId + ' .pv-full_img_frame')
							.live("contextmenu." + locals.meId, function (e) {
								return false;
							});
					}
				}
                if (locals.show == true) {
                    pic.frameDom
                        .bind('mousemove.' + locals.meId, function(e) {
                            showTooltip(e);
                        })
                    ;
                }

                pic.dom
                //.empty()
                    .append(pic.frameDom)
                ;

                pic.imgDomLoad
                    .attr('src', resUrl)
                ;

                if (pic.imgDomLoad == null)
                    ; // already loaded
                else if (pic.imgDomLoad[0].complete) {
                    preloadCallback(pic.imgDomLoad);
                }
            }

            function showTooltip(e)
            {
                if (locals.imgInfo == null || locals.imgInfoSize == null)
                    return;
                var x = e.pageX + 15;
                if ((x + locals.imgInfoSize.Width) > (locals.pageWidth - 50))
                    x = locals.pageWidth - 50 - locals.imgInfoSize.Width;
                locals.imgInfo.css({ left: x + 'px', top: (e.pageY + 15) + 'px' });
                locals.imgInfoOverlay.css({ width: locals.imgInfoSize.Width + 'px', height: locals.imgInfoSize.Height + 'px', left: x + 'px', top: (e.pageY + 15) + 'px' });
            }

            function firstTimeRenderCallback()
            {
                if (locals.innerWidth == locals.me.innerWidth())
                {
                    render(true);
                    updateMenu();
                }
                else {
                    resize();
                }
            }

            var firstRender = true;
            function render(forceLoad) {
                locals.container.empty();

                switch (locals.settings.navigation.flow) {
                    case 'scroll':
                        locals.innerHeight = (locals.rows * (locals.imageSize.height + locals.imagePadding)) + locals.settings.menu.height;
                        locals.container_parent.css({ overflow: 'auto', height: (locals.innerHeight - locals.settings.menu.height) + 'px' });
                        locals.main.css({ height: locals.innerHeight + 'px' });
                        break;
                    case 'page':
                        locals.innerHeight = (locals.rows * (locals.imageSize.height + locals.imagePadding)) + locals.settings.menu.height;
                        locals.container_parent.css({ overflow: 'hidden', height: (locals.innerHeight - locals.settings.menu.height) + 'px' });
                        locals.main.css({ height: locals.innerHeight + 'px' });
                        break;
                    default: // auto
                        locals.container_parent.css({ overflow: 'visible', height: 'auto' });
                        locals.main.css({ height: '100%' });
                        break;
                }

                if (firstRender)
                {
                     setTimeout(firstTimeRenderCallback, 30);
                     firstRender = false;
                     return;
                }

                for (var i = 0; i < locals.pics.length; i++) {
                    var pic = locals.pics[i];
                    if (pic == null)
                        continue;

                    pic.loadIndex = i;
                    var loading = $('<span class="pv-full_img_loading">Loading</span>');
                    pic.dom = $('<div class="pv-full_img"></div>').append(loading).css({ width: locals.imageSize.width + 'px', height: locals.imageSize.height + 'px', 'margin-right': locals.imagePadding + 'px', 'margin-bottom': locals.imagePadding + 'px' }).data('pic', pic.index);
                    //console.log('pic.dom ' + pic.dom.css('width') + 'x' + pic.dom.css('height'));
                    locals.container.append(pic.dom);

                    var loadingWidth = loading.width();
                    loading.css('left', Math.round((locals.imageSize.width / 2) - (loadingWidth / 2)) + 'px');
                }

                // update dimensions so reload does not keep getting called
                locals.innerWidth = locals.me.innerWidth();
                locals.innerHeight = locals.me.innerHeight();

                if (locals.settings.navigation.flow == 'scroll' || locals.settings.navigation.flow == 'page') {
                    locals.container.css('height', 'auto'); // reset before getting real height
                    pg_size = ((locals.imageSize.height + locals.imagePadding) * locals.rows);
                    pg_count = locals.container.height() / pg_size;
                    new_height = parseInt(Math.ceil(pg_count) * pg_size);
                    locals.container.css('height', new_height + 'px');
                }
            }

            function hideBlockingNodes(){
                try{
                    $('.fullscreen-hide').each(function(index, node){
                    
                        if($(node).is("iframe")){

                            if ( node.style ) {
					            var visibility = jQuery.css( node, "visibility" );

					            if ( visibility !== "hidden" && !jQuery.data( node, "prevvisibility" ) ) {
						            jQuery.data( node, "prevvisibility", visibility );
					            }
				            }
                            $(node).css("visibility", "hidden");
                        }
                        else{
                            $(node).hide();
                        }
                    });
                }catch(e){
                    //this happens when an iFrame is from a different domain.
                }
            }

            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 'popup':
                        if (e) e.stopPropagation();
                        var originalAlbumId = '#' + locals.meId;

                        var popupSettings = $.extend(true, {}, locals.settings.popupSettings, { autoShow: true, frameWidth: 0, imageClickBehavior: 'next', preload: 1, picIndexToSelect: pic.index, paplayer_path: locals.settings.paplayer_path });
                        popupSettings.picsToLoad = locals.pics;
                        $(this)
                            .wstAlbumPopup(uri, popupSettings)
                        ;
                        hideBlockingNodes();
                        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++) {
                        var res = { index: locals.resources.length, height: null };
                        locals.resources.push(res);
                    }
                }

                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('pv-full_img')
                    ;
                    pic.dom.data('pic', pic.index);

                    locals.container.append(pic.dom);
                    */
                }

                // config full_img events
                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;

                locals.isLoaded = true;
                if (locals.pics.length > 0)
                    locals.menuContent.empty();

                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
                            , notes: pic.notes
                            , width: null
                            , origW: null
                            , imgDom: null
                    };

                    if (pic.res.length > 0)
                        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 != null ? tmp.title : '')
                                , notes: (tmp.notes != null ? tmp.notes : '')
                                , width: null
                                , origW: null
                                , imgDom: null
								, mediaType: (tmp.mediaType != null ? tmp.mediaType : 'image')
                        };

                        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) {
                                prev_url = tmp.smallUrl;
                                pic.res.push({ url: tmp.smallUrl });
                            }
                            if (tmp.largeUrl != null) {
                                prev_url = tmp.largeUrl;
                                pic.res.push({ url: tmp.largeUrl });
                            }
                            if (tmp.url != null) {
                                prev_url = tmp.url;
                                pic.res.push({ url: tmp.url });
                            }
                        }

                        if (pic.res.length > 0)
                            tmpPics.push(pic);
                    }
                    loadPics(tmpPics);
                }
                    , error: function(req, textStatus, err) {
                        locals.menuContent.children('.pv-loading').html('Error loading image collection...');
                    }
                });
            }
            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 = [];

                    var picsRoot = $('pics', xml);
                    if (picsRoot.attr('allowDownload') == 'false')
                        locals.settings.popupSettings.disableRightClick = true;
                    picsXml = $('pic', xml);

                    picsXml
                            .each(function() {
                                var picElement = $(this);
                                var pic = {
                                    res: []
                                    , title: picElement.children('title').text()
                                    , notes: picElement.children('notes').text()
                                    , width: null
                                    , origW: null
                                    , imgDom: null
									, mediaType: picElement.children('mediaType').text()
                                };

                                if (pic.title == null)
                                    pic.title = '';
                                if (pic.notes == null)
                                    pic.notes = '';
                                if (!pic.mediaType)
                                    pic.mediaType = 'image';

                                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) {
                                        prev_url = tmp.smallUrl;
                                        pic.res.push({ url: tmp.smallUrl });
                                    }
                                    if (tmp.largeUrl != null) {
                                        prev_url = tmp.largeUrl;
                                        pic.res.push({ url: tmp.largeUrl });
                                    }
                                    if (tmp.url != null) {
                                        prev_url = tmp.url;
                                        pic.res.push({ url: tmp.url });
                                    }
                                }

                                if (pic.res.length > 0)
                                    tmpPics.push(pic);
                            })
                        ;

                    loadPics(tmpPics);
                }
                    , error: function(req, textStatus, err) {
                        // TODO!!! add retry logic
                        locals.menuContent.children('.pv-loading').html('Error loading image collection...');
                    }
                });
            }

            function attachResize() {
                resizeWindow();
                $(window)
                    .unbind('resize.' + locals.meId)
                    .bind('resize.' + locals.meId, resizeWindow)
                ;

                locals.resizeCheckTimer = setInterval(resize, 1000);
            }

            function destroy(locals) {
                if (locals.resizeAsyncTimer != null) {
                    clearTimeout(locals.resizeAsyncTimer);
                    locals.resizeAsyncTimer = null;
                }
                if (locals.resizeCheckTimer != null) {
                    clearInterval(locals.resizeCheckTimer);
                    locals.resizeCheckTimer = null;
                }
                if (locals.isReadyTimer != null) {
                    clearInterval(locals.isReadyTimer);
                    locals.isReadyTimer = null;
                }

                if (locals.imgInfo != null)
                    locals.imgInfo.remove();

                // only kill events for our id
                $(window).unbind('.' + locals.meId);
                locals.me.unbind('.' + locals.meId);
                $('.pv-containerp:first', locals.me).unbind('.' + locals.meId);
                $('.pv-full_img img', locals.me).unbind('.' + locals.meId);
                $('.pv-full_img_frame', locals.me).unbind('.' + locals.meId).die("contextmenu." + locals.meId);
                $('.pv-menu-page').die('click.' + locals.meId);

                locals.me.stop(true, false); // stop any pending animations

                //reload(); // should not be needed -- empty should stop further loads

                locals.me.removeClass('pviewer').empty().hide(); // clean up, and hide
            }

            locals.smartLoaderTimer = null;
            locals.smartLoaderTime = new Date().getTime();
            function smartLoader(fast) {
                if (locals.isReady == false || locals.isLoaded == false || locals.pics.length == 0 || locals.smartLoaderTimer != null)
                    return; // in progress

                var delay = 500; // slow
                var now = new Date().getTime();

                if (fast == true || ((now - locals.smartLoaderTime) > 5000)) {
                    delay = 30; // fast
                    locals.smartLoaderTime = now;
                }

                locals.smartLoaderTimer = window.setTimeout(smartLoaderCallback, delay);
            }

            function smartLoaderCallback() {
                locals.smartLoaderTimer = null;

                if (locals.picsLoading >= locals.settings.resourceLoadCount) {
                    return; // nothing more we can do for now
                }

                var pageTop = 0;
                if (typeof (window.pageYOffset) == 'number') {
                    pageTop = window.pageYOffset;
                } else if (document.body && (document.body.scrollTop)) {
                    pageTop = document.body.scrollTop;
                } else if (document.documentElement && (document.documentElement.scrollTop)) {
                    pageTop = document.documentElement.scrollTop;
                }

                var pageBottom = pageTop + locals.pageHeight;

                var meOffset = locals.me.offset();
                var meHeight = locals.me.height();
                var meBottom = meOffset.top + meHeight;

                if (pageBottom < meOffset.top || pageTop > meBottom) {
                    return; // optimization: not visible, nothing to load
                }

                var containerPos;
                try {
                    containerPos = locals.container.position();
                } catch (e) {
                    return;
                }

                // determine visible Y spectrum
                var visibleTop = Math.abs(containerPos.top);
                var visibleBottom = visibleTop + meHeight;
                if (pageTop > meOffset.top)
                    visibleTop += (pageTop - meOffset.top);
                if (locals.pageHeight < meHeight)
                    visibleBottom = visibleTop + locals.pageHeight;

                // prefetch support
                var prefetchSize = ((locals.imageSize.height + locals.imagePadding) * locals.settings.prefetchRows);
                visibleTop -= prefetchSize;
                visibleBottom += prefetchSize;

                //console.log('smartLoaderCallback page: ' + pageTop + '-' + pageBottom + ' containerPos: ' + containerPos.top + ' me: ' + meOffset.top + '-' + meBottom + ' visible: ' + visibleTop + '-' + visibleBottom);

                for (var i = 0; i < locals.pics.length; i++) {
                    var pic = locals.pics[i];
                    if (pic == null || pic.loading == true)
                        continue; // ignore
                    if (pic.position == null)
                        pic.position = pic.dom.position();
                    var top = pic.position.top;
                    var bottom = top + locals.imageSize.height;
                    if (bottom >= visibleTop && top <= visibleBottom) {
                        pic.loading = true;
                        loadPrimaryImage(pic);
                        smartLoader(true);
                        return;
                    }
                }
            }

            attachResize();

            // 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 = $.fn.PhotoViewer.instances[meId] = { me_this: this, fn: function(locals, uri, settings) {

        return locals.fn(locals, uri, settings);
    };

    // GLOBALS
    $.fn.PhotoViewer.instances = {};

})(jQuery);

