var Slider = function() {
    this.els = {};
    for(var a in Slider.elements) {
        this.els[a] = $(Slider.elements[a]);
    }
    
    this.slideshow = new Slideshow();

    this.currentSlide = 0;
    
    var l = this.els.items.length;
    while(l--) {
        this.els.chicletsContainer.prepend('<li><a href="#slide' + l + '">Slide' + l +'</a></li>');
    }
    this.els.chicletsContainer.hide();
    this.els.progress.hide();
    this.els.chiclets = this.els.chicletsContainer.find('a');
    this.els.chiclets.click(this.goToSlide.useEL(this));
    
    // this is a dummy item to allow the chiclets to have an extra background
    $(this.els.items.clone().get(this.els.items.length-1)).appendTo(this.els.itemContainer).css({ opacity: Slider.opacity.inactive }).find('.content').text('');
    
    this.els.container.addClass('js');
    this.els.itemContainer.width(this.els.items.outerWidth(true) * (this.els.items.length + 1));
    this.els.itemsBg.css({ opacity: Slider.opacity.inactive });

    this.els.totalKey.text(this.els.items.length);
    this.updateNavigation();
        
    this.els.nextBtn.unbind('click').bind('click', this.nextSlide.useEL(this));
    this.els.prevBtn.unbind('click').bind('click', this.prevSlide.useEL(this));
    $(document).bind('keyup', this.keyListener.useEL(this));
    
    this.els.closeBtn.unbind('click').bind('click', this.reset.useEL(this));
};
$.extend(Slider, {
    elements: {
        container: '#homeslider',
        slider: '#sliding',
        itemContainer: '#homeslider ul.slides',
        items: '#homeslider ul.slides li',
        itemsBg: '#homeslider ul.slides li .container',
        itemsContent: '#homeslider ul.slides li .content',
        progress: '#homeslider #slideProgress',
        totalKey: '#slideProgress .total',
        currentKey: '#slideProgress .current',
        nextBtn: '#homeslider #next',
        prevBtn: '#homeslider #prev',
        closeBtn: '#homeslider .close',
        chicletsContainer: '#slideChiclets'
    },
    currentBgColor: '8DB9E5',
    defaultBgColor: '766A63',
    scrollSpeed: 1000, // pixels per second
    init: function() {
        Slider.instance = new Slider();
    },
    opacity: {
        inactive: 0.8,
        active: 0.9
    }
});
$.extend(Slider.prototype, {
    nextSlide: function(event) {
        if(event) { event.stop(); }
        
        if(this.currentSlide < this.els.items.length - 1) {
            this.goToSlide(this.currentSlide + 1);
        }
    },
    prevSlide: function(event) {
        if(event) { event.stop(); }
        
        if(this.currentSlide != 0) {
            this.goToSlide(this.currentSlide - 1);
        }
    },
    keyListener: function(event) {
        if(!event.keyCode) { return; }
        
        switch(event.keyCode) {
            case 39: // Right
            case 63235: // Safari 2 Right
                this.nextSlide(null);
                break;
            case 37: // Left
            case 63234: // Safari 2 Left
                this.prevSlide(null)
                break;
        }
    },
    updateNavigation: function(show) {
        this.els.currentKey.text(this.currentSlide + 1);
                
        this.els.chiclets.removeClass('current');
        $(this.els.chiclets.get(this.currentSlide)).addClass('current');
        
        if(show) {
            this.els.chicletsContainer.fadeIn(500);
        } else {
            this.els.chicletsContainer.fadeOut(500);
        }
        
        if(this.currentSlide + 1 == this.els.items.length) {
            this.els.nextBtn.stop().animate({ opacity: 0 }, 500);
        } else {
            this.els.nextBtn.stop().animate({ opacity: 1 }, 500);
        }

        if(this.currentSlide == 0) {
            this.els.prevBtn.stop().animate({ opacity: 0 }, 500);
        } else {
            this.els.prevBtn.stop().animate({ opacity: 1 }, 500);
        }
    },
    goToSlide: function(event) {
        if(event.target) {
            event.stop();
            var slide = parseInt($(event.target).get(0).hash.replace('#slide', ''), 10);
        } else {
            var slide = event;
        }
        
        //if(this.slideshow.isAnimating) { this.slideshow.pauseTimer(); }

        var newLeft = (this.els.items.outerWidth(true) * slide) + (this.els.items.outerWidth(true) / 2);
        
        this.els.itemContainer.stop().animate({ left: -newLeft + 'px' }, Slider.scrollSpeed, 'easeOutBack');
        var i = 0;
        this.els.itemsBg.each(function() {
            if(i != slide) {
                $(this).stop().animate({ backgroundColor: '#' + Slider.defaultBgColor, opacity: Slider.opacity.inactive }, Slider.scrollSpeed, 'easeOutSine');
                $(this).next().stop().animate({ opacity: 0 }, Slider.scrollSpeed, 'easeOutSine');
            } else {
                $(this).stop().animate({ backgroundColor: '#' + Slider.currentBgColor, opacity: Slider.opacity.active }, Slider.scrollSpeed, 'easeOutSine');
                $(this).next().stop().animate({ opacity: 1 }, Slider.scrollSpeed, 'easeOutSine');
            }
            i++;
        });
                
        this.currentSlide = slide;
        this.updateNavigation(true);
        
        pageTracker._trackEvent('Homepage Slider', 'ChangeSlide', this.currentSlide+'');
    },
    reset: function(event) {
        if(event) {
            event.stop();
        }
        
        var newLeft = 0;
        var slide = 0;
        
        this.els.itemContainer.stop().animate({ left: -newLeft + 'px' }, Slider.scrollSpeed, 'easeOutBack');
        var i = 0;
        this.els.itemsBg.each(function() {
            if(i != slide) {
                $(this).stop().animate({ backgroundColor: '#' + Slider.defaultBgColor, opacity: Slider.opacity.inactive }, Slider.scrollSpeed, 'easeOutSine');
                $(this).next().stop().animate({ opacity: 0 }, Slider.scrollSpeed, 'easeOutSine');
            } else {
                $(this).stop().animate({ backgroundColor: '#' + Slider.defaultBgColor, opacity: Slider.opacity.active }, Slider.scrollSpeed, 'easeOutSine');
                $(this).next().stop().animate({ opacity: 1 }, Slider.scrollSpeed, 'easeOutSine');
            }
            i++;
        });
        
                
        this.currentSlide = slide;
        this.updateNavigation(false);
    }
});


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();
    this.isAnimating = true;
};
$.extend(Slideshow.prototype, {
    initialize: function() {
        this.current = 0;
        this.next = 0;
        this.slides[0].preload(function() { this.changeSlides(); }.use(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.fadeSpeed);
            this.startTimer();
        }.use(this), Slideshow.timing.interval)
    },
    pauseTimer: function() {
        this.timerTimer = setTimeout(function() {
            clearTimeout(this.timer);
        }.use(this), 300);
        this.isAnimating = false;
    },
    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.fadeSpeed);
    },
    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.fadeSpeed);
    },
    changeSlides: function(speed) {
        var speed = (speed) ? speed : Slideshow.timing.fadeSpeed;
        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;
            
        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: '#homeslider',
        slides: '#homeslider ul#sliderBackgrounds li'
    },
    timing: {
        interval: 8000,
        fadeSpeed: 2000,
        manualFadeSpeed: 1500
    }
});

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'));
    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.text(this.els.el.text());
        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'
    }
});


/**
 * Preloader
 * var myPreloader = new Preloader();
 * $(myPreloader).bind('loading', myLoadStartCallback);
 * $(myPreloader).bind('loaded', myImageLoadedCallback);
 * $(myPreloader).bind('complete', myLoadCompleteCallback);
 * $(myPreloader).bind('error', myLoadErrorCallback); // event.data.message returns error text string from Preloader.strings.error
 * myPreloader.load(['img1.png', 'img2.png', 'img3.png';]);
 */
var Preloader = function() {
    this.cache = [];
    this.loading = false;
};
$.extend(Preloader.prototype, {
   _load: function(source) {
       if($.inArray(source, this.cache) != -1) {
           $(this).trigger({type: 'loaded', image: source});
           return;
       }
       
       var image = new Image();
       
       image.onload = function() {
           this.cache.push(image.src);
           var now = new Date();
           var imgId = 'bg' + now.valueOf();
           $(this).trigger({type: 'loaded', image: source, id: imgId });
       }.use(this);
       
       image.onerror = function() {
           $(this).trigger({type: 'error', message: Preloader.strings.error})
       }.use(this);
       
       this.loading = true;
       
       $(this).trigger({type: '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({type: 'complete', cache: this.cache});
           }
       }.useEL(this));
       
       while(l--) {
           this._load(sources[l]);
       }
   }
});
$.extend(Preloader, {
    strings: {
        error: 'Error loading images. Please reload this page to try again.'
    }
});

$(document).ready(function() {
    Slider.init();
});

