var Slideshow = function() {
    this.els = {};
    for(var key in Slideshow.selectors) {
        this.els[key] = $(Slideshow.selectors[key]);
    }
    
    this.els.container.addClass('interactive');
 
    var slides = [];
    this.els.slides.each(function() {
        slides.push(new Slide(this));
    });
    this.slides = slides;
    this.els.slides.hide();
    
    this.initialize();
};
$.extend(Slideshow.prototype, {
    initialize: function() {
        this.els.totalKey.text(this.slides.length);
        
        this.current = 0;
        this.next = 0;
        this.slides[0].preload(function() { this.changeSlides(); }.use(this));
        
        this.els.nextBtn.unbind('click').bind('click', this.advance.useEL(this));
        this.els.prevBtn.unbind('click').bind('click', this.retreat.useEL(this));

        $(document).bind('keyup', this.keyListener.useEL(this));
        
        //this.els.container.bind('mouseover', this.pauseTimer.useEL(this));
        //this.els.container.bind('mouseout', this.startTimer.useEL(this));
        
        this.startTimer();
    },
    startTimer: function() {
        clearTimeout(this.timerTimer)
        clearTimeout(this.timer);
        this.timer = setTimeout(function() {
            this.next = this.current+1;
            if(this.next >= this.slides.length) {
                this.next = 0;
            }
            
            this.changeSlides(Slideshow.timing.autoSpeed);
            this.startTimer();
        }.use(this), Slideshow.timing.interval)
    },
    pauseTimer: function() {
        this.timerTimer = setTimeout(function() {
            clearTimeout(this.timer);
        }.use(this), 300);
    },
    advance: function(event) {
        if(event) { 
            event.stop(); 
            this.pauseTimer();
        }
        
        this.next = this.current+1;
        if(this.next >= this.slides.length) {
            this.next = 0;
        }
        
        this.changeSlides(Slideshow.timing.manualSpeed);
    },
    retreat: function(event) {
        if(event) { 
            event.stop(); 
            this.pauseTimer();
        }
        
        this.next = this.current-1;
        if(this.next <= 0) {
            this.next = this.slides.length-1;
        }
        
        this.changeSlides(Slideshow.timing.manualSpeed);
    },
    keyListener: function(event) {
        if(!event.keyCode) { return; }
        
        switch(event.keyCode) {
            case 39: // Right
            case 63235: // Safari 2 Right
                this.advance(null);
                break;
            case 37: // Left
            case 63234: // Safari 2 Left
                this.retreat(null)
                break;
        }
    },
    changeSlides: function(speed) {
        var speed = (speed) ? speed : Slideshow.timing.autoSpeed;
        if(this.slides[this.current]) { this.slides[this.current].hide(speed); }
        if(this.slides[this.next]) { this.slides[this.next].show(speed); }
           
        this.current = this.next;
        this.next = null;
        
        this.els.currentKey.text(this.current+1);
    
        if(this.slides[this.current+1]) {
            this.slides[this.current+1].preload();
        } else {
            this.slides[0].preload();
        }
        
        if(this.slides[this.current-1]) {
            this.slides[this.current-1].preload();
        } else {
            this.slides[this.slides.length-1].preload();
        }
    }
});
$.extend(Slideshow, {
    selectors: {
        container: '#workshow',
        slides: '#slideshow li',
        nextBtn: '.workNav.next a',
        prevBtn: '.workNav.prev a',
        currentKey: '.title .current',
        totalKey: '.title .total'
    },
    timing: {
        interval: 5000,
        autoSpeed: 1500,
        manualSpeed: 500
    },
    init: function() {
        Slideshow.instance = new Slideshow();
    }
});

var Slide = function(el) {
    this.els = {};
    for(var key in Slide.selectors) {
        this.els[key] = $(Slide.selectors[key]);
    }

    this.els.el = $(el).hide();
    this.els.link = this.els.el.find('a:first').hide();
    this.description = this.els.el.find('p').hide().html();
    this.source = (this.els.link.attr('rel').match(/[jpg|png|gif]$/)) ? this.els.link.attr('rel') : this.els.link.attr('href');
    this.preloader = new Preloader();
};
$.extend(Slide.prototype, {
    preload: function(callback) {
        if(this.image) { 
            if(callback) { callback(); }
            return; 
        }
        
        $(this.preloader).bind('loaded', this.appendImage.useEL(this));
        
        if(callback) {
            $(this.preloader).bind('loaded', callback);
        }
        
        this.preloader.load(this.source);
    },
    appendImage: function() {
        this.els.el.append('<img src="'+this.source+'" alt="" />');
        this.image = $(this.els.el.find('img'));
    },
    show: function(speed) {
        var speed = (speed) ? speed : 500;
        this.els.el.fadeIn(speed);
        this.els.title.html('<strong>' + this.els.link.text() + '</strong> &mdash; ' + this.description);
        //this.els.overlay.attr('href', this.els.link.attr('href'));
    },
    hide: function(speed) {
        var speed = (speed) ? speed : 500;
        this.els.el.fadeOut(speed);
    }
});
$.extend(Slide, {
    selectors: {
        title: '.title .slideTitle',
        overlay: 'a.slideshowOverlay'
    }
});


/**
 * Image Preloader
 * Accepts a single or array of image source strings, preloads them and fires events.
 */
var Preloader = function(overlay) {
    this.cache = [];
    this.loading = false;
    
    if(overlay) {
        this.els = {
            overlay: $(Preloader.selectors.overlay),
            container: $(Preloader.selectors.loadingBox)
        };
        
        $(document).bind('stage:ready', this.hide.useEL(this));
        
        this.show();
    }
};
$.extend(Preloader.prototype, {
   _load: function(source) {
       var image = new Image();
       
       image.onload = function() {
           this.cache.push(image.src);
           $(this).trigger('loaded');
       }.use(this);
       
       image.onerror = function() {
           $(document).trigger('error', {image: source});
       }.use(this);
       
       this.loading = true;
       
       $(this).trigger('loading', {image: source});
       
       image.src = source;
   },
   load: function(sources) {
       var sources = $.makeArray(sources);
              
       var preCacheLength = this.cache.length;
       var l = sources.length;
              
       $(this).bind('loaded', function(event) {
           if(sources.length+preCacheLength == this.cache.length) {
               $(this).trigger('complete');
           }
       }.useEL(this));
       
       $(this).bind('error', function(event) {
           $(document).trigger('error', {message: Preloader.strings.error})
       }.useEL(this));
       
       while(l--) {
           this._load(sources[l]);
       }
   },
   setPosition: function() {
       var leftCenter = Math.round(($(window).width()/2)-(this.els.container.width()/2));
       var topCenter = Math.round(($(window).height()/2)-(this.els.container.height()/2));
       
       this.els.container.css({ 'top': topCenter+'px', 'left': leftCenter+'px' });
   },
   show: function() {
       this.els.overlay.show();
       this.setPosition();
       this.els.container.show();
   },
   hide: function() {
       setTimeout(function() {
           this.els.overlay.fadeOut(2000)
           if($.support.opacity) {
               this.els.container.fadeOut(2000)
           } else {
               this.els.container.hide()
           }
       }.use(this), Preloader.minTimeout);
   }
});
$.extend(Preloader, {
    strings: {
        error: 'Error loading images. Please reload this page to try again.'
    },
    selectors: {
        overlay: '#overlay',
        loadingBox: '#loadingBox' 
    },
    minTimeout: 1000,
    init: function() {
        Preloader.instance = new Preloader(true);
    }
});


$(document).ready(function() {
    if($(Slideshow.selectors.container).length) {
        Slideshow.init();
    }
});