// begin DO NOT TOUCH! (unless you know what you're doing)
var scroll = 0;        // while set, scrolls through thumbnails until end is reached
var timeout;           // controls speed of scrolling, inversely proportional to speed
var leftmost;          // sets the end of thumbnail scrolling
var images = [];       // array of images
var i_images;          // index for images
var imgTO;             // holds the timeout counter, used to clear timeout events in click events
var imgTimer = 0;      // flag to indicate whether a timeout event is active
var clickedTn;         // stores currently active thumbnail ID
var tnWidth = 0;       // stores the width of thumbnails
var tnWindowWidth = 0; // stores the width of the container of thumbnails
var playSlideShow = 0; // plays through all images if set
var imgOver = 0;       // disables/enables sequence play through
var direction = 1;     // thumbnail scroll direction (1 - next; 0 - prev)
var imgOver = 0;       // flag to indicate whether mouse is over displayed image
var imgID = '#imgPanel';
var captionID = '#captionPanel';
var scrollerID = '#tnScroller';
var scrollWindowID = '#tnScrollInner';
var scrollControlID = '#slideControl';
var scrollLeftID = '#scLeft';
var scrollRightID = '#scRight';
var showNextID = '#showNext';
var showPrevID = '#showPrev';
var playSlideShowID = '#playSlideShow';
var cacheID = '#cache';
var imgOverID = '#imgPanelOver';         // id for the overlay div for cross dissolving displayed image
var captionOverID = '#captionPanelOver'; // id for the overlay div for cross dissolving caption
var sfxImage = 'Img';
var sfxAnchor = 'Anc';
var xgif = '/static/js/rh-image-gallery/x.gif';
// end DO NOT TOUCH!

// begin configuration variables
var fadeDuration = 750;           // duration of fade in effect (miliseconds)
var showDuration = 1500;          // time for image to be stale in slideshow (miliseconds)
var slideSpeedMultiplier = 2;     // increase for faster time (applies to scroll bar only)
var tnFadeDuration = 350;         // duration of fade of thumbnails (miliseconds)
var tnOpacity = 0.35;             // inactive thumbnail opacity (1 is opaque, 0 is transparent)
var showCaption = 0;              // displays the content of alt under the image if set
var showPageNum = 0;
var playSeqOnMouseEnter = 1;      // if set, multi-image plays on hover event, else, plays automatically
var scrollBarDivision = 10;       // division of the scroll bar (has to be at least 4 and an even numberi)
var playSlideShowRepeat = 1;      // restarts slide when it reaches the end
var playBtn = 'Play Slide Show';  // content of play button, can be set to an <img> tag
var pauseBtn = 'Stop Slide Show'; // content of pause button, can be set to an <img> tag
// end configuration variables

// define a class to hold information necessary for
// gallery display
function galleryImg() {
    this.tnPath = '';       // holds thumbnail path (first <a></a>'s <img>)
    this.imgPaths = [];     // holds an array of paths to display images (from <a></a>)
    this.imgDesc = [];      // holds an array of description of display iamges (from <a></a>'s title attribute)
    this.description = '';  // holds thumbnail's alt attribute
    this.cached = 0;        // flag that indicates whether the display images have been cached
    this.tnObj;             // holds the thumbnail DOM object

    this.setTn = function(path) { this.tnPath = path; }
    this.isCached = function() { return this.cached; }
    this.setCached = function() { this.cached = 1; }
    this.addImg = function(path) { this.imgPaths.push(path); }
    this.addImgDesc = function(desc) { this.imgDesc.push(desc); }
    this.getTn = function() { return this.tnPath; }
    this.getTnHTML = function() {
        return '<img alt="' + this.description + '" src="' + this.tnPath + '">';
    }
    this.getImg = function(i) { return this.imgPaths[i]; }
    this.getImgHTML = function(i) {
	var desc = (this.imgDesc[i] != '') ? this.imgDesc[i] : this.description;
        return '<img alt="' + desc + '" src="' + this.imgPaths[i] + '">';
    }
    this.getImgDesc = function(i) { return this.imgDesc[i]; }
    this.getNumImg = function() { return this.imgPaths.length; }
    this.setDesc = function(desc) { this.description = desc; }
    this.getDesc = function() { return this.description; }
    this.setTnObj = function(t) { this.tnObj = t; }
    this.getTnObj = function() { return this.tnObj; }
}

function tnScrollStop() {
    scroll = 0;
}

function tnScrollStart(t, d) {
    scroll = 1;
    var id = (d) ? scrollRightID.replace('#', '') : scrollLeftID.replace('#', '');
    var to = parseInt(t.attr('id').replace(id, ''));
    timeout = 800 / slideSpeedMultiplier / Math.pow(2, to);
    $(scrollerID).stop();
    var left = parseInt($(scrollerID).css('left').replace('px', ''));
    var rem = left % tnWidth;
    left = (!d) ? (left + tnWidth) : left;
    left -= rem;
    left = (left < leftmost) ? leftmost : (left > 0) ? 0 : left;
    if(rem) {
        $(scrollerID).css('left', left + 'px');
    }
    tnScroll(left, d);
}

function tnScroll(left, d) {
    var leftval = '';
    if(d) {
        if((left - tnWidth) > leftmost) {
            left = left - tnWidth;
            leftval = '-=' + tnWidth + 'px';
        } else {
            $(scrollerID).css('left', leftmost + 'px');
        }
    } else {
        if((left + tnWidth) <= 0) {
            left = left + tnWidth;
            leftval = '+=' + tnWidth + 'px';
        } else {
            $(scrollerID).css('left', '0px');
        }
    }
    if(scroll && leftval != '') {
        $(scrollerID).animate({ "left": leftval }, timeout, "linear", function() {
            tnScroll(left, d);
        });
    }
}

function tnMouseEnter(tn) {
    var t = parseInt(tn.attr('title'));
    cacheImg(t);
    if(tn.is(':animated')) {
        tn.stop().fadeTo(0, 0.5);
    }
    direction = 1;
    tn.fadeTo(tnFadeDuration, 1);
}

function tnMouseLeave(tn) {
    var t = parseInt(tn.attr('title'));
    if(tn.is(':animated')) {
        tn.stop().fadeTo(0, 1);
    }
    if(t != clickedTn) {
        tn.fadeTo(tnFadeDuration, tnOpacity);
    }
}

function tnClick(tn, e) {
    e.preventDefault();
    var t = parseInt(tn.attr('title'));
    if(t != clickedTn) {
        if(typeof(clickedTn) != 'undefined') {
            images[clickedTn].getTnObj().fadeTo(tnFadeDuration, tnOpacity);
        }
        clickedTn = t;
    	if(clickedTn == 0) {
            $(showPrevID).fadeTo(tnFadeDuration, tnOpacity);
            if(images.length > 1) {
                $(showNextID).fadeTo(tnFadeDuration, 1);
            } else {
                $(showNextID).fadeTo(tnFadeDuration, tnOpacity);
            }
        } else if(clickedTn >= (images.length - 1)) {
            $(showNextID).fadeTo(tnFadeDuration, tnOpacity);
            $(showPrevID).fadeTo(tnFadeDuration, 1);
        } else {
            $(showPrevID).fadeTo(tnFadeDuration, 1);
            $(showNextID).fadeTo(tnFadeDuration, 1);
        }
        if(images[clickedTn].getTnObj().css('opacity') != '1') {
            images[clickedTn].getTnObj().stop().fadeTo(tnFadeDuration, 1);
        }
        i_images = 0;
        cleanCache();
        if(imgTimer) {
            clearTimeout(imgTO);
            imgTimer = 0;
        }
        scrollTo(clickedTn);
        imgShow();
    } else if(playSlideShow) {
        imgShow();
    }
}

function playSequence() {
    var i = images[clickedTn].getNumImg();
    var p = playSeqOnMouseEnter;
    if(playSlideShow && (i_images >= (i - 1) || i == 1)) {
        if(clickedTn >= (images.length - 1)) {
            if(i > 1 && ((p && imgOver) || (!p && !imgOver) || playSlideShow)) {
                i_images = (++i_images >= i) ? 0 : i_images;
                imgShow();
            }
            if(!playSlideShowRepeat) {
                $(playSlideShowID).html(playBtn);
                playSlideShow = 0;
            } else {
                images[0].getTnObj().click();
            }
        } else {
            $(showNextID).click();
        }
    } else if(i > 1 && ((p && imgOver) || (!p && !imgOver) || playSlideShow)) {
        i_images = (++i_images >= i) ? 0 : i_images;
        imgShow();
    }
}

function imgShow() {
    if($(imgOverID + sfxImage).is(':animated')) {
        $(imgID + sfxImage).stop().fadeTo(0, 0);
        $(imgOverID + sfxImage).stop().fadeTo(0, 1);
        $(captionOverID + 1).stop().fadeTo(0, 0);
        $(captionOverID + 2).stop().fadeTo(0, 1);
    }
    $(imgID + sfxImage).attr('src', $(imgOverID + sfxImage).attr('src'));
    $(imgID + sfxImage).attr('alt', $(imgOverID + sfxImage).attr('alt'));
    var i = images[clickedTn];
    $(imgOverID + sfxImage).attr('src', i.getImg(i_images));
    $(imgOverID + sfxImage).attr('alt', i.getDesc());
    var t = '';
    if(showPageNum || showCaption) {
        if(showPageNum) {
            t += (clickedTn + 1) + ' of ' + images.length + ' - ';
        }
        if(showCaption) {
            t += i.getDesc();
        }
    } else if(i.getNumImg() > 1) {
        var desc = images[clickedTn].getImgDesc(i_images);
            t += (desc != '') ? desc : ' (' + (i_images + 1) + '/' + i.getNumImg() + ')';
        if(playSeqOnMouseEnter) {
            t += ' rollover image to view';
        }
    }
    $(captionOverID + 1).html($(captionOverID + 2).html());
    $(captionOverID + 2).html(t);
    var p = playSeqOnMouseEnter;
    $(captionOverID + 1).fadeTo(0, 1).fadeTo(fadeDuration, 0);
    $(captionOverID + 2).fadeTo(0, 0).fadeTo(fadeDuration, 1);
    $(imgID + sfxImage).fadeTo(0, 1).fadeTo(fadeDuration, 0);
    $(imgOverID + sfxImage).fadeTo(0, 0).fadeTo(fadeDuration, 1, function() {
        if((p && (imgOver || playSlideShow)) || (!p && !imgOver)) {
            clearTimeout(imgTO);
            imgTO = setTimeout(function() {
                playSequence();
            }, showDuration);
            imgTimer = 1;
        }
    });
}

function imgMouseEnter(img) {
    imgOver = 1;
    var n = images[clickedTn].getNumImg();
    if(!playSeqOnMouseEnter || (playSeqOnMouseEnter && !playSlideShow)) {
   	if(img.is(':animated')) {
            img.stop().fadeTo(0, 1);
        }
        if(imgTimer) {
            clearTimeout(imgTO);
            imgTimer = 0;
        }
    }
    if(playSeqOnMouseEnter && n > 1 && !playSlideShow) {
    	i_image = (++i_images >= n) ? 0 : i_images;
        imgShow();
    }
}

function imgMouseLeave(img) {
    imgOver = 0;
    var n = images[clickedTn].getNumImg();
    if(!playSeqOnMouseEnter) {
	clearTimeout(imgTO);
        imgTO = setTimeout(function() {
            playSequence();
        }, showDuration);
        imgTimer = 1;
    } else if(n > 1 && !playSlideShow && i_images != 0) {
    	i_images = 0;
	imgShow();
    }
}

function scrollTo(n) {
    var l = parseInt($(scrollerID).css('left').replace('px', ''));
    var r = (tnWindowWidth - (tnWindowWidth % tnWidth)) / tnWidth - 1;
    var rStart = (0 - l) / tnWidth;
    if(n < rStart || n > (rStart + r)) {
        if(direction) {
            var left = (0 - n + r) * tnWidth;
            left = (left > 0) ? 0 : left;
            $(scrollerID).animate({
                "left": '+=' + (left - l) + 'px'
            }, tnFadeDuration, 'linear');
        } else {
            var left = (0 - n) * tnWidth;
            left = (left > 0) ? 0 : left;
            $(scrollerID).animate({
                "left": '-=' + (l - left) + 'px'
            }, tnFadeDuration, 'linear');
        }
    }
}

function navClick(e, d) {
    e.preventDefault();
    var n = clickedTn;
    if(!d && clickedTn > 0) {
        n = (--n < 0) ? 0 : n;
        cacheImg(n - 1);
    } else if(d && clickedTn < (images.length - 1)) {
        n = (++n >= images.length) ? (images.length - 1) : n;
        cacheImg(n + 1);
    }
    direction = d;
    if(n != clickedTn) {
        if($(scrollerID).is(':animated')) {
            $(scrollerID).stop();
        }
        images[n].getTnObj().click();
    }
}

function playSlideShowClick(e, me) {
    e.preventDefault();
    me.html((playSlideShow) ? playBtn : pauseBtn);
    playSlideShow = !playSlideShow;
    if(playSlideShow && clickedTn >= (images.length - 1)) {
        var l = parseInt($(scrollerID).css('left').replace('px', ''));
        if($(scrollerID).is(':animated')) {
            $(scrollerID).stop();
        }
        i_images = (++i_images > images[0].getNumImg()) ? 0 : i_images;
        images[0].getTnObj().click();
    } else if(playSlideShow) {
        $(showNextID).click();
    }
    if(!playSlideShow && playSeqOnMouseEnter) {
        $(imgOverID + sfxImage).mouseleave();
    }
}

function cacheImg(n) {
    if(n > -1 && n < images.length) {
        if(!images[n].isCached()) {
            for(var i = 0; i < images[n].getNumImg(); i++) {
                $(cacheID).append(images[n].getImgHTML(i));
            }
            images[n].setCached();
        }
    } else {
        cleanCache();
    }
}

function cleanCache() {
    $(cacheID).html('');
}

function processListItem() {
    // process thumbnails
    var t = 0;
    images = [];
    $(scrollerID).children().each(function() {
        // create an array of galleryImg
        var img = new galleryImg();
        // retrieve display image data
        var i = 0;
        $(this).children().each(function() {
            if(i == 0) {
                img.setTn($(this).children().attr('src'));
                img.setDesc($(this).children().attr('alt'));
                i++;
                img.addImg($(this).attr('href'));
                img.addImgDesc($(this).attr('title'));
            } else if(i > 0) {
                if(this.tagName != 'A') {
                    img.setDesc($(this).html());
                } else {
                    img.addImg($(this).attr('href'));
                    img.addImgDesc($(this).attr('title'));
                }
            }
        });
        // sets the title of thumbnail anchor to hold its index value in the array
        $(this).attr('title', t);
        $(this).bind("mouseenter", function() { tnMouseEnter($(this)); });
        $(this).bind("mouseleave", function() { tnMouseLeave($(this)); });
        $(this).click(function(event) { tnClick($(this), event); });
        $(this).fadeTo(0, tnOpacity);
        img.setTnObj($(this));
        images.push(img);
        // calculate width of each thumbnail
        // also taking into account its padding and margin
        if(tnWidth == 0) {
            tnWidth = parseInt($(this).css('width').replace('px', ''));
            tnWidth += parseInt($(this).css('padding-left').replace('px', ''));
            tnWidth += parseInt($(this).css('padding-right').replace('px', ''));
            tnWidth += parseInt($(this).css('margin-left').replace('px', ''));
            tnWidth += parseInt($(this).css('margin-right').replace('px', ''));
        }
	t++;
    });
}

function galleryInit() {
    // add div to cache image
    $(document.body).append('<div id="' + cacheID.replace('#', '') + '"></div>');
    $(cacheID).css('display', 'none');

    // setting thumbnail scroller properties
    tnWindowWidth = parseInt($(scrollWindowID).css('width').replace('px', ''));
    $(scrollerID).css('left', 0).css('width', images.length * tnWidth);
    leftmost = (0 - images.length) * tnWidth + tnWindowWidth;

    // add overlay div for cross dissolving
    $(captionID).css('position', 'relative').css('overflow', 'hidden');
    var id = imgID.replace('#', '');
    $(imgID).html('<img id="' + id + sfxImage + '" src="" alt="a">');
    id = imgOverID.replace('#', '');
    $(imgID).css('position', 'relative').css('overflow', 'hidden');
    $(imgID).append('<div id="' + id + '"><img id="' + id + sfxImage + '" src="" alt=""></div>');
    $(imgOverID).css('position', 'absolute').css('top', '0px').css('left', '0px');
    $(imgOverID).css('width', $(imgID).css('width')).css('height', $(imgID).css('height'));
    id = captionOverID.replace('#', '')
    $(captionID).append('<div id="' + id + '1"></div><div id="' + id + '2"></div>');
    $(captionOverID + 1).css('width', $(captionID).css('width')).css('position', 'absolute');
    $(captionOverID + 1).css('top', '0px').css('left', '0px');
    $(captionOverID + 2).css('width', $(captionID).css('width')).css('position', 'absolute');
    $(captionOverID + 2).css('top', '0px').css('left', '0px');

    // add hover events to temporarily stop slide show
    $(imgOverID).bind("mouseenter", function() { imgMouseEnter($(this)); });
    //$(imgOverID).click(function() { imgMouseEnter($(this)); });
    $(imgOverID).bind("mouseleave", function() { imgMouseLeave($(this)); });

    // create slider bar controls
    var w = parseInt($(scrollControlID).css('width').replace('px', ''));
    var h = parseInt($(scrollControlID).css('height').replace('px', ''));
    w = (w - (w % scrollBarDivision)) / scrollBarDivision;
    var sc;
    var speed = ['', 'slowly', 'normally', 'quickly', 'very quickly'];
    for(var i = (scrollBarDivision / 2 - 1); i >= 0; i--) {
	id = scrollLeftID.replace('#', '');
        sc = '<div id="' + id + i + '"><a href="#" id="' + id + sfxAnchor + i;
        sc += '"><img id="' + id + sfxImage + i + '" src="' + xgif + '" alt="' + (i > 0) ? 'scroll left ' : 'spacer';
	sc += speed[i] + '"></a></div>';
        $(scrollControlID).append(sc);
        if(i > 0) {
            $(scrollLeftID + i).bind("mouseenter", function() { tnScrollStart($(this), 0); });
            $(scrollLeftID + i).bind("mouseleave", function() { tnScrollStop(); });
        }
        $(scrollLeftID + i).click(function(event) { event.preventDefault(); });
        $(scrollLeftID + i).css('float', 'left').css('width', w + 'px').css('height', h + 'px').css('border', '0px');
    }
    for(var i = 0; i <= (scrollBarDivision / 2 - 1); i++) {
    	id = scrollRightID.replace('#', '');
    	sc = '<div id="' + id + i + '"><a href="#" id="' + id + sfxAnchor + i;
	sc += '"><img id="' + id + sfxImage + i + '" src="' + xgif + '" alt="' + (i > 0) ? 'scroll right ' : 'spacer';
        sc += speed[i] + '"></a></div>';
        $(scrollControlID).append(sc);
        if(i > 0) {
            $(scrollRightID + i).bind("mouseenter", function() { tnScrollStart($(this), 1); });
            $(scrollRightID + i).bind("mouseleave", function() { tnScrollStop(); });
        }
        $(scrollRightID + i).click(function(event) { event.preventDefault(); });
        $(scrollRightID + i).css('float', 'left').css('width', w + 'px').css('height', h + 'px').css('border', '0px');
    }
    $(scrollControlID).append('<div class="clear"></div>');

    // bind controler events
    $(showPrevID).click(function(event) { navClick(event, 0); });
    $(showPrevID).bind("mouseenter", function() { cacheImg(clickedTn - 1); });
    $(showNextID).click(function(event) { navClick(event, 1); });
    $(showNextID).bind("mouseenter", function() { cacheImg(clickedTn + 1); });
    $(playSlideShowID).html(playBtn);
    $(playSlideShowID).click(function(event) { playSlideShowClick(event, $(this)); });
}

$(document).ready(function() {
    processListItem();
    galleryInit();
    // start with first image
    images[0].getTnObj().click();
    cacheImg(1);
});

