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.slidenav.hide();
        
        this.els.nextBtn.bind('click', this.advanceStory.useEL(this));
        this.els.closeBtn.bind('click', this.hideStories.useEL(this));
        //this.els.prevBtn.bind('click', this.retreat.useEL(this));

        $(document).bind('keyup', this.keyListener.useEL(this));
        
        // if we want to pause on mouseover or not
        //this.els.container.bind('mouseover', this.pauseTimer.useEL(this));
        //this.els.container.bind('mouseout', this.startTimer.useEL(this));
        
        $(this.slides).bind('story:show', this.pauseTimer.useEL(this));
        $(this.slides).bind('story:show', this.hideIntros.useEL(this));
        
        this.startTimer();
    },
    hideIntros: function() {
        this.els.slidenav.fadeIn(500);
        $(this.slides).each(function() {
            this.hideIntro();
        });
    },
    hideStories: function(event) {
        if(event) { event.stop(); }
        this.els.slidenav.fadeOut(500);
        $(this.slides).each(function() {
            this.showIntro();
        });
        this.startTimer();
    },
    startTimer: function() {
        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() {
        clearTimeout(this.timer);
    },
    advance: function(event) {
        if(event) { event.stop(); }
        
        this.next = this.current+1;
        if(this.next >= this.slides.length) {
            this.next = 0;
        }
        
        this.changeSlides(Slideshow.timing.manualSpeed);
    },
    advanceStory: function(event) {
        if(event) { event.stop(); }
        
        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.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: '#slideshow',
        slides: '#slideshow li',
        slidenav: '#slidenav',
        nextBtn: '#slidenav a.next',
        //prevBtn: '#slidenav .prev a',
        closeBtn: '#slidenav a.close',
        currentKey: '#slidenav .slideCurrent',
        totalKey: '#slidenav .slideTotal'
    },
    timing: {
        interval: 6500,
        autoSpeed: 1500,
        manualSpeed: 500
    },
    init: function() {
        Slideshow.instance = new Slideshow();
    }
});

var Slide = function(el) {
    this.els = {};
    this.els.el = $(el).hide();
    for(var key in Slide.selectors) {
        this.els[key] = $(this.els.el.find(Slide.selectors[key]));
    }
    this.els.image = false;
    
    this.doShowIntro = true;
    this.slideNumber = this.els.more.attr('href').split('#more')[1];
    
    this.els.morecontent.hide();
    
    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();
    
    this.els.more.bind('click', this.showStory.useEL(this));
};
$.extend(Slide.prototype, {
    preload: function(callback) {
        if(this.els.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 class="' + Slide.selectors.image.replace('.', '') + '" src="'+this.source+'" alt="" />');
        this.els.image = $(this.els.el.find(Slide.selectors.image));
    },
    show: function(speed) {
        if(!this.doShowIntro && this.els.image) {
            this.els.image.hide();
        } else if(this.els.image) {
            this.els.image.show();
        }
        
        if(!this.doShowIntro) {
            this.els.morecontent.show();
        } else {
            this.els.morecontent.hide();
        }
          
        var speed = (speed) ? speed : 500;
        this.els.el.fadeIn(speed);
    },
    hide: function(speed) {
        var speed = (speed) ? speed : 500;
        
        if(!this.doShowIntro) {
            this.els.morecontent.fadeOut(speed);
        }
        
        this.els.el.fadeOut(speed);
    },
    showStory: function(event) {
        event.stop();
        
        this.els.morecontent.fadeIn(500);
        this.els.more.fadeOut(500);
        $(this).trigger({ type: 'story:show', slide: this.slideNumber });
    },
    showIntro: function() {
        if(this.els.image) {
            this.els.image.fadeIn(500);
        }
        this.els.more.fadeIn(500);
        this.els.morecontent.fadeOut(500);
        this.doShowIntro = true;
    },
    hideIntro: function() {
        this.els.more.hide();
        if(this.els.image) {
            this.els.image.fadeOut(500);
        }
        this.doShowIntro = false;
    }
});
$.extend(Slide, {
    selectors: {
        image: '.slide',
        intro: '.intro',
        link: '.intro a',
        morecontent: '.story',
        more: 'a.readmore'
    }
});

/**
 * 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;
};
$.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]);
       }
   }
});
$.extend(Preloader, {
    strings: {
        error: 'Error loading images. Please reload this page to try again.'
    },
    minTimeout: 1000,
    init: function() {
        Preloader.instance = new Preloader(true);
    }
});


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