﻿var Scroller=new Class({Implements:[Events,Options],options:{area:20,velocity:1,onChange:function(x,y){this.element.scrollTo(x,y)},fps:50,scrollElement:null},initialize:function(element,options){this.setOptions(options);this.element=document.id(element);this.docBody=document.id(this.element.getDocument().body);this.listener=($type(this.element)!='element')?this.docBody:this.element;if(this.options.scrollElement){this.element=this.options.scrollElement}this.timer=null;this.bound={attach:this.attach.bind(this),detach:this.detach.bind(this),getCoords:this.getCoords.bind(this)}},start:function(){this.listener.addEvents({mouseenter:this.bound.attach,mouseleave:this.bound.detach})},stop:function(){this.listener.removeEvents({mouseenter:this.bound.attach,mouseleave:this.bound.detach});this.detach();this.timer=$clear(this.timer)},attach:function(){this.listener.addEvent('mousemove',this.bound.getCoords)},detach:function(){this.listener.removeEvent('mousemove',this.bound.getCoords);this.timer=$clear(this.timer)},getCoords:function(event){this.page=(this.listener.get('tag')=='body')?event.client:event.page;if(!this.timer)this.timer=this.scroll.periodical(Math.round(1000/this.options.fps),this)},scroll:function(){var size=this.element.getSize(),scroll=this.element.getScroll(),pos=this.element!=this.docBody?this.element.getOffsets():{x:0,y:0},scrollSize=this.element.getScrollSize(),change={x:0,y:0},top=this.options.area.top||this.options.area,bottom=this.options.area.bottom||this.options.area;for(var z in this.page){if(this.page[z]<(top+pos[z])&&scroll[z]!=0){change[z]=(this.page[z]-top-pos[z])*this.options.velocity}else if(this.page[z]+bottom>(size[z]+pos[z])&&scroll[z]+size[z]!=scrollSize[z]){change[z]=(this.page[z]-size[z]+bottom-pos[z])*this.options.velocity}change[z]=change[z].round()}if(change.y||change.x)this.fireEvent('change',[scroll.x+change.x,scroll.y+change.y])}});

function setupThumbArrows(scrollDiv, index) {
    var arrowContainerDiv = new Element("div", { "class": "thumbWrapper", styles: { "width": "100%" }});
    scrollDiv.getParents()[0].grab(arrowContainerDiv).setStyle("position", "relative");
    arrowContainerDiv.wraps(scrollDiv);
    var arrowHeight = scrollDiv.getChildren("div")[0].getSize().y
    var arrowDivLeft = new Element("div", { "class": "arrowLeft", styles: { "height": arrowHeight } });
    var arrowDivRight = new Element("div", { "class": "arrowRight", styles: { "height": arrowHeight } });
    arrowDivLeft.addEvent("mouseover", function(){
        scrollDiv.store("scrollDirection", "left");
    }).fade("hide");
    arrowDivRight.addEvent("mouseover", function(){
        scrollDiv.store("scrollDirection", "right");
    }).fade("hide");
    arrowContainerDiv.adopt(arrowDivLeft, arrowDivRight);
}

function getFullPercentage(scrollDiv) {
    return (scrollDiv.getScroll().x/(scrollDiv.getScrollSize().x - scrollDiv.getSize().x))
}
function getPercentageScrolled(scrollDiv) {
    return (scrollDiv.getScroll().x/(scrollDiv.getScrollSize().x - scrollDiv.getSize().x))
}

function thumbScroll (scrollDiv, totalScrollTime, autoScroll, elementsToScrollTo) {
    if (!forceStop) {
        var percentageScrolled = getPercentageScrolled(scrollDiv);
        var fullPercentage = getFullPercentage(scrollDiv);
        var currentScrollDirection = scrollDiv.retrieve("scrollDirection");
        if (fullPercentage == 0) {
            thumbScrollRight(scrollDiv, totalScrollTime, autoScroll, percentageScrolled, elementsToScrollTo);
        } else if (fullPercentage == 1) {
            thumbScrollLeft(scrollDiv, totalScrollTime, autoScroll, percentageScrolled, elementsToScrollTo);
        } else if (currentScrollDirection == "right") {
            thumbScrollRight(scrollDiv, totalScrollTime, autoScroll, percentageScrolled, elementsToScrollTo);
        } else if (currentScrollDirection == "left") {
            thumbScrollLeft(scrollDiv, totalScrollTime, autoScroll, percentageScrolled, elementsToScrollTo);
        }
    }
}

function thumbScrollRight(scrollDiv, totalScrollTime, autoScroll, percentageScrolled, elementsToScrollTo) {
    scrollDiv.store("scrollDirection", "right");
    autoScroll.options.duration = Math.round(totalScrollTime - (totalScrollTime*percentageScrolled));
    autoScroll.toElement(elementsToScrollTo.last);
}

function thumbScrollLeft(scrollDiv, totalScrollTime, autoScroll, percentageScrolled, elementsToScrollTo) {
    scrollDiv.store("scrollDirection", "left");
    autoScroll.options.duration = Math.round(totalScrollTime*percentageScrolled);
    autoScroll.toElement(elementsToScrollTo.first);
}

function setupThumbScroll(scrollDiv, thumbnailAnchors, index) {
    var totalScrollTime = globalStore["slideshow_" + index].totalScrollTime = ((thumbnailAnchors.length-4) * 4000);
    globalStore["slideshow_" + index].scrollDiv = scrollDiv;
    var elementsToScrollTo = {first: thumbnailAnchors[0], last: (thumbnailAnchors[thumbnailAnchors.length-4])};
    globalStore["slideshow_" + index].elementsToScrollTo = elementsToScrollTo;
    var autoScroll = globalStore["slideshow_" + index].autoScrollInstance = new Fx.Scroll(scrollDiv, {
        duration: totalScrollTime,
        transition: Fx.Transitions.linear,
        onComplete: function() {
            thumbScroll(scrollDiv, totalScrollTime, autoScroll, elementsToScrollTo);
        }
    });
    scrollDiv.getParents()[0].getParents()[0].addEvent("mouseenter", function() {
        autoScroll.cancel();
    }).addEvent("mouseleave", function() {
        thumbScroll(scrollDiv, totalScrollTime, autoScroll, elementsToScrollTo);
    });
    autoScroll.toElement(elementsToScrollTo.last)
    globalStore["slideshow_" + index].scroller = new Scroller(scrollDiv.getParents()[0], { area: 50, velocity: 0.8, scrollElement: scrollDiv });
}

var globalStore = new Hash();
var forceStop = false;

var pauseAllSlideshows = function() {
    forceStop = true;
    globalStore.each(function(item) {
        item.shouldPlay = item.slideshow.options.play;
        item.slideshow.options.play = false;
        item.slideshow.stopPlay();
        if (!item.noThumbScroll) {
            item.autoScrollInstance.cancel();
        }
    });
}
var pauseSpecificSlideshow = function(store) {
    forceStop = true;
    store.shouldPlay = store.slideshow.options.play;
    store.slideshow.options.play = false;
    store.slideshow.stopPlay();
    if (!store.noThumbScroll) {
        store.autoScrollInstance.cancel();
    }
}
var playAllSlideshows = function() {
    forceStop = false;
    globalStore.each(function(item) {
        item.slideshow.options.play = item.shouldPlay;
        item.slideshow.startPlay();
        if (!item.noThumbScroll) {
            thumbScroll(item.scrollDiv, item.totalScrollTime, item.autoScrollInstance, item.elementsToScrollTo);
        }
    });
}
var playSpecificSlideshow = function(store) {
    forceStop = false;
    store.slideshow.options.play = store.shouldPlay;
    store.slideshow.startPlay();
    if (!store.noThumbScroll) {
        thumbScroll(store.scrollDiv, store.totalScrollTime, store.autoScrollInstance, store.elementsToScrollTo);
    }
}



window.addEvent("domready", function() {
    Asset.images([
        "/images/loader.gif",
        "/images/play128.png",
        "/images/play48.png",
        "/images/arrowLeft.png",
        "/images/arrowLeftOver.png",
        "/images/arrowRight.png",
        "/images/arrowRightOver.png"
    ]);
    $$(".slideshow").each(function(element, index) {
        globalStore["slideshow_" + index] = {};
        
        //Get image data from hidden field
        var hiddenField = element.getElement("input[type=hidden]");
        //Decode image data into an array of objects
        var images = JSON.decode(hiddenField.get("value"));
        //Remove the hidden field from the DOM
        hiddenField.destroy();
        //Instantiate an array for image source strings
        var imagesToLoad = [];
        //Instantiate an array for thumbnail source strings
        var thmbnailsToLoad = [];
        //Instantiate an array for the large image anchor containers
        var anchors = [];
        //Create a thumbnail container and place it in the slideshow area
        var thumbsContainer = new Element("div", {
            "class": "thumbnailImages"
        }).inject(element);
        
        //Find and set the link type for this page (whether to open a shadowbox or send to a new page
        var linkType = (($$(".slideshow").filter(function(item) { return item.hasClass("shadowbox"); })).length > 0) ? "shadowbox" : "newPage" ;
        
        //Create the large image container and inject it into the slideshow area as the first child
        var largeImageContainer = new Element("div", { "class": "largeImages" }).inject(element, "top");
        
        //Loop through the image data
        images.each(function(item, index) {
            //Push the image source to the array
            imagesToLoad.push(item.src);
            
            //Create the thumb image for the coresponding large image (this one will be a placeholder)
            var thumb = new Element("img", { "alt": "  " });
            //Create anchor to wrap the thumb
            var thumbAnchor = new Element("a", {
                "href": item.file,
                "class": item.type
            });
            //Inject the anchor into the thumb container and the thumbnail into the anchor
            thumbsContainer.grab(thumbAnchor.grab(thumb));
            if (item.type == "video" || item.type == "youtube") {//If the thumbnail is for a video
                //Set the anchor to open the video
                thumbAnchor.addEvent("click", function(event) {
                    Shadowbox.open(this.retrieve("corespondingPanel"));
                });
            }
            //Mask the thumb
            thumbAnchor.set("mask", { destroyOnHide: true, inject: { where: "inside", target: thumbAnchor } }).mask();
            
            //Push the thumbnail source to the array
            thmbnailsToLoad.push(item.thumbSrc);
            
            //Create an anchor that the large image will be placed in when loaded.
            var imageAnchor = new Element("a", {
                "class": images[index].type,
                "href": images[index].file
            });
            //Set the build in tween object on the anchor to hide the mask when it completes it's fade
            imageAnchor.set("tween", {
                onComplete: function() {
                    this.unmask();
                }
            });
            //Mask the anchor
            imageAnchor.set("mask", { destroyOnHide: true, inject: { where: "inside", target: imageAnchor } }).mask();
            
            if (linkType == "shadowbox") {//If images should open in the shadowbox
                //Set the anchor's rel to shadowbox
                var rel = "shadowbox";
                //If the image is to a video, set the width and height
                if (imageAnchor.hasClass("video") || imageAnchor.hasClass("youtube")) { rel += ";height=348;width=617"; }
                imageAnchor.set("rel", rel);
            } else {//Otherwise
                //Set the anchor's link to the one specifyed
                imageAnchor.set("href", images[index].link);
            }
            
            //Place the anchor onto the page, then push it into the array for storage
            largeImageContainer.grab(imageAnchor);
            anchors.push(imageAnchor);
        });
        
        if (linkType == "shadowbox") {//If links should open the shadowbox
            //Initilize (or reinitilize) the Shadowbox class
            if (Shadowbox) {
                Shadowbox.clearCache();
                Shadowbox.setup("a[rel*=shadowbox]");
            } else {
                Shadowbox.init();
            }
        }
        
        //Get the anchors from the thumbnail area
        var thumbnailAnchors = thumbsContainer.getChildren("a");
        if (thumbnailAnchors.length > 1) {//If there is more than one thumbnail
            //Instantiate the slideshow class
            globalStore["slideshow_" + index].slideshow = new bsfs(element, {
                togglersAreaClass: ".thumbnailImages",
                panelsAreaClass: ".largeImages",
                switchDelaySeconds: 5,
                play: false,
                fxType: "fadeOut",
                disableHeight: true
            });
            //Add the slideshow events to the Shadowbox instance
            Shadowbox.applyOptions({
                onOpen: pauseAllSlideshows,
                onClose: playAllSlideshows
            });
            //Instantiate a number that will be the width of all the thumbnails.
            var allImagesWidth = 0;
            //Loop through the thumbnail anchors
            thumbnailAnchors.each(function(item) {
                //Add the thumbnail's width along with its margins to the all thumbnails width number
                allImagesWidth += item.getSize().x + item.getStyle("margin-left").toInt() + item.getStyle("margin-right").toInt();
            });
            //Set the thumbnail container to be the width of all the thumbnails combined.
            thumbsContainer.setStyle("width", allImagesWidth);
            if (thumbnailAnchors.length > 4) {//If there are more than four thumbnails
                //Create a div that will be used to scroll the thumbnails and wrap the thumbnail container in it.
                var scrollDiv = new Element("div", { styles: { "width": "100%", "overflow": "hidden", "position": "relative" } }).wraps(thumbsContainer);
                
                //Store the current scroll direction on the scroll div
                scrollDiv.store("scrollDirection", "right");
                //Setup the arrows for scrolling the thumb container
                setupThumbArrows(scrollDiv, index);
                //Setup the mouse scrolling on the scroll div
                setupThumbScroll(scrollDiv, thumbnailAnchors, index);
            } else {//Otherwise
                //Specify in the slideshow instance that the thumbs shouldn't scroll
                globalStore["slideshow_" + index].noThumbScroll = true;
            }
            //Store the slideshow instance on the current slideshow instance for easy retrival
            element.store("slideshowItems", globalStore["slideshow_" + index]);
        } else {//Otherwise
            //Hide the thumbnail container
            thumbsContainer.setStyle("display", "none");
            element.setStyle("height", 348);
        }
        
        //Instantiate the loader variables
        var loader, thumbLoader;
        
        //setup image load progress function
        var thumbProgress = function(counter, index) {
            //Get the loaded image
            var image = thumbLoader[index];
            //Get the coresponding anchor container
            var imageAnchor = thumbsContainer.getChildren("a")[index];
            //Swap the loaded image for the placeholder image
            image.replaces(imageAnchor.getFirst("img"));
            if (imageAnchor.hasClass("video") || imageAnchor.hasClass("youtube")) {//If the image is for a video
                //Inject a play button into the anchor
                imageAnchor.grab(new Element('img', { src: '/images/play48.png', 'class': 'play' }));
            }
            //Unmask the anchor
            imageAnchor.get("mask").element.fade("out");
        }
        
        //setup image load progress function
        var progress = function(counter, index) {
            //Get the loaded image
            var image = loader[index];
            //Set the images alt text
            image.set("alt", images[index].alt);
            //Get the coresponding anchor container
            var imageAnchor = anchors[index];
            //Inject the image into it's container
            imageAnchor.grab(image);
            if (imageAnchor.hasClass("video") || imageAnchor.hasClass("youtube")) {//If the image is for a video
                //Inject a play button into the anchor
                imageAnchor.grab(new Element('img', { src: '/images/play128.png', 'class': 'play' }));
            }
            //Unmask the anchor
            imageAnchor.get("mask").element.fade("out");
        }
        
        //setup all images loaded function
        var allLoaded = function() {
            globalStore["slideshow_" + index].shouldPlay = true;
            if (thumbnailAnchors.length > 1) {
                playSpecificSlideshow(globalStore["slideshow_" + index]);
            }
            if (thumbnailAnchors.length > 4) {
                element.getElements(".arrowLeft, .arrowRight").fade("in");
                globalStore["slideshow_" + index].scroller.start();
            }
        }
        
        //Instantiate the thumb loader
        thumbLoader = new Asset.images(thmbnailsToLoad, {
            onProgress: thumbProgress
        });
        
        //Instantiate the image loader
        loader = new Asset.images(imagesToLoad, {
            onComplete: allLoaded,
            onProgress: progress
        });
        
    });
});
