/**
Script: Slideshow.js
	Slideshow - A javascript class for Mootools to stream and animate the presentation of images on your website.

License:
	MIT-style license.

Copyright:
	Copyright (c) 2011 [Aeron Glemann](http://www.electricprism.com/aeron/).

Dependencies:
	Mootools 1.3.1 Core: Fx.Morph, Fx.Tween, Selectors, Element.Dimensions.
	Mootools 1.3.1.1 More: Assets.
 */
(function(){
    WhenPaused = 1 << 0;
    WhenPlaying = 1 << 1;
    OnStart = 1 << 2;
	
    Videoshow = new Class({
        Implements: [Chain, Events, Options],

        options: {/*
			onComplete: $empty,
			onEnd: $empty,
			onStart: $empty,*/
            accesskeys: {
                'first': {
                    'key': 'shift left', 
                    'label': 'Shift + Leftwards Arrow'
                }, 
                'prev': {
                    'key': 'left', 
                    'label': 'Leftwards Arrow'
                }, 
                'pause': {
                    'key': 'p', 
                    'label': 'P'
                }, 
                'next': {
                    'key': 'right', 
                    'label': 'Rightwards Arrow'
                }, 
                'last': {
                    'key': 'shift right', 
                    'label': 'Shift + Rightwards Arrow'
                }
            },
            center: true,
            classes: [/*'slideshow', 'first', 'prev', 'play', 'pause', 'next', 'last', 'images', 'captions', 'controller', 'thumbnails', 'hidden', 'visible', 'inactive', 'active', 'loader'*/],
            data: null,
            delay: 2000,
            duration: 1000,
            fast: false,
            height: false,
            thrumbProportion: {'width': 100, 'height': 75, 'exact': true},
            href: '',
            hu: '',
            linked: false,
            loader: true,
            loop: true,
            match: /\?slide=(\d+)$/,
            overlap: true,
            paused: false,
            random: false,
            replace: [/(\.[^\.]+)$/, 't$1'],
            resize: 'fill',
            slide: 0,
            thumbnails: true,
            titles: false,
            transition: 'sine:in:out',
            thumbURL: 'http://i.ytimg.com/vi/{key}/0.jpg',
            width: false
        },

        /**
	Constructor: initialize
		Creates an instance of the Slideshow class.

	Arguments:
		element - (element) The wrapper element.
		data - (array or object) The images and optional thumbnails, captions and links for the show.
		options - (object) The options below.

	Syntax:
		var myShow = new Slideshow(element, data, options);
         */

        initialize: function(el, data, options) {
            this.setOptions(options);
            this.el = document.id(el);
            if (!this.el) 
                return;
            var match = window.location.href.match(this.options.match);
            this.slide = this._slide = this.options.match && match ? match[1].toInt() 
            : this.options.slide;
            this.counter = this.timeToNextTransition = this.timeToTransitionComplete = 0;
            this.direction = 'left';
            this.cache = {};
            this.paused = false;
            if (!this.options.overlap)
                this.options.duration *= 2;
            var anchor = this.el.getElement('a') || new Element('a');
            if (!this.options.href)
                this.options.href = anchor.get('href') || '';
            if (this.options.hu.length && !this.options.hu.test(/\/$/)) 
                this.options.hu += '/';
            if (this.options.fast === true)
                this.options.fast = WhenPaused | WhenPlaying;

            // styles

            var keys = 'slideshow first prev play pause next last images captions controller thumbnails hidden visible inactive active loader'.split(' '),
            values = keys.map(function(key, i){
                return this.options.classes[i] || key;
            }, this);
            this.classes = values.associate(keys);
            this.classes.get = function(){
                var str = '.' + this.slideshow;
                for (var i = 0, l = arguments.length; i < l; i++)
                    str += '-' + this[arguments[i]];
                return str;
            }.bind(this.classes);
                        
            var loaded = this.load(data);
            if (!loaded)
                return; 

            // events

            this.events = {};
            this.events.push = function(type, fn){
                if (!this[type])
                    this[type] = [];
                this[type].push(fn);
                document.addEvent(type, fn);
                return this;
            }.bind(this.events);

            this.accesskeys = {};
            for (action in this.options.accesskeys){
                var obj = this.options.accesskeys[action];
                this.accesskeys[action] = accesskey = {
                    'label': obj.label
                };
                ['shift', 'control', 'alt'].each(function(modifier){
                    var re = new RegExp(modifier, 'i');
                    accesskey[modifier] = obj.key.test(re);
                    obj.key = obj.key.replace(re, '');
                });
                accesskey.key = obj.key.trim();
            }

            this.events.push('keyup', function(e){
                Object.each(this.accesskeys, function(accesskey, action){
                    if (e.key == accesskey.key && e.shift == accesskey.shift && e.control == accesskey.control && e.alt == accesskey.alt)
                        this[action]();
                }, this);			
            }.bind(this));	 

            // required elements
            
            var containterID = 'video_' + String.uniqueID();

            this.height = this.options.height;		
            this.width = this.options.width;
           
            
            var images = new Element('div', {
                'id': containterID,
                'styles': {
                    'width': this.width,
                    'height': this.height
                },
                'class': this.classes.get('images').substr(1)
            }).inject(this.el);
            
            // Init Video Player X1dtGlqU9Y0
            new Swiff('http://www.youtube.com/e/' + this.data.images[this._slide] + '?enablejsapi=1&rel=0', {
                'container': containterID,
                'id': 'uTubePlayerObject',
                'width': this.width,
                'height': this.height,
                'params': {
                    'wMode': 'opaque'
                }
            });

            this.uTimer = (function () {
                if (document.id("uTubePlayerObject") != null) {
                    this.playerAPI = document.id("uTubePlayerObject");
                    clearInterval(this.uTimer);
                }
            }).periodical(100, this);
                
            //  this.el.store('images', images);
            this.a = this.b = {};


            // optional elements
            this.options.loader && new Loader(this);
            this.options.thumbnails && new Thumbnails(this);

        // begin show
  
        //   this._preload(this.options.fast & OnStart);
    
            
       
        },

        /**
	Public method: go
		Jump directly to a slide in the show.

	Arguments:
		n - (integer) The index number of the image to jump to, 0 being the first image in the show.

	Syntax:
		myShow.go(n);	
         */

        go: function(n, direction){
            var nextSlide = (this.slide + this.data.images.length) % this.data.images.length;
            if (n == nextSlide || Date.now() < this.timeToTransitionComplete)
                return;		
            clearTimeout(this.timer);
            this.timeToNextTransition = 0;		
            this.direction = direction ? direction 
            : n < this._slide ? 'right' 
            : 'left';
            this.slide = this._slide = n;
            if (this.preloader) 
                this.preloader = this.preloader.destroy();
            this._preload((this.options.fast & WhenPlaying) || (this.paused && this.options.fast & WhenPaused));
        },

        /**
	Public method: first
		Goes to the first image in the show.

	Syntax:
		myShow.first();	
         */

        first: function(){
            this.prev(true); 
        },

        /**
	Public method: prev
		Goes to the previous image in the show.

	Syntax:
		myShow.prev();	
         */

        prev: function(first){
            var n = 0;
            if (!first){
                if (this.options.random){
                    if (this.showed.i < 2)
                        return;
                    this.showed.i -= 2;
                    n = this.showed.array[this.showed.i];
                }
                else
                    n = (this.slide - 1 + this.data.images.length) % this.data.images.length;									
            }
            this.go(n, 'right');
        },

        /**
	Public method: pause
		Toggles play / pause state of the show.

	Arguments:
		p - (undefined, 1 or 0) Call pause with no arguments to toggle the pause state. Call pause(1) to force pause, or pause(0) to force play.

	Syntax:
		myShow.pause(p);	
         */

        pause: function(p){
            if (p != undefined)
                this.paused = p ? false 
                : true;
            if (this.paused){ // play
                this.paused = false;
                this.timeToTransitionComplete = Date.now() + this.timeToTransitionComplete;		
                this.timer = this._preload.delay(50, this);
                [this.a, this.b].each(function(img){
                    ['morph', 'tween'].each(function(p){
                        if (this.retrieve(p)) this.get(p).resume();
                    }, img);
                });
                this.controller && this.el.retrieve('pause').getParent().removeClass(this.classes.play);
            } 
            else { // pause
                this.paused = true;
                this.timeToTransitionComplete = this.timeToTransitionComplete - Date.now();
                clearTimeout(this.timer);
                [this.a, this.b].each(function(img){
                    ['morph', 'tween'].each(function(p){
                        if (this.retrieve(p)) this.get(p).pause();
                    }, img);
                });
                this.controller && this.el.retrieve('pause').getParent().addClass(this.classes.play);
            }
        },

        /**
	Public method: next
		Goes to the next image in the show.

	Syntax:
		myShow.next();	
         */

        next: function(last){
            var n = last ? this.data.images.length - 1 
            : this._slide;
            this.go(n, 'left');
        },

        /**
	Public method: last
		Goes to the last image in the show.

	Syntax:
		myShow.last();	
         */

        last: function(){
            this.next(true); 
        },

        /**
	Public method: load
		Loads a new data set into the show: will stop the current show, rewind and rebuild thumbnails if applicable.

	Arguments:
		data - (array or object) The images and optional thumbnails, captions and links for the show.

	Syntax:
		myShow.load(data);
         */

        load: function(data) {
            this.firstrun = true;
            this.showed = {
                'array': [], 
                'i': 0
            };
            if (typeOf(data) == 'array'){
                this.options.captions = false;			
                data = new Array(data.length).associate(data.map(function(image, i){
                    return image + '?' + i
                })); 
            }
            this.data = {
                'images': [], 
                'captions': [], 
                'hrefs': [], 
                'thumbnails': [], 
                'targets': [], 
                'titles': []
            };
            for (var image in data){
                var obj = data[image] || {};
                var image = this.options.hu + image;
                var caption = obj.caption ? obj.caption.trim()  : '';
                var href = obj.href ? obj.href.trim() : this.options.linked ? image : this.options.href;
                var target = obj.target ? obj.target.trim() : '_self';
                
                var thumbnail = obj.thumbnail ? this.options.hu + obj.thumbnail.trim() : this.options.thumbURL.substitute({
                    'key': image
                });
                
                var title = caption.replace(/<.+?>/gm, '').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, "'");
                
                this.data.images.push(image);
                this.data.captions.push(caption);
                this.data.hrefs.push(href);
                this.data.targets.push(target);
                this.data.thumbnails.push(thumbnail);
                this.data.titles.push(title);
            }
            if (this.options.random)
                this.slide = this._slide = Number.random(0, this.data.images.length - 1);

            // only run when data is loaded dynamically into an existing slideshow instance

            if (this.options.thumbnails && this.el.retrieve('thumbnails'))
                this._thumbnails();
            if (this.el.retrieve('images')){
                [this.a, this.b].each(function(img){
                    ['morph', 'tween'].each(function(p){
                        if (this.retrieve(p)) this.get(p).cancel();
                    }, img);
                });
                this.slide = this._slide = this.timeToTransitionComplete = 0;
                this.go(0);		
            }
            return this.data.images.length;
        },

        /**
	Public method: destroy
		Destroys a Slideshow instance.

	Arguments:
		p - (string) The images and optional thumbnails, captions and links for the show.

	Syntax:
		myShow.destroy(p);
         */

        destroy: function(p){
            Object.each(this.events, function(array, e){
                if ('each' in array)
                    array.each(function(fn){
                        document.removeEvent(e, fn);
                    });
            });
            this.pause(1);
            'caption loader thumbnails'.split(' ').each(function(i, timer){
                this.options[i] && (timer = this[i].retrieve('timer')) && clearTimeout(timer);
            }, this);
            typeOf(this.el[p]) == 'function' && this.el[p]();
            delete this.el.uid;
        },

        /**
	Private method: preload
		Preloads the next slide in the show, once loaded triggers the show, updates captions, thumbnails, etc.
         */

        _preload: function(fast){
            var src = this.data.images[this._slide].replace(/([^?]+).*/, '$1');
           
            if (Date.now() > this.timeToNextTransition && Date.now() > this.timeToTransitionComplete) {
                var src = this.data.images[this._slide].replace(/([^?]+).*/, '$1');
                if (this.stopped){
                    //  this.pause(1);
                    if (this.end) this.fireEvent('end');
                    this.stopped = this.end = false;
                    return;				
                }
                this.image = this.a;  
             
                
                this.image.src = src;	
                this.image.caption = this.data.titles[this._slide];
                
                this.options.loader && this.loader.fireEvent('hide');				
                this.options.thumbnails && this.thumbnails.fireEvent('update', fast); 			
                this._show(fast);
                this._loaded(fast);
            } 
            else {
                if (Date.now() > this.timeToNextTransition && this.options.loader)
                    this.loader.fireEvent('show');
            }
        },

        /**
	Private method: show
		Does the slideshow effect.
         */

        _show: function(fast){           
            var hidden = this.classes.get('images', (this.direction == 'left' ? 'next' : 'prev'));
            this.playerAPI.loadVideoById(this.a.src);
        },

        /**
	Private method: loaded
		Run after the current image has been loaded, sets up the next image to be shown.
         */

        _loaded: function(fast){
            this.counter++;
            this.timeToNextTransition = Date.now() + this.options.duration + this.options.delay;
            this.direction = 'left';			
            this.timeToTransitionComplete = fast ? 0 : Date.now() + this.options.duration;
            if (this._slide == (this.data.images.length - 1) && !this.options.loop && !this.options.random)
                this.stopped = this.end = true;
            if (this.options.random){
                this.showed.i++;
                if (this.showed.i >= this.showed.array.length){
                    var n = this._slide;
                    if (this.showed.array.getLast() != n) this.showed.array.push(n);
                    while (this._slide == n)
                        this.slide = this._slide = Number.random(0, this.data.images.length - 1);				
                }
                else
                    this.slide = this._slide = this.showed.array[this.showed.i];
            }
            else {
                this.slide = this._slide;
                this._slide = (this.slide + 1) % this.data.images.length;
            }		
            if (this.preloader) 
                this.preloader = this.preloader.destroy();
            this.paused || this._preload();
        },

        /**
	Private method: center
		Center an image.
         */

        _center: function(img){
            var size = img.getSize(), 
            h = size.y, w = size.x; 
            img.set('styles', {
                'left': (w - this.width) / -2, 
                'top': (h - this.height) / -2
            });
        },

        /**
	Private method: resize
		Resizes an image.
         */

        _resize: function(img){
            var h = img.get('height').toFloat(), w = img.get('width').toFloat(),
            dh = this.height / h, dw = this.width / w;
            if (this.options.resize == 'fit')
                dh = dw = dh > dw ? dw 
                : dh;
            if (this.options.resize == 'fill')
                dh = dw = dh > dw ? dh 
                : dw;
            img.set('styles', {
                'height': Math.ceil(h * dh), 
                'width': Math.ceil(w * dw)
            });
        },

        /**
	Private method: start
		Callback on start of slide change.
         */

        _start: function(){		
            this.fireEvent('start');
        },

        /**
	Private method: complete
		Callback on start of slide change.
         */

        _complete: function(){
            if (this.firstrun && this.options.paused)
                this.pause(1);
            this.firstrun = false;
            this.fireEvent('complete');
        }	
    });


    /**
	Private method: loader
		Builds the optional loader element, adds interactivity.
		This method can safely be removed if the loader option is not enabled.
     */

    var Loader = new Class({
        Implements: [Chain, Events, Options],

        options: {/*
			duration: 500,
			transition: 'sine:in:out',
			unit: false, */
            fps: 20,
            link: 'cancel'			
        },

        initialize: function(slideshow){
            if (!slideshow)
                return;
            var options = slideshow.options.loader;
            if (options === true)
                options = {};
            this.setOptions(options);
            var loader = new Element('div', {
                'aria-hidden': false,
                'class': slideshow.classes.get('loader').substr(1),				
                'morph': this.options,
                'role': 'progressbar'
            }).store('animate', false).store('i', 0).store('delay', 1000 / this.options.fps).inject(slideshow.el);
            slideshow.loader = loader;
            var url = loader.getStyle('backgroundImage').replace(/url\(['"]?(.*?)['"]?\)/, '$1').trim();
            if (url){
                if (url.test(/\.png$/) && Browser.ie && Browser.version < 7)
                    loader.setStyles({
                        'backgroundImage': 'none', 
                        'filter': 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + url + '", sizingMethod="crop")'
                    });					
                new Asset.image(url, {
                    'onload': function(){
                        var size = loader.getSize(),
                        width = this.get('width'), 
                        height = this.get('height');
                        if (width > size.x)
                            loader.store('x', size.x).store('animate', 'x').store('frames', (width / size.x).toInt());
                        if (height > size.y)
                            loader.store('y', size.y).store('animate', 'y').store('frames', (height / size.y).toInt());
                    }
                });
            }
            loader.set('events', {
                'animate': this.animate.bind(loader),
                'hide': this.hide.pass(slideshow.classes.get('loader', 'hidden'), loader),
                'show': this.show.pass(slideshow.classes.get('loader', 'visible'), loader)
            });
            loader.fireEvent('hide');
        },

        animate: function(){
            var animate = this.retrieve('animate');
            if (!animate)
                return;
            var i = (this.retrieve('i').toInt() + 1) % this.retrieve('frames');
            this.store('i', i);
            var n = (i * this.retrieve(animate)) + 'px';
            if (animate == 'x')
                this.setStyle('backgroundPosition', n + ' 0px');			
            if (animate == 'y')
                this.setStyle('backgroundPosition', '0px ' + n);			
        },

        hide: function(hidden){
            if (this.get('aria-hidden') == 'false'){
                this.set('aria-hidden', true).morph(hidden);
                if (this.retrieve('animate'))
                    clearTimeout(this.retrieve('timer'));
            }
        },

        show: function(visible){
            if (this.get('aria-hidden') == 'true'){
                this.set('aria-hidden', false).morph(visible);
                if (this.retrieve('animate')){
                    this.store('timer', function(){ 
                        this.fireEvent('animate') 
                    }.periodical(this.retrieve('delay'), this));			
                }
            }
        }
    });

    /**
	Private method: thumbnails
		Builds the optional thumbnails element, adds interactivity.
		This method can safely be removed if the thumbnails option is not enabled.
     */

    var Thumbnails = new Class({
        Implements: [Chain, Events, Options],

        options: {/*
			duration: 500,
			transition: 'sine:in:out',
			unit: false, */
            columns: null,
            fps: 50,
            link: 'cancel',
            position: null,
            rows: null,
            scroll: null
        },

        initialize: function(slideshow){
            var options = (slideshow.options.thumbnails === true) ? {} 
            : slideshow.options.thumbnails;
            this.setOptions(options);
            var el = slideshow.el.getElement(slideshow.classes.get('thumbnails')),
            thumbnails = el ? el.empty() 
            : new Element('div', {
                'class': slideshow.classes.get('thumbnails').substr(1)
            });

            slideshow.thumbnails = thumbnails;
            thumbnails.set({
                'role': 'menubar', 
                'styles': {
                    'overflow': 'hidden'
                }
            });
            var uid = thumbnails.retrieve('uid', 'Slideshow-' + Date.now()),
            ul = new Element('ul', {
                'role': 'menu', 
                'styles': {
                    'left': 0, 
                    'position': 'absolute', 
                    'top': 0
                }, 
                'tween': {
                    'link': 'cancel'
                }
            }).inject(thumbnails);
            var helpers = new jsCore.Helpers();
            slideshow.data.thumbnails.each(function(thumbnail, i){
                var li = new Element('li', {
                    'id': uid + i
                }).inject(ul),
                a = new Element('a', {
                    'class': slideshow.classes.get('thumbnails', 'hidden').substr(1),
                    'events': {
                        'click': this.click.pass(i, slideshow)
                    },
                    'href': slideshow.data.images[i],
                    'morph': this.options,
                    'role': 'menuitem',
                    'tabindex': i
                }).store('uid', i).inject(li);
                if (slideshow.options.titles)
                    a.set('title', slideshow.data.titles[i]);

                var ima = new Asset.image(thumbnail, {
                    'styles': {
                        'visibility': 'hidden'
                    },
                    'onload': this.onload.pass(i, slideshow)
                }).inject(a); 
            }, this);
            thumbnails.set('events', {
                'scroll': this.scroll.bind(thumbnails),
                'update': this.update.bind(slideshow)
            });
            thumbnails.inject(slideshow.el);
            
            var coords = thumbnails.getCoordinates();
            if (!options.scroll) options.scroll = (coords.height > coords.width) ? 'y' : 'x';

            var props = (options.scroll == 'y') ? 'top bottom height y width'.split(' ')  : 'left right width x height'.split(' ');
            
            thumbnails.store('props', props).store('delay', 1000 / this.options.fps);
            
            slideshow.events.push('mousemove', this.mousemove.bind(thumbnails));

            thumbnails.getElements('img').each(function (img) {
                img.setStyles(Object.merge({
                    'visibility': 'visible'
                }, helpers.imageResize(img, slideshow.options.thrumbProportion.width, slideshow.options.thrumbProportion.height, slideshow.options.thrumbProportion.exact)));
            }); 
        },

        click: function(i){
            this.go(i); 
            return false; 
        },

        mousemove: function(e){
            var coords = this.getCoordinates();
            if (e.page.x > coords.left && e.page.x < coords.right && e.page.y > coords.top && e.page.y < coords.bottom){
                this.store('page', e.page);			
                if (!this.retrieve('mouseover')){
                    this.store('mouseover', true);
                    this.store('timer', function(){
                        this.fireEvent('scroll');
                    }.periodical(this.retrieve('delay'), this));
                }
            }
            else {
                if (this.retrieve('mouseover')){
                    this.store('mouseover', false);				
                    clearTimeout(this.retrieve('timer'));
                }
            }			
        },

        onload: function(i){
            var thumbnails = this.thumbnails,
            a = thumbnails.getElements('a')[i];
            if (a){
                (function(a){
                    var visible = i == this.slide ? 'active' 
                    : 'inactive';					
                    a.store('loaded', true).get('morph').set(this.classes.get('thumbnails', 'hidden')).start(this.classes.get('thumbnails', visible));	
                }).delay(Math.max(1000 / this.data.thumbnails.length, 100), this, a);
            }					
            if (thumbnails.retrieve('limit'))
                return;
            var props = thumbnails.retrieve('props'), 
            options = this.options.thumbnails,
            pos = props[1], 
            length = props[2], 
            width = props[4],
            li = thumbnails.getElement('li:nth-child(' + (i + 1) + ')').getCoordinates();
            if (options.columns || options.rows){
                thumbnails.setStyles({
                    'height': this.height, 
                    'width': this.width
                });
                if (options.columns.toInt())
                    thumbnails.setStyle('width', li.width * options.columns.toInt());
                if (options.rows.toInt())
                    thumbnails.setStyle('height', li.height * options.rows.toInt());
            }
            var div = thumbnails.getCoordinates();
            if (options.position){
                if (options.position.test(/bottom|top/))
                    thumbnails.setStyles({
                        'bottom': 'auto', 
                        'top': 'auto'
                    }).setStyle(options.position, -div.height);
                if (options.position.test(/left|right/))
                    thumbnails.setStyles({
                        'left': 'auto', 
                        'right': 'auto'
                    }).setStyle(options.position, -div.width);
            }
            var units = Math.floor(div[width] / li[width]),
            x = Math.ceil(this.data.images.length / (units <= 0 ? 1 : units)),
            r = this.data.images.length % (units <= 0 ? 1 : units),
            len = x * li[length],
            ul = thumbnails.getElement('ul').setStyle(length, len);
            ul.getElements('li').setStyles({
                'height': li.height, 
                'width': li.width
            });
            thumbnails.store('limit', div[length] - len);
        },

        scroll: function(n, fast){
            var div = this.getCoordinates(),
            ul = this.getElement('ul').getPosition(),
            props = this.retrieve('props'),
            axis = props[3], delta, pos = props[0], size = props[2], value,			
            tween = this.getElement('ul').set('tween', {
                'property': pos
            }).get('tween');	
            if (n != undefined){
                var uid = this.retrieve('uid'),
                li = document.id(uid + n).getCoordinates();
                delta = div[pos] + (div[size] / 2) - (li[size] / 2) - li[pos];
                value = (ul[axis] - div[pos] + delta).limit(this.retrieve('limit'), 0);
                tween[fast ? 'set' : 'start'](value);
             
            }
            else{
                var area = div[props[2]] / 3, 
                page = this.retrieve('page'), 
                velocity = -(this.retrieve('delay') * 0.01);			
                if (page[axis] < (div[pos] + area))
                    delta = (page[axis] - div[pos] - area) * velocity;
                else if (page[axis] > (div[pos] + div[size] - area))
                    delta = (page[axis] - div[pos] - div[size] + area) * velocity;			
                if (delta){			
                    value = (ul[axis] - div[pos] + delta).limit(this.retrieve('limit'), 0);
                    tween.set(value);
                }
            }				
        },

        update: function(fast){
        
            var thumbnails = this.thumbnails,
            uid = thumbnails.retrieve('uid');
            thumbnails.getElements('a').each(function(a, i){
                if (a.retrieve('loaded')){
                    if (a.retrieve('uid') == this._slide){
                        if (!a.retrieve('active', false)){
                            a.store('active', true);
                            var active = this.classes.get('thumbnails', 'active');							
                            if (fast) a.get('morph').set(active);
                            else a.morph(active);
                        }
                    } 
                    else {
                        if (a.retrieve('active', true)){
                            a.store('active', false);
                            var inactive = this.classes.get('thumbnails', 'inactive');						
                            if (fast) a.get('morph').set(inactive);
                            else a.morph(inactive);
                        }
                    }
                }
            }, this);
            if (!thumbnails.retrieve('mouseover'))
                thumbnails.fireEvent('scroll', [this._slide, fast]);
        }
    });
})();
