/**
 CHANGELOG:
 2007/12/03 - Upgraded to v1.2 syntax
 2008/02/07 - Added specific functionality for todaynetwork gallery
 - Popup for gallery speed
 - Toggle Rotate changes
 2008/02/22 - Ad refreshes only once for rotate
 - Ad refreshes every image change
 - Image alt changes per image change
 - Image anchor title changes per image change
 2008/06/02 - Changed the nielsen reporting function call to a gallery specific one. (currently austereo specific)
 2008/06/17 - Updated with endOfShow screen
 2008/06/18 - Added item poll functionality
 2008/06/23 - Added timestamp to swap poll request URL to stop IE caching the response.
 2008/07/09 - Changed filename (and location) to allow use across all Austereo sites.
 2008/08/01 - Roll back of nielsen function call. Added (22/08/2008).
 2008/10/14 - Design version and sectionSubDir of the poll is now driven from the template.
 2009/05/04 - Added title to img tag to display correctly in firefox (Austereo TripleM issue 1276).
 2009/09/02 - Changed moveNavToCurrentImage logic
 2010/03/12 - Updated image poll form/results to be loaded on page load to work with front side caching
 **/

if(window['FD']) {
    /* Now Playing Media Player
     ------------------------------------------------------------------------------------------- */
    FD.SuperGallery = function(fdOptions) {

        var defaultOptions = {
            idScroll: "FDGThumbs",
            idMainImg: "mImg",
            idImgDesc: "mImgDesc",
            idSwitch: "FDGSwitch",
            idRotate: "rotate",
            idGallery: "gallery",
            idNav: "nav",
            classSelected: "selected",
            classPrev: "prev",
            classNext: "next",
            classPageNo: "page",
            classHidden: "hidden",
            classReset: "reset",
            rotateDur: 1500,
            preload: true,
            galW: 800,
            galH: 600,
            dur: 200,
            hotZone: 50,
            hotZoneDelay: 2000,
            coldZone: 125,
            openPos: 0,
            imgMThreshold: 50,
            itemsAtOnce: 6,
            adSwapCount: 3,
            pageOf: "of",
            navElementType: "a",
            rotateSpeeds: [0, 5000, 3500, 1500],
            rotateClasses: ["stop", "slow", "med", "fast"],
            adSwapCount: 1
        };

        /**
         * The final, merged version of the toggle text definition.
         * <p/>
         * This toggle text definition is the result of extending the <code>defaultOptions</code> object with our custom
         * parameters passed in via <code>fdOptions</code>.
         *
         * @private
         */
        var options = $.extend(true, defaultOptions, fdOptions);

        //NOTE i can't find any emailAFriend HTML, so this emailAfriend validation etc may not work...
        var toggles = ['about', 'moreGalleries', 'emailAFriend', 'endOfShow', 'emailFailure'];

        var errors = {
            name: "Please enter your friend's name",
            email: "Please enter your friend's email address",
            yourName: "Please enter your name",
            yourEmail: "Please enter your email address"
        };

        var sentRotateReq = false;
        var thumbsVisible = true;
        var navW = 100;
        var navH= 115;
        var imgC= 0;
        var imgPos= 0;
        var imgLoaded= [];
        var navPos= 0;
        var navOn= true;
        var navTrans= false;
        var clickNo= 0;
        var rotating= false;
        var rotateID = 0;
        var disabled= false;
        var mainMargins= [];
        var transBuffer = "";
        var galLeft = 0;
        var galTop = 0;
        var imgArr = [];
        var closeDelay = 0;
        var setMImgTitle = false;
        var navOver = false;

        /**
         *
         * @constructor
         * @private
         */
        (function() {
            baseInitialize();
            initialize();
        })();

        function baseInitialize() {
            var gal = getGal();
            var nav = getNav();
            if(gal.length && nav.length && window['FDGalleryImages']) {
                // Get the horizontal nav left offset
                galLeft = gal.offset().left;
                galTop = gal.offset().top;
                imgArr = FDGalleryImages;
                // Get the image gallery image array
                constructNav();
                autoAdjustMargin($("#"+options.idMainImg), 0);
                if(options.hotZone > 0) {
                    nav.bind("mouseover", setNavOver);
                    setTimeout(function(){appendMouseE(gal);},options.hotZoneDelay);
                    closeDelay = setTimeout(function(){closeNav();},options.hotZoneDelay);
                } else {
                    nav.bind("click", toggleNav);
                }
                gal.bind("click", {i: 1}, moveBy);
                $('body').bind("keydown", doKeyPress);

                if(options.preload) {
                    // Load the images.
                    for (var i = 0; i < FDGalleryImages.length; i++) {
                        FD.element('img', {
                            src: FDGalleryImages[i]
                        });
                        setImgLoaded(i);
                    }

                    nav.bind("click", catchClick);
                }
                var stupidreset = $("."+options.classReset);
                stupidreset.each(function(idx, tres) {
                    var res = $(tres);
                    res.bind("click", reset);
                });

            }
        }

        function initialize() {
            for(var i = 0; i < toggles.length; i++) {
                var t = toggles[i];
                if(t) {
                    parseInnerButtons(t);
                    var button = $("#"+t);
                    if(button.length) {
                        button.bind("click", {toggleName: t}, toggle);
                    }
                }
            }


            // Get the description height
            var desc = $("#"+options.idImgDesc);
            //if(desc.length) {
            //  defaultDescHeight = desc.css("height").toInt();
            // defaultOpenPos = this.options.openPos;
            //  var nav = this.getNav();
            //}

            checkDesc();

            // Add Events to form, etc.
            setupEmailForm();

            // Sharing
            _initShowHide("share");
            _initShowHide("autoplay");
            _initItemPollForm();
            $('body').bind("swap", checkDesc);
            $('body').bind("swap", doDynB);
            $('body').bind("swap", swapItemPoll);
            $('body').bind("navOpen", {title: "Hide Thumbs"}, setThumbsTitle);
            $('body').bind("navClosed", {title: "Show Thumbs"}, setThumbsTitle);
            var thumbnails = $('#thumbnails');
            if(thumbnails.length) {
                thumbnails.bind("click", closeNav);
            }
            swapItemPoll();
        }

        /*
         Function: doKeyPress

         This processes key events.
         The gallery focus previous or next on left / right.
         */
        function doKeyPress(event) {
            if(!disabled) {
                var move = 0;
                var code = (event.keyCode ? event.keyCode : event.which);
                if(code != 17 && code != 16 && code != 18) {
                    if(code == 37 || code == 32 || code == 39) {
                        if(code == 37) {
                            move = -1;
                        } else if(code == 39 || code == 32) {
                            move = 1;
                        }
                        event.data.i = move;
                        moveBy(event);
                    } else if(code == 27) {
                        closeNav();
                    }
                }
            }
        }

        /*
         Function: setNavOver

         This function is called when the mouse hovers over the nav.
         It clears the close delay if it exists and sets this.navOver to be true
         */
        function setNavOver() {
            if(closeDelay && closeDelay != 0) {
                clearInterval(closeDelay);
            }

            if(!navOver) {
                navOver = true;
            }
        }

        /*
         Function: autoAdjustMargin

         This function adjusts the margin of the main image to align it in the
         center and middle if it's height is less than that of the main gallery
         image holder div.
         */
        function autoAdjustMargin(el, a) {
            if(el.length) {
                if(!a) {
                    var a = 0;
                }
                if(!mainMargins[a]) {
                    var mImgH = el.height();
                    if(mImgH > 100 && mImgH < options.galH) {
                        var mImgM = Math.round((options.galH - mImgH) / 2);
                        mainMargins[a] = mImgM;
                    }
                }
                if(mainMargins[a]) {
                    FD.log("Adusting margin for image "+el.attr("src"));
                    el.css("margin-top", mainMargins[a]+"px");
                }
            }
        }

        /*
         Function: catchClick

         This function catches clicks at a lowest level of the nav to
         prevent the anchors around the images firing and directing
         the browser to a new URL.
         */
        function catchClick(e) {
            if (e) {
                FD.stopEvent(e);
            }
        }

        /*
         Function: setImgLoaded

         This function sets an image in the image Assets array to be
         loaded.
         When this occurs the class loading is removed from the image
         and its opacity is set to 1.
         */
        function setImgLoaded(x) {
            var img = $("#FDGalThumb_"+x);
            if(img.length) {
                imgLoaded[x] = true;
                img.css("opacity", 1);
                img.removeClass("loading");
            }
        }

        /*
         Function: openNav

         This function opens the nav to display the thumbnails.
         */
        function openNav() {
            if(!navOn) {
                if(!navTrans) {
                    var nav = getNav();
                    navTrans = true;
                    nav.animate({
                        top: options.openPos
                    },options.dur, navComplete);
                    transBuffer = "";
                } else {
                    transBuffer = "open";
                }
            }
        }

        /*
         Function: closeNav

         This function closes the nav hiding the thumbnails.
         */
        function closeNav() {
            if(navOn) {
                if(!navTrans) {
                    var nav = getNav();
                    navTrans = true;
                    var to = navH * -1;
                    if(options.openPos > 0) {
                        to = navH + options.openPos;
                    }
                    FD.log("Closing nav");
                    nav.animate({
                        top: to
                    },options.dur, navComplete);
                    transBuffer = "";
                } else {
                    transBuffer = "close";
                }
            }
        }

        /*
         Function: navComplete

         This function fires on the onComplete event when the nav is
         opened or closed.
         */
        function navComplete() {
            navTrans = false;
            var t = transBuffer;
            FD.log("Nav trans finished");
            if(t == "close") {
                closeNav();
            } else if(t == "open") {
                openNav();
            } else {
                var nav = getNav();
                var top = nav.position().top;
                if(top == options.openPos) {
                    navOn = true;
                    $.event.trigger('navOpen');
                } else {
                    navOn = false;
                    $.event.trigger('navClosed');
                }
            }
        }

        /*
         Function: constructNav

         This function constructs the nav, setting click events to swap
         the main image to that which is clicked.
         */
        function constructNav() {
            var scroller = getScroller();
            if(scroller.length) {
                navH = scroller.height();
                var thumbs = scroller.find(options.navElementType);
                imgC = thumbs.length;
                thumbs.each(function(idx, tthumb) {
                    var thumb = $(tthumb);
                    if(idx == 0) {
                        navW = tthumb.offsetWidth;
                        if(options.startImg) {
                            if(thumbs[options.startImg]) {
                                thumbs[options.startImg].addClass(options.classSelected);
                            }
                        } else {
                            thumb.addClass(options.classSelected);
                        }
                    }
                    thumb.bind("click", {i: idx}, swap);
                    var img = thumb.find("img")[0];
                    img.id = "FDGalThumb_"+idx;
                    if(img.offsetHeight < navH) {
                        var diff = Math.floor((navH - img.offsetHeight) / 2);
                        if(diff > 1) {
                            img.style.marginTop = diff+"px";
                        }
                    }
                });

                var nav = getNav();
                var nW = nav.width();
                thumbsVisible = nW / navW;
                parseButtons();
                // Initial Image setting
                if(options.startImg) {
                    var sImg = options.startImg;
                    if(sImg <= imgC) {
                        imgPos = options.startImg;
                        moveNavToCurrentImage();
                    }
                }
                // Bind the on/off button if it exists
                var galSwitch = $("#"+options.idSwitch);
                if(galSwitch.length) {
                    scroller.bind("click", toggleNav);
                    galSwitch.bind("click", toggleNav);
                }
            }
        }

        /*
         Function: toggleNav

         Opens or closes the nav depending on its current state.
         This function is used when the switch option is engaged.
         */
        function toggleNav(event) {
            if (event) {
                FD.stopEvent(event);
            }

            var text = "Show Thumbnails";
            if(!navOn) {
                text = "Hide Thumbnails";
                navOn = true;
                openNav();
            } else {
                navOn = false;
                closeNav();
            }
            var galSwitch = $("#"+options.idSwitch);
            if(galSwitch.length) {
                galSwitch.html(text);
            }
        }

        /*
         Function: parseButtons

         This function processes the next and previous image buttons,
         the scroll next and previous nav buttons and the auto rotate
         button.
         */
        function parseButtons() {
            var scrollPrev = $("#scrollPrev");
            var scrollNext = $("#scrollNext");
            if(scrollPrev.length) {
                scrollPrev.bind("click", {i: (-1 * options.itemsAtOnce)}, doMoveNavClick);
                scrollPrev.addClass(options.classHidden);
            }
            if(scrollNext.length) {
                if(imgC <= options.itemsAtOnce) {
                    scrollNext.addClass(options.classHidden);
                }
                scrollNext.bind("click", {i: options.itemsAtOnce}, doMoveNavClick);
            }

            var moveLinks = $(".move");
            moveLinks.each(function(idx, links){
                var l = $(links);
                var dir = 1;
                if(l.hasClass(options.classPrev)) {
                    dir = -1;
                }
                l.bind("click", {i: dir}, moveBy);
            });

            initRotate();
        }

        /**function initRotate() {
            var rot = $("#"+options.idRotate);
            if(rot.length) {
                rot.bind("click", rotate);
            }
        }**/

        /*
         Function: moveBy

         This function is used to swap the main forward or backwards
         depending on the value of i.
         i is not the index of the image, but the increment or decrement
         to the selected image index.

        function moveBy(event) {
            var i = event.data.i

            FD.stopEvent(event);

            // TODO Do we really need this
            // this.swap(e, pos);
            // this.moveNavToCurrentImage();
            if(options.hotZone > 0) {
                closeNav();
            } else if(navOn) {
                toggleNav();
            }
            var pos = imgPos + i;
            if(pos == imgC) {
                pos = 0;
            } else if (pos < 0) {
                pos = imgC - 1;
            }
            event.data.i = pos;
            swap(event);
            moveNavToCurrentImage();
        }*/

        /*
         Function: reset

         This function resets the gallery to the first image.
         */
        function reset(event) {
            if(event) {
                FD.stopEvent(event);
            }
            var move = -1 * imgPos;
            moveBy(move);
        }

        /*
         Function: rotate

         This function toggles the gallery automatic image auto play rotation.
         */
        function rotate(event) {
            if (event) {
                FD.stopEvent(event);
            }
            var rotateSwitch = $("#"+options.idRotate+"Switch");
            if(rotateSwitch.length) {
                if(!rotating) {
                    rotating = true;
                    rotateID = setInterval(function() { moveBy(1); }, options.rotateDur);
                    rotateSwitch.addClass(options.classSelected);
                } else {
                    clearInterval(rotateID);
                    rotateID = false;
                    rotating = false;
                    rotateSwitch.removeClass(options.classSelected);
                }
            }
        }

        /*
         Function: moveNavToCurrentImage

         This function moves the nav so that the currently image's thumbnail
         is as close to the center of the nav as possible.
         */
        function moveNavToCurrentImage() {
            var move = 0;
            // If the image is outside the nav
            if((imgPos + 1) > (thumbsVisible + navPos) || imgPos < navPos) {
                // The image is outside - Move the nav to be spaced evenly around the selected image if possible
                if(imgPos + 1 > 0) {
                    move = imgPos + 1 - navPos - Math.floor(thumbsVisible / 2);
                    moveNav(move);
                }
            }
        }

        /*
         Function: checkNav

         This function is called onMouseMove to ensure that the mouse's
         vertical position is still witin the hotzone (if there is one).
         */
        function checkNav(event) {
            if(!event) {
                closeNav();
                return;
            }
            var scroll = $(window).scrollTop();
            var pos = (event.clientY + scroll - galTop);
            if((!navTrans) && (!disabled)) {
                if(options.openPos == 0) {
                    // Top
                    if(!navOn && pos < options.hotZone) {
                        openNav();
                    } else if(navOn && navOver && pos > options.coldZone) {
                        closeNav();
                    }
                } else {
                    // Bottom
                    if((!navOn) && pos > options.openPos) {
                        openNav();
                    } else if(navOn && pos < options.openPos) {
                        closeNav();
                    }
                }
            }
        }

        /*
         Function: doMoveNavClick

         This function catches the click of scrolling the nav.
         */
        function doMoveNavClick(event) {
            var i = event.data.i
            if(i) {
                if (event) {
                    FD.stopEvent(event);
                }
                moveNav(i);
            }
        }

        /*
         Function: moveNav

         This function moves the nav.
         i is not the index of the image, but the increment or decrement
         to the selected image index.
         */
        function moveNav(i) {
            var pos = navPos + i;
            if(i > 0) {
                if((pos + thumbsVisible) >= imgC) {
                    pos = imgC - thumbsVisible;
                }
            } else {
                if(pos < 0) {
                    pos = 0;
                }
            }
            if(pos == (imgC - thumbsVisible)) {
                $("#scrollNext").addClass(options.classHidden);
            } else {
                $("#scrollNext").removeClass(options.classHidden);
            }
            if(pos == 0) {
                $("#scrollPrev").addClass(options.classHidden);
            } else {
                $("#scrollPrev").removeClass(options.classHidden);
            }
            navPos = pos;
            var to = (pos * navW) * -1;
            var nav = getScroller();
            var from = nav.position().left;
            if(from != to && to < options.galW) {
                nav.animate({
                    left: to
                },options.dur);

            }
        }

        /*
         Function: swap

         This function swaps the main image to that of the index passed in.
         This function also swaps the advertisement and registers a page impression.
         */
        function swap(ev) {
            var a = ev;
            if (ev.data && ev.data.i) {
                a = ev.data.i;
                FD.stopEvent(ev);
                // This is a click. If rotating stop the rotation.
                if(rotateID) {
                    rotate();
                }
            }

            if(!isNaN(a) && imgArr[a]) {
                clickNo++;
                var gal = getGal();
                if(options.preload) {
                    if(imgLoaded[a]) {
                        gal.removeClass("loading");
                    } else {
                        gal.addClass("loading");
                    }
                }
                setSelected(a);
                // Set the description.
                var desc = getImgDesc();
                if(desc.length) {
                    desc.html(FDGalleryDesc[a]);
                }
                var mImg = $('#mImg');
                var nImg = FD.element('img', {
                    src: imgArr[a]
                });

                // Get the adjusted margin
                mImg.parent().prepend(nImg);
                autoAdjustMargin(nImg, a);
                mImg.remove();
                nImg.attr("id", "mImg");

                setImageNumber(a);
                $.event.trigger('swap');
            }
        }

        /*
         Function: setPageNumber

         This function sets the current page number on all page number identifiers.
         */
        function setImageNumber(pageNo) {
            var pages = $('.'+options.classPageNo);
            var page = (pageNo + 1)+" "+options.pageOf+" "+imgC;
            pages.each(function(idx, tp) {
                var p = $(tp);
                p.html(page);
            });
        }

        /*
         Function: setSelected

         This function sets the image indicated by i to be selected.
         */
        function setSelected(i) {
            if(!isNaN(i)) {
                imgPos = i;
                var thumbs = $("#"+options.idScroll).find("a");
                thumbs.each(function(idx, tthumb) {
                    var thumb = $(tthumb);
                    if(idx == i) {
                        thumb.addClass(options.classSelected);
                    } else {
                        thumb.removeClass(options.classSelected);
                    }
                });
            }
        }

        /*
         Function: getGal

         This function returns the gallery div
         */
        function getGal() {
            return $("#"+options.idGallery);
        }

        /*
         Function: getNav

         This function returns the gallery navigation div
         */
        function getNav() {
            return $("#"+options.idNav);
        }

        /*
         Function: getScroller

         This function returns the gallery navigation scroller div
         */
        function getScroller() {
            return $("#"+options.idScroll);
        }

        /*
         Function: getImgDesc

         This function returns the image description div
         */
        function getImgDesc() {
            if(window['FDGalleryDesc']) {
                return $("#"+options.idImgDesc);
            }
        }

        function _initShowHide(id) {
            var ele = $("#"+id);
            if(ele.length) {
                var eleD = ele.find("ul").first();
                if(eleD.length) {
                    ele.bind("mouseenter", {el: eleD}, show);
                    ele.bind("mouseleave", {el: eleD}, hide);
                }
            }
        }

        /**
         * binds a submit handler to the item poll form if it exists.
         */
        function _initItemPollForm() {
            var ele = $("#galleryItemPollForm");
            if(ele.length) {
                ele.bind("submit", itemPollVote);
            }
        }

        /*
         Function: setThumbsTitle

         Sets the title of the navigation label
         */
        function setThumbsTitle(event) {
            var t = event.data.title
            if(t) {
                var title = $('#thumbnails');
                if(title.length) {
                    title.html(t);
                }
            }
        }

        /*
         Function: appendMouseE

         Appends the mousemove event to the gallery.
         This function is trigered after the period denoted in this.options.hotZoneDelay

         Called by FD.Gallery, overwritten here.
         */
        function appendMouseE(gal) {
            var thumbnails = $('#thumbnails');
            if(thumbnails.length) {
                thumbnails.bind("click", checkNav);
            }
        }

        function setupEmailForm() {
            // Email a friend validation
            var emailD = $('#emailAFriendScreen');
            if(emailD.length) {
                var f = emailD.find("form").first();
                if(f.length) {
                    f.bind("submit", {f : f}, validateEmailForm);
                }
            }
        }

        function validateEmailForm(event) {
            if (event) {
                FD.stopEvent(event);
            }
            var f = event.data.f;

            var inps = f.find("input");
            var error = $('#validationError');
            if(error.length) {
                inps.each(function(idx, tinput) {
                    var inp = $(tinput);
                    error.empty();
                    if(tinput.type != "submit") {
                        var p = inp.parent();
                        if(p.length && ((tinput.name.toLowerCase().indexOf("email") > -1 && (!validateEmail(tinput.value))) || tinput.value.trim() == "")) {
                            p.addClass("error");
                            error.html(errors[tinput.name]);
                            inp.focus();
                            tinput.select(); //Dom method to select content of text field.
                            return false;
                        } else {
                            p.removeClass("error");
                        }
                    }
                });

            }

            //Note this wasn't turned on for any sites so didn't bother testing.
            var url = f.attr('action')
            var params = f.serialize();

            $.ajax({
                type: "GET",
                data: params,
                dataType: "html",
                statusCode: {200:updateForm },
                //success: updateForm,
                timeout: 1500,
                url: url
            });

        }

        function updateForm(ret) {
            if(ret) {
                var form = $('#emailFailureScreen');
                form.html(ret);
                toggleWorker('emailFailure');
                parseInnerButtons('emailFailure');
            }
        }

        function validateEmail(email) {
            if(email.length > 0) {
                // Check for '@'
                var firstAt = email.indexOf("@");
                if(firstAt > 0) {
                    var lastAt = email.lastIndexOf("@");
                    // Ensure there is only one "@"
                    if(firstAt == lastAt) {
                        // There is a valid @ - Check for invalid characters.
                        var namePortion = email.substr(0, lastAt + 1);
                        var filter = /^([a-zA-Z0-9_\.\-\+])+\@/;
                        if(!filter.test(namePortion)) {
                            return false;
                        }
                    } else {
                        // There is a second @!
                        return false;
                    }
                } else {
                    // There is no @
                    return false;
                }

                // Check for Domain
                var domainName = email.substr(email.indexOf("@") + 1, email.length);
                var domainFilter = /^(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})$/;
                if(!domainFilter.test(domainName)) {
                    // Invalid Domain name.
                    return false;
                }

                // Valid Email address
                return true;
            }
        }

        /*
         Function: moveBy

         This function is used to swap the main forward or backwards
         depending on the value of i.
         i is not the index of the image, but the increment or decrement
         to the selected image index.
         */
        function moveBy(event) {
            var i = event;
            if (event.data && event.data.i) {
                i = event.data.i
            }

            if (event.data) {
                FD.stopEvent(event);
            }

            if(disabled) {
                if(imgPos != (imgC - 1)) {
                    closeAllToggles();
                }
            }
            if(options.hotZone > 0) {
                if(event.data) {
                    closeNav();
                }
            } else if(navOn) {
                toggleNav();
            }
            var pos = imgPos + i;
            if((pos == imgC && !disabled) || // Last image - Enable
                    (i < 0 && disabled)) {             // Pressing previous button - Disable
                toggleWorker("endOfShow");
            }
            swap(pos);
            moveNavToCurrentImage();
        }

        function toggleWorker(toggleName) {
            var disable = false;

            if(toggleName) {
                checkNav();
                for(var i = 0; i < toggles.length; i++) {
                    var t = toggles[i];
                    var elName = "#"+t+"Screen";
                    var tD = $(elName);
                    if(tD.length) {
                        var mode = "hidden";
                        var disp = tD.css("visibility");
                        if(disp == "hidden" && toggleName == t) {
                            mode = "visible";
                            disable = true;
                            if(rotating) {
                                rotate();
                            }
                        }
                        tD.css("visibility", mode);
                    }
                }
                disabled = disable;
            }
        }

        function toggle(event) {
            var el = event.data.toggleName;
            FD.stopEvent(event);
            toggleWorker(el);
        }

        function show(event) {
            var el = event.data.el;
            if(el.length) {
                el.css("visibility", "visible");
            }
        }

        function hide(event) {
            var el = event.data.el;
            if(el.length) {
                el.css("visibility", "hidden");
            }
        }

        function parseInnerButtons(el) {
            var elName = "#"+el+"Screen";
            var tD = $(elName);
            if(tD.length) {

                var cbs = tD.find("a.close");
                cbs.each(function(idx, tcb) {
                    var cb = $(tcb);
                    cb.bind("click", {toggleName: el}, toggle);
                });

                var cls = tD.find(".email");
                cls.each(function(idx, tcl) {
                    var cl = $(tcl);
                    cl.bind("click", {toggleName: "emailAFriend"}, toggle);
                });
            }
        }

        function toggleRotate() {
            if(disabled) {
                if((imgC - 1) == imgPos) {
                    reset();
                } else {
                    closeAllToggles();
                    disabled = false;
                }
            }
            sentRotateReq = false;
            var rotateStop = $('#rotateStop');
            if(rotateStop.length) {
                rotateStop.css("display", (rotating ? "none" : "block"));
            }
            rotate();
        }

        function doDynB() {
            // Swap ad
            if(clickNo > 0 && clickNo % options.adSwapCount == 0) {

                if (document.dcdAdsR) {
                    document.refreshAds("adspot-300x250-pos-1");
                    document.refreshAds("adspot-300x250-pos-2");
                }
            }

            if((!rotating) || (rotating && (!sentRotateReq))) {
                FD.doNielsenSlideShowImpression();
                setRotateReq = true;
            }

        }

        /**
         * Makes an ajax request for the corresponding poll.
         */
        function swapItemPoll() {
            var params = 'galleryPollAssetId=' + FDGalleryImageAssetIds[imgPos] + '&designVersionName=' + options.currentDesignVersion + '&sectionSubDir=' + options.pollComponentSectionSubDir + '&reqTime=' + new Date().getTime();

            $.ajax({
                type: "GET",
                data: params,
                dataType: "html",
 //               success: handleSwapItemPollResponse,
                statusCode: {200:handleSwapItemPollResponse },
                timeout: 1500,
                url: options.galleryItemPollPath
            });
        }

        /**
         * Inserts the response poll html and binds to the new poll form.
         */
        function handleSwapItemPollResponse(response, textStatus) {
            var galleryWrapper = $('#galleryWrapper');
            var pollWrapper = $('#galleryItemPollWrapper');

            if(response.trim() == "") {
                if (pollWrapper.length) {
                    pollWrapper.empty();
                }
                if (galleryWrapper.length) {
                    galleryWrapper.removeClass('galleryWithPoll');
                    galleryWrapper.addClass('galleryWithoutPoll');
                }
            } else {
                if (galleryWrapper.length) {
                    galleryWrapper.removeClass('galleryWithoutPoll');
                    galleryWrapper.addClass('galleryWithPoll');
                }
                if (pollWrapper.length) {
                    pollWrapper.html(response);
                }
            }



            _initItemPollForm();
        }

        /**
         * Stops the item poll form from submitting and submit via ajax.
         */
        function itemPollVote(event) {
            if (event) {
                FD.stopEvent(event);
            }
            var form = $(this);
            var url = form.attr('action')
            var params = form.serialize();

            $.ajax({
                type: "GET",
                data: params,
                dataType: "html",
                statusCode: {200:handleItemPollVoteResponse },
                //success: handleItemPollVoteResponse,
                timeout: 1500,
                url: url
            });
        }

        /**
         * Inserts the response poll html.
         */
        function handleItemPollVoteResponse(response) {
            var pollWrapper = $('#galleryItemPollWrapper');
            pollWrapper.html(response);
            _initItemPollForm();
        }

        function closeAllToggles() {
            disabled = false;
            var t = toggles;
            for(var a = 0; a < t.length; a++) {
                var elName = "#"+t[a]+"Screen";
                var d = $(elName);
                if(d.length) {
                    d.css("visibility", "hidden");
                }
            }
        }

        function initRotate() {
            // Init the rotate button
            var rotateContainer = $("#"+options.idRotate);
            if(rotateContainer.length) {
                var rotateSwitch = $("#"+options.idRotate+"Switch");
                if(rotateSwitch.length) {
                    rotateSwitch.bind("click", toggleRotate);
                    var rotateButtons = rotateContainer.find("."+options.idRotate);
                    // Get the rotate buttons
                    var rotateClasses = options.rotateClasses;
                    var rotateSpeeds = options.rotateSpeeds;
                    if($.isArray(rotateClasses)) {
                        rotateButtons.each(function(idx, tbutton) {
                            var button = $(tbutton);
                            for(var a = 0; a < rotateClasses.length; a++) {
                                if(button.hasClass(rotateClasses[a])) {
                                    button.bind("click", {dur:rotateSpeeds[a],eles:rotateButtons}, setRotateSpeed);
                                }
                            }
                        });
                    }
                }
            }
        }

        /*
         Function: setRotateSpeed

         This function sets the duration of the rotation and
         restarts it.
         */
        function setRotateSpeed(event) {
            var dur = event.data.dur;
            var eles = event.data.eles;
            FD.stopEvent(event);
            var numberRegex = /^[+-]?\d+(\.\d+)?([eE][+-]?\d+)?$/;
            if(numberRegex.test(dur)) {
                if(dur == 0) {
                    if(rotating) {
                        toggleRotate();
                    }
                    return;
                }
                options.rotateDur = dur;
                if(rotating) {
                    clearInterval(rotateID);

                    rotateID = false;
                    rotating = false;
                }
                // Restart the rotation process
                rotate();
                var rotateStop = $('#rotateStop');
                if(rotateStop.length) {
                    rotateStop.css("display", (!rotating ? "none" : "block"));
                }
                //why does it do this... random
                eles.removeClass(options.classSelected);
                $(this).addClass(options.classSelected);

            }
        }

        function checkDesc() {
            var desc = $("#"+options.idImgDesc);
            var nav = getNav();
            if(desc.length) {
                var descH = desc.attr('offsetHeight');
                var t = options.galH - (descH + 10);
                options.openPos = options.galH - descH - (nav.attr('offsetHeight') - 15);
                if(navOn) {
                    t = options.openPos;
                }
                if(!navTrans) {
                    nav.css("top", t+"px");
                } else {
                    closeNav();
                }
            }
            // Update the alt tag of the main image and the title of the anchor surrounding it
            var mImg = $("#"+options.idMainImg);
            var a = mImg.parent();
            // Check this is not the initial load.
            if(setMImgTitle && mImg.length) {
                mImg.attr('alt', desc.html());
                mImg.attr('title', desc.html());
                // Get the next desc
                if(FDGalleryDesc) {
                    var nextDesc = FDGalleryDesc[imgPos + 1] || FDGalleryDesc[0];
                }
                a.attr('title', nextDesc);
            } else {
                setMImgTitle = true;
            }
        }
    }

    $(function() {
        if (window['FDGalleryOptions']) {
            var sg = new FD.SuperGallery(FDGalleryOptions);
            window['FDSuperGallery'] = sg;
        }
    });

}
