﻿// JavaScript Document
// (c) 2008 Trent Foley
; (function ($) {
    document.write("<style type='text/css'>.noscript{display:none}</style>"); var ver = 'galleriffic-0.7'; var galleryOffset = 0; var galleries = []; var allImages = []; var historyCurrentHash; var historyBackStack; var historyForwardStack; var isFirst = false; var dontCheck = false; var isInitialized = false; function getHash() { var hash = location.hash; if (!hash) return -1; hash = hash.replace(/^.*#/, ''); if (isNaN(hash)) return -1; return (+hash); }
    function registerGallery(gallery) { galleries.push(gallery); galleryOffset += gallery.data.length; }
    function getGallery(hash) {
        for (i = 0; i < galleries.length; i++) {
            var gallery = galleries[i]; if (hash < (gallery.data.length + gallery.offset))
                return gallery;
        }
        return 0;
    }
    function historyCallback() { var hash = getHash(); if (hash < 0) return; var gallery = getGallery(hash); if (!gallery) return; var index = hash - gallery.offset; gallery.goto(index); }
    function historyInit() {
        if (isInitialized) return; isInitialized = true; var current_hash = location.hash; historyCurrentHash = current_hash; if ($.browser.msie) { if (historyCurrentHash == '') { historyCurrentHash = '#'; } } else if ($.browser.safari) { historyBackStack = []; historyBackStack.length = history.length; historyForwardStack = []; isFirst = true; }
        setInterval(function () { historyCheck(); }, 100);
    }
    function historyAddHistory(hash) { historyBackStack.push(hash); historyForwardStack.length = 0; isFirst = true; }
    function historyCheck() {
        if ($.browser.safari) {
            if (!dontCheck) {
                var historyDelta = history.length - historyBackStack.length; if (historyDelta) {
                    isFirst = false; if (historyDelta < 0) { for (var i = 0; i < Math.abs(historyDelta); i++) historyForwardStack.unshift(historyBackStack.pop()); } else { for (var i = 0; i < historyDelta; i++) historyBackStack.push(historyForwardStack.shift()); }
                    var cachedHash = historyBackStack[historyBackStack.length - 1]; if (cachedHash != undefined) { historyCurrentHash = location.hash; historyCallback(); } 
                } else if (historyBackStack[historyBackStack.length - 1] == undefined && !isFirst) { historyCallback(); isFirst = true; } 
            } 
        } else { var current_hash = location.hash; if (current_hash != historyCurrentHash) { historyCurrentHash = current_hash; historyCallback(); } } 
    }
    var defaults = { delay: 3000, numThumbs: 20, preloadAhead: 40, enableTopPager: true, enableBottomPager: true, imageContainerSel: '', thumbsContainerSel: '', controlsContainerSel: '', titleContainerSel: '', descContainerSel: '', downloadLinkSel: '', renderSSControls: true, renderNavControls: true, playLinkText: 'Play', pauseLinkText: 'Pause', prevLinkText: 'Previous', nextLinkText: 'Next', nextPageLinkText: 'Next &rsaquo;', prevPageLinkText: '&lsaquo; Prev' }; function clickHandler(gallery) { gallery.pause(); return false; }
    $.fn.galleriffic = function (thumbsContainerSel, settings) {
        $.extend(this, { ver: function () { return ver; }, buildDataFromThumbs: function () { this.data = []; var gallery = this; this.$thumbsContainer.find('li').each(function (i) { var $a = $(this).find('a'); var $img = $a.find('img:first'); gallery.data.push({ slide: $a.attr('href'), thumb: $img.attr('src'), original: $a.attr('original'), title: $a.attr('title'), description: $a.attr('description'), hash: gallery.offset + i }); }); return this; }, isPreloadComplete: false, preloadInit: function () { if (this.settings.preloadAhead == 0) return this; this.preloadStartIndex = this.currentIndex; var nextIndex = this.getNextIndex(this.preloadStartIndex); return this.preloadRecursive(this.preloadStartIndex, nextIndex); }, preloadRelocate: function (index) { this.preloadStartIndex = index; return this; }, preloadRecursive: function (startIndex, currentIndex) {
            if (startIndex != this.preloadStartIndex) { var nextIndex = this.getNextIndex(this.preloadStartIndex); return this.preloadRecursive(this.preloadStartIndex, nextIndex); }
            var gallery = this; var preloadCount = currentIndex - startIndex; if (preloadCount < 0)
                preloadCount = this.data.length - 1 - startIndex + currentIndex; if (this.settings.preloadAhead >= 0 && preloadCount > this.settings.preloadAhead) { setTimeout(function () { gallery.preloadRecursive(startIndex, currentIndex); }, 500); return this; }
            var imageData = this.data[currentIndex]; if (imageData.$image)
                return this.preloadNext(startIndex, currentIndex); var image = new Image(); image.onload = function () { imageData.$image = this; gallery.preloadNext(startIndex, currentIndex); }; image.alt = imageData.title; image.src = imageData.slide; return this;
        }, preloadNext: function (startIndex, currentIndex) {
            var nextIndex = this.getNextIndex(currentIndex); if (nextIndex == startIndex) { this.isPreloadComplete = true; } else { var gallery = this; setTimeout(function () { gallery.preloadRecursive(startIndex, nextIndex); }, 100); }
            return this;
        }, getNextIndex: function (index) {
            var nextIndex = index + 1; if (nextIndex >= this.data.length)
                nextIndex = 0; return nextIndex;
        }, getPrevIndex: function (index) {
            var prevIndex = index - 1; if (prevIndex < 0)
                prevIndex = this.data.length - 1; return prevIndex;
        }, pause: function () {
            if (this.interval)
                this.toggleSlideshow(); return this;
        }, play: function () {
            if (!this.interval)
                this.toggleSlideshow(); return this;
        }, toggleSlideshow: function () {
            if (this.interval) { clearInterval(this.interval); this.interval = 0; if (this.$controlsContainer) { this.$controlsContainer.find('div.ss-controls span').removeClass().addClass('play').attr('title', this.settings.playLinkText).html(this.settings.playLinkText); } } else { this.ssAdvance(); var gallery = this; this.interval = setInterval(function () { gallery.ssAdvance(); }, this.settings.delay); if (this.$controlsContainer) { this.$controlsContainer.find('div.ss-controls span').removeClass().addClass('pause').attr('title', this.settings.pauseLinkText).html(this.settings.pauseLinkText); } }
            return this;
        }, ssAdvance: function () {
            var nextIndex = this.getNextIndex(this.currentIndex); var nextHash = this.data[nextIndex].hash; location.href = '#' + nextHash; if ($.browser.msie) { this.goto(nextIndex); }
            return this;
        }, goto: function (index) { if (index < 0) index = 0; else if (index >= this.data.length) index = this.data.length - 1; this.currentIndex = index; this.preloadRelocate(index); return this.refresh(); }, refresh: function () {
            if (this.$imageContainer) {
                var imageData = this.data[this.currentIndex]; var isFading = 1; var gallery = this; this.$imageContainer.fadeOut('fast', function () {
                    isFading = 0; if (gallery.$controlsContainer) { gallery.$controlsContainer.find('div.nav-controls a.prev').attr('href', '#' + gallery.data[gallery.getPrevIndex(gallery.currentIndex)].hash).end().find('div.nav-controls a.next').attr('href', '#' + gallery.data[gallery.getNextIndex(gallery.currentIndex)].hash); }
                    if (gallery.$titleContainer) { gallery.$titleContainer.empty().html(imageData.title); }
                    if (gallery.$descContainer) { gallery.$descContainer.empty().html(imageData.description); }
                    if (gallery.$downloadLink) { gallery.$downloadLink.attr('href', imageData.original); }
                    if (imageData.$image) { gallery.buildImage(imageData.$image); } 
                }); if (this.onFadeOut) this.onFadeOut(); if (!imageData.$image) { var image = new Image(); image.onload = function () { imageData.$image = this; if (!isFading) { gallery.buildImage(imageData.$image); } }; image.alt = imageData.title; image.src = imageData.slide; }
                this.relocatePreload = true;
            }
            return this.syncThumbs();
        }, buildImage: function (image) {
            if (this.$imageContainer) { this.$imageContainer.empty(); var gallery = this; this.$imageContainer.append('<span class="image-wrapper"><a class="advance-link" rel="history" href="#' + this.data[this.getNextIndex(this.currentIndex)].hash + '" title="' + image.alt + '"></a></span>').find('a').append(image).click(function () { clickHandler(gallery); }).end().fadeIn('fast'); if (this.onFadeIn) this.onFadeIn(); }
            return this;
        }, syncThumbs: function () {
            if (this.$thumbsContainer) { var page = Math.floor(this.currentIndex / this.settings.numThumbs); if (page != this.currentPage) { this.currentPage = page; this.updateThumbs(); } else { var selectedThumb = this.currentIndex % this.settings.numThumbs; this.$thumbsContainer.find('ul.thumbs li.selected').removeClass('selected').end().find('ul.thumbs li').eq(selectedThumb).addClass('selected'); } }
            return this;
        }, updateThumbs: function () {
            if (this.$thumbsContainer) {
                if (this.currentPage < 0)
                    this.currentPage = 0; var startIndex = this.currentPage * this.settings.numThumbs; var stopIndex = startIndex + this.settings.numThumbs - 1; if (stopIndex >= this.data.length)
                    stopIndex = this.data.length - 1; var needsPagination = this.data.length > this.settings.numThumbs; this.$thumbsContainer.empty(); this.$thumbsContainer.append('<div class="top pagination"></div>'); if (needsPagination && this.settings.enableTopPager) { this.buildPager(this.$thumbsContainer.find('div.top')); }
                var $ulThumbs = this.$thumbsContainer.append('<ul class="thumbs"></ul>').find('ul.thumbs'); for (i = startIndex; i <= stopIndex; i++) {
                    var selected = ''; if (i == this.currentIndex)
                        selected = ' class="selected"'; var imageData = this.data[i]; $ulThumbs.append('<li' + selected + '><a rel="history" href="#' + imageData.hash + '" title="' + imageData.title + '"><img src="' + imageData.thumb + '" alt="' + imageData.title + '" /></a></li>');
                }
                if (needsPagination && this.settings.enableBottomPager) { this.$thumbsContainer.append('<div class="bottom pagination"></div>'); this.buildPager(this.$thumbsContainer.find('div.bottom')); }
                var gallery = this; this.$thumbsContainer.find('a[@rel="history"]').click(function () { clickHandler(gallery); });
            }
            return this;
        }, buildPager: function (pager) {
            var startIndex = this.currentPage * this.settings.numThumbs; if (this.currentPage > 0) { var prevPage = startIndex - this.settings.numThumbs; pager.append('<a rel="history" href="#' + this.data[prevPage].hash + '" title="' + this.settings.prevPageLinkText + '">' + this.settings.prevPageLinkText + '</a>'); }
            for (i = this.currentPage - 3; i <= this.currentPage + 3; i++) {
                var pageNum = i + 1; if (i == this.currentPage)
                    pager.append('<strong>' + pageNum + '</strong>'); else { var imageIndex = i * this.settings.numThumbs; if (i >= 0 && i < this.numPages) { pager.append('<a rel="history" href="#' + this.data[imageIndex].hash + '" title="' + pageNum + '">' + pageNum + '</a>'); } } 
            }
            var nextPage = startIndex + this.settings.numThumbs; if (nextPage < this.data.length) { pager.append('<a rel="history" href="#' + this.data[nextPage].hash + '" title="' + this.settings.nextPageLinkText + '">' + this.settings.nextPageLinkText + '</a>'); }
            return this;
        } 
        }); this.settings = $.extend({}, defaults, settings); if (this.interval)
            clearInterval(this.interval); this.interval = 0; if (this.settings.imageContainerSel) this.$imageContainer = $(this.settings.imageContainerSel); if (this.settings.thumbsContainerSel) this.$thumbsContainer = $(this.settings.thumbsContainerSel); if (this.settings.titleContainerSel) this.$titleContainer = $(this.settings.titleContainerSel); if (this.settings.descContainerSel) this.$descContainer = $(this.settings.descContainerSel); if (this.settings.downloadLinkSel) this.$downloadLink = $(this.settings.downloadLinkSel); this.offset = galleryOffset; if (thumbsContainerSel instanceof Array) { this.data = thumbsContainerSel; } else { this.$thumbsContainer = $(thumbsContainerSel); this.buildDataFromThumbs(); }
        registerGallery(this); this.numPages = Math.ceil(this.data.length / this.settings.numThumbs); this.currentPage = -1; this.currentIndex = 0; var gallery = this; if (this.settings.controlsContainerSel) {
            this.$controlsContainer = $(this.settings.controlsContainerSel).empty(); if (this.settings.renderSSControls) { this.$controlsContainer.append('<div class="ss-controls"><span class="play" title="' + this.settings.playLinkText + '">' + this.settings.playLinkText + '</span></div>').find('div.ss-controls span').click(function () { gallery.toggleSlideshow(); }); }
            if (this.settings.renderNavControls) { this.$controlsContainer.append('<div class="nav-controls"><a class="prev" rel="history" title="' + this.settings.prevLinkText + '">' + this.settings.prevLinkText + '</a><a class="next" rel="history" title="Next">' + this.settings.nextLinkText + '</a></div>').find('a[@rel="history"]').click(function () { clickHandler(gallery); }); } 
        }
        historyInit(); var hash = getHash(); var hashGallery = (hash >= 0) ? getGallery(hash) : 0; var gotoIndex = (hashGallery && this == hashGallery) ? (hash - this.offset) : 0; this.goto(gotoIndex); setTimeout(function () { gallery.preloadInit(); }, 1000); return this;
    };
})(jQuery);