/**
* Scrolling location photos widget
* Requires: animator.js, prototype.js, vntools.js
*
*/

var locationPhotos = {
    init: function () { // call this immediately after the photos HTML and locationPhotos.images array are written to the page
        if (locationPhotos.images.length > 1) { // only do all this if we have more than 1 image
            var node = document.createElement('A');
            node.appendChild(document.createElement('IMG'));
            locationPhotos.nodes.thumb = node;
            locationPhotos.viewport.init();
        }
    },
    nodes: {
        thumb: undefined
    },
    on: {
        next: function () {
            locationPhotos.viewport.removeEventListeners();
            locationPhotos.index.increment();
            locationPhotos.viewport.setBigImage();
            locationPhotos.viewport.setSelectedThumb('next');
            if ('thumbs' == locationPhotos.viewport.element.id) {
                locationPhotos.viewport.add.right();
                locationPhotos.viewport.move.forward();
            } else {
                locationPhotos.viewport.restoreEventListeners();
            }
        },
        previous: function () {
            locationPhotos.viewport.removeEventListeners();
            locationPhotos.index.decrement();
            locationPhotos.viewport.setBigImage();
            locationPhotos.viewport.setSelectedThumb('previous');
            if ('thumbs' == locationPhotos.viewport.element.id) {
                locationPhotos.viewport.add.left();
                locationPhotos.viewport.move.back();
            } else {
                locationPhotos.viewport.restoreEventListeners();
            }
        },
        next2: function () {
            locationPhotos.viewport.removeEventListeners();
            locationPhotos.index.increment();
            locationPhotos.index.increment();
            locationPhotos.viewport.setBigImage();
            locationPhotos.viewport.setSelectedThumb('next2');
            locationPhotos.viewport.restoreEventListeners();
        },
        previous2: function () {
            locationPhotos.viewport.removeEventListeners();
            locationPhotos.index.decrement();
            locationPhotos.index.decrement();
            locationPhotos.viewport.setBigImage();
            locationPhotos.viewport.setSelectedThumb('previous2');
            locationPhotos.viewport.restoreEventListeners();
        }
    },
    index: {
        value: 0, // current index of the images array (the big image)
        increment: function () {
            locationPhotos.index.value = (locationPhotos.index.value + 1).mod(locationPhotos.images.length);
        },
        decrement: function () {
            locationPhotos.index.value = (locationPhotos.index.value - 1).mod(locationPhotos.images.length);
        }
    },
    viewport: {
        element: undefined, // reference to the actual viewport DOM element
        animator: {
            // animation characteristics
            duration: 300,
            optionsNext: undefined,
            optionsPrevious: undefined,
            // positioning
            restPosition: -23,
            movePosition: -93,
            // callback on complete of animation
            callback: function (dir) {
                locationPhotos.viewport.prune(dir);
                locationPhotos.viewport.restoreEventListeners();
            }
        },
        init: function () {
            var id = (2 == locationPhotos.images.length)? 'thumbs-2': (3 == locationPhotos.images.length)? 'thumbs-3': 'thumbs';
            locationPhotos.viewport.element = $(id);
            locationPhotos.viewport.animator.optionsNext = {
                duration: locationPhotos.viewport.animator.duration,
                onComplete: function() {
                    locationPhotos.viewport.animator.callback('next');
                }
            };
            locationPhotos.viewport.animator.optionsPrevious = {
                duration: locationPhotos.viewport.animator.duration,
                onComplete: function() {
                    locationPhotos.viewport.animator.callback('previous');
                }
            };
            // preload images
            $A(locationPhotos.images).each(function (filename) {
                var img = new Image();
                img.src = filename.small;
            });
            // ready to go, activate the controls
            locationPhotos.viewport.restoreEventListeners();
        },
        move: {
            forward: function () {
                var next = new Animator(locationPhotos.viewport.animator.optionsNext).addSubject(new NumericalStyleSubject(locationPhotos.viewport.element, 'left', locationPhotos.viewport.animator.restPosition, locationPhotos.viewport.animator.movePosition));
                next.seekTo(1);
            },
            back: function () {
                var previous = new Animator(locationPhotos.viewport.animator.optionsPrevious).addSubject(new NumericalStyleSubject(locationPhotos.viewport.element, 'left', locationPhotos.viewport.animator.movePosition, locationPhotos.viewport.animator.restPosition));
                previous.seekTo(1);
            }
        },
        add: { // add an image to the thumbs container
            width: function () {
                locationPhotos.viewport.element.setStyle({
                    width: locationPhotos.viewport.element.getWidth() + 75 + 'px'
                });
            },
            left: function () {
                // increase width of container
                locationPhotos.viewport.add.width();
                // determine which image to add
                var index = (locationPhotos.index.value - 2).mod(locationPhotos.images.length);
                // add photo
                var src = locationPhotos.images[index].small;
                var a = locationPhotos.nodes.thumb.cloneNode(true);
                a.firstChild.src = src;
                var newElement = locationPhotos.viewport.element.cloneNode(true);
                newElement.insertBefore(a, newElement.firstChild);
                newElement.setStyle({
                    left: locationPhotos.viewport.animator.movePosition + 'px'
                });
                locationPhotos.viewport.element.parentNode.replaceChild(newElement, locationPhotos.viewport.element);
                locationPhotos.viewport.element = newElement;
            },
            right: function () {
                // increase width of container
                locationPhotos.viewport.add.width();
                // determine which image to add
                var index = (locationPhotos.index.value + 2).mod(locationPhotos.images.length);
                // add photo
                var src = locationPhotos.images[index].small;
                var a = locationPhotos.nodes.thumb.cloneNode(true);
                a.firstChild.src = src;
                locationPhotos.viewport.element.appendChild(a);
            }
        },
        prune: function (dir) { // reduce the image set to the ones showing, always shifting the left property to the resting position
            // prune unnecessary photos
            if ('previous' == dir) {
                var imgs = locationPhotos.viewport.element.immediateDescendants();
                imgs[imgs.length - 1].remove();
                // shift left position
                locationPhotos.viewport.element.setStyle({
                    left: locationPhotos.viewport.animator.restPosition + 'px'
                });
            } else { // 'next' == dir
                var newElement = locationPhotos.viewport.element.cloneNode(true);
                var children = newElement.getElementsByTagName('A');
                children[0].remove();
                newElement.setStyle({
                    left: locationPhotos.viewport.animator.restPosition + 'px'
                });
                locationPhotos.viewport.element.parentNode.replaceChild(newElement, locationPhotos.viewport.element);
                locationPhotos.viewport.element = newElement;
            }
            // reduce the DIV width
            locationPhotos.viewport.element.setStyle({
                width: locationPhotos.viewport.element.getWidth() - 75 + 'px'
            });
        },
        setBigImage: function () {
            var newSrc = locationPhotos.images[locationPhotos.index.value].large;
            $('big').src = newSrc;
        },
        setSelectedThumb: function (dir) {
            var imgs = locationPhotos.viewport.element.getElementsByClassName('selected');
            imgs[0].removeClassName('selected');
            switch (dir) {
                case 'previous':
                    var img = imgs[0].previous();
                    if (!img) {
                        if ('thumbs-2' == locationPhotos.viewport.element.id) {
                            img = imgs[0].next();
                        } else if ('thumbs-3' == locationPhotos.viewport.element.id) {
                            imgs = imgs[0].siblings();
                            img = imgs[imgs.length - 1];
                        } else {
                            // PEBCAK
                        }
                    }
                    break;
                case 'next':
                    var img = imgs[0].next();
                    if (!img) {
                        if ('thumbs-2' == locationPhotos.viewport.element.id) {
                            img = imgs[0].previous();
                        } else if ('thumbs-3' == locationPhotos.viewport.element.id) {
                            imgs = imgs[0].siblings();
                            img = imgs[0];
                        } else {
                            // PEBCAK
                        }
                    }
                    break;
                case 'previous2':
                    imgs = imgs[0].siblings();
                    img = imgs[0];
                    break;
                case 'next2':
                    imgs = imgs[0].siblings();
                    img = imgs[imgs.length - 1];
                    break;
            }
            img.addClassName('selected');
        },
        removeEventListeners: function () { // while an animation is happening, remove all event listeners to avoid crazy clicks
            // detach event listeners
            if (document.all && !window.opera) {
                Event.stopObserving($('photo-left'), 'click', locationPhotos.on.previous);
                Event.stopObserving($('photo-right'), 'click', locationPhotos.on.next);
            } else {
                Event.stopObserving($('photo-arrow-left'), 'click', locationPhotos.on.previous);
                Event.stopObserving($('photo-arrow-right'), 'click', locationPhotos.on.next);
            }
            var imgs = locationPhotos.viewport.element.getElementsByClassName('selected');
            if ('thumbs-3' == locationPhotos.viewport.element.id) {
                var sibs = imgs[0].siblings();
                switch (locationPhotos.index.value) {
                    case 2:
                        Event.stopObserving(sibs[0], 'click', locationPhotos.on.next);
                        Event.stopObserving(sibs[1], 'click', locationPhotos.on.next2);
                        break;
                    case 0:
                        Event.stopObserving(sibs[0], 'click', locationPhotos.on.previous);
                        Event.stopObserving(sibs[1], 'click', locationPhotos.on.next);
                        break;
                    case 1:
                        Event.stopObserving(sibs[0], 'click', locationPhotos.on.previous2);
                        Event.stopObserving(sibs[1], 'click', locationPhotos.on.previous);
                        break;
                }
            } else {
                var imgs = locationPhotos.viewport.element.getElementsByClassName('selected');
                var nextImg = imgs[0].next();
                var previousImg = imgs[0].previous();
                if (nextImg) Event.stopObserving(nextImg, 'click', locationPhotos.on.next);
                if (previousImg) Event.stopObserving(previousImg, 'click', locationPhotos.on.previous);
            }
        },
        restoreEventListeners: function () { // once an animation has stopped, restore event listeners to center 3 images and < and > icons
            // attach click events to arrows
            if (document.all && !window.opera) {
                Event.observe($('photo-left'), 'click', locationPhotos.on.previous);
                Event.observe($('photo-right'), 'click', locationPhotos.on.next);
                // workaround for IE's lack of ability to handle a simple mouseover
                Event.observe($('photo-left'), 'mouseover', function () { imgHi($('photo-left').childNodes[0].childNodes[0]); });
                Event.observe($('photo-left'), 'mouseout', function () { imgLo($('photo-left').childNodes[0].childNodes[0]); });
                Event.observe($('photo-right'), 'mouseover', function () { imgHi($('photo-right').childNodes[0].childNodes[0]); });
                Event.observe($('photo-right'), 'mouseout', function () { imgLo($('photo-right').childNodes[0].childNodes[0]); });
            } else {
                Event.observe($('photo-arrow-left'), 'click', locationPhotos.on.previous);
                Event.observe($('photo-arrow-right'), 'click', locationPhotos.on.next);
            }
            var imgs = locationPhotos.viewport.element.getElementsByClassName('selected');
            if ('thumbs-3' == locationPhotos.viewport.element.id) {
                var sibs = imgs[0].siblings();
                switch (locationPhotos.index.value) {
                    case 2:
                        Event.observe(sibs[0], 'click', locationPhotos.on.next);
                        Event.observe(sibs[1], 'click', locationPhotos.on.next2);
                        break;
                    case 0:
                        Event.observe(sibs[0], 'click', locationPhotos.on.previous);
                        Event.observe(sibs[1], 'click', locationPhotos.on.next);
                        break;
                    case 1:
                        Event.observe(sibs[0], 'click', locationPhotos.on.previous2);
                        Event.observe(sibs[1], 'click', locationPhotos.on.previous);
                        break;
                }
            } else {
                var nextImg = imgs[0].next();
                var previousImg = imgs[0].previous();
                if (nextImg) {
                    Event.observe(nextImg, 'click', locationPhotos.on.next);
                }
                if (previousImg) {
                    Event.observe(previousImg, 'click', locationPhotos.on.previous);
                }
            }
        }
    }
};
