var Caption = Class.extend({
    init: function(title, caption, url) {
        this.title = title;
        this.caption = caption;
        this.url = url;
    }
});

var Slideshow = Class.extend({
    init: function(selector) {
        
        this.iPhone = false

        if (navigator.userAgent.match(/iPhone/i)) {
            this.iPhone = true;
        }
        
        
        if(this.iPhone) return;
        
        this.VIEWABLE_WIDTH = 930;
        this._currentPosition = 0;
        this._currIndex = 0;
        this._prevIndex = 0;
        
        this._container = $(selector);
        this._window = this._container.find("div.slide-window");
        this._window.css({overflow: 'hidden'});
        this._window.scrollLeft(0);

        this._banner = this._container.find(".slide-banner-wrapper");
        this._indicator = this._container.find("ul.slide-indicator");
        
        var activeLI = this._indicator.find("li").get(0);
        $(activeLI).addClass("active");

        this._createNextBack();
        
        this._slideCopy = this._container.find("ul.slideshow li").clone();
        this._length = this._slideCopy.length;
        
        this._reshuffle(0);
        var initLI = $("ul.slideshow li").get(1);
        this._window.scrollLeft($(initLI).position().left);

        var me = this;
        me._indicator.find("li").click(function(e) {
            me.moveHeader($(this).index());
        });
        
        this._enableKeys();
    },

    setCaptions: function(captions) {
        var slideshow = this;

        this.captions = [];

        $.each(captions, function(index, item) {
            slideshow.captions.push(new Caption(item[0], item[1], item[2]));   
        });
        
        this._banner.append(this.setText(this.captions[0], 1));
        this._cufonize();
        this._showBanner();
    },
    
    getNext: function() {
        var obj = this;
        function inner() {
            if (obj._currIndex != (obj._length - 1)) {
                obj.moveHeader(obj._currIndex + 1, 'next');
            } else {
                obj.moveHeader(0, 'next');
            }
        };

        return inner;
    },
    
    getPrev: function() {
        var obj = this;
        
        function inner() {
            if (obj._currIndex != 0) {
                obj.moveHeader(obj._currIndex - 1, 'prev');
            } else {
                obj.moveHeader(obj._length-1, 'prev');
            }
        }

        return inner;
    },

    goPrev: function() {
        this.getPrev()();
    },

    goNext: function() {
        this.getNext()();
    },

    moveHeader: function(index, direction) {
        this._prevIndex = this._currIndex;
        this._currIndex = index;

        this._reshuffle(index);

        /********Indicator switching**********/
        var prevLI = this._indicator.find("li").get(this._prevIndex);
        var activeLI = this._indicator.find("li").get(this._currIndex);

        $(prevLI).removeClass("active");
        $(activeLI).addClass("active");
        /********end indicator**********/

        var currLI = $("ul.slideshow li").get(1);
        var prevLI = $("ul.slideshow li[data-order='"+ this._prevIndex +"']");
        this._window.scrollLeft($(prevLI).position().left);
        
        var position = $(currLI).position().left;
        
        /************************************************************************/
        this._currentPosition = position;
        var instance = this;

        this.updateBanner(index, direction);
        this._window.stop().animate({scrollLeft: position}, 1300, 'easeInOutExpo');
    },

    setText: function(obj, num) {
        if (obj.title == "" && obj.caption == "") return null;
        
        // unbind goNext from current, prepare it to be an external link or not
        $('.slideshow-container li[data-order=' + this._currIndex + ']').unbind();
        $('.slideshow-container').unbind('mouseenter mouseleave');

        // reset
        $('.slideshow-container > a').remove();
        
        num = (num < 10 ? '0' : '') + num + '.';
        
        var banner;
            banner = $('<h2></h2>').addClass('slide-banner').css('cursor', 'default');
            banner.append( $('<span></span>').addClass('num knockout_27').text(num) );
            banner.append( $('<span></span>').addClass('title').text(obj.title) );
            banner.append( $('<em></em>').addClass('caption knockout_27').text(obj.caption.toUpperCase()) );
        
        if (obj.url != "") {
            var link = $('<a></a>').attr('href', obj.url).attr('target', '_blank');                    
                link.click(function() { window.open(this.href); });
        
            $('.slideshow-container').prepend(link);
                                   
            $('.slide-window img').css('cursor', 'pointer');
            
            banner.css('cursor', 'pointer');
            
            
            banner.bind('click', function() {
                $('.slideshow-container > a').trigger("click");
            });
            
            var me = this;
            $(banner).hover(function() {
                $('.slide-banner em').addClass('highlight-banner');
                me._cufonize();
            }, function() {
                $('.slide-banner em').removeClass('highlight-banner');
                me._cufonize();
            });
            
        } 
        
        var nextIndex = (this._currIndex != (this._length - 1)) ? (this._currIndex + 1) : 0;
        var next = $('.slideshow-container li[data-order=' + nextIndex + ']');
            next.children('a').click(function(e) { e.preventDefault(); });
            next.bind('click', this.getNext());
        
        return banner;
    },

    updateBanner: function(index, direction) {
        if (!this.captions) return;

        var obj = this,
        caption = obj.captions[index],
        // stop any current animations and let them delete old oldCaptions before getting the new oldCaption!
        oldCaption = this._banner.stop(true, true).find('.slide-banner'),
        container, scrollTo;

        container = obj.setText(caption, index + 1);

        if (direction == 'next') {
            oldCaption.after(container);
            scrollTo = 89;
        } else {
            oldCaption.before(container);
            obj._banner.get(0).scrollTop = 89;
            scrollTo = 0;
        }
        
        obj._cufonize();
        obj._banner.animate({ scrollTop: scrollTo }, 1000, 'easeInOutExpo', function () {
            obj._banner.get(0).scrollTop = 0;
            oldCaption.remove();
        });
    },

    /*********Private Methods********/
    _reshuffle: function(curr) {
        //always put the curr in second position
        //defer to putting things at the end
        var orderArray = [];
        var start = (curr > 0) ? curr-1 : this._length - 1;
        
        for (var i=start; i < this._length; i++) {
            orderArray.push(i);
        }
        
        for (var j=0; j < start; j++) {
            orderArray.push(j);
        }
        
        //order has been set. Reorder physical
        var list = this._container.find("ul.slideshow li");
        
        for (var k=0; k< this._length; k++) {
            var oldElement = $(list[k]);
            var newElement = $(this._slideCopy[orderArray[k]]).clone(); 
            oldElement.replaceWith(newElement);
        }
    },
    
    _createNextBack: function() {
        this._arrowContainer = $("<ul></ul>").addClass("arrows");
        
        var li_prev = $("<li></li>").addClass("previous");
            li_prev.append($("<a></a>").text("Previous"));
            
        this._arrowContainer.append(li_prev);
        
        var li_next = $("<li></li>").addClass("next");
            li_next.append($("<a></a>").text("Next"));
            
        this._arrowContainer.append(li_next);
        
        $("#container").append(this._arrowContainer);
        
        var arrowsY = this._container.position().top + ( this._container.height() / 2 ) - ($(this._arrowContainer).height() / 2);
        $(this._arrowContainer).css({top:arrowsY});
        
        this._enableNext();
        this._enablePrev();
    },

    _enableNext: function() {
        this._nextBtn = $(this._arrowContainer).find("li.next a").click(this.getNext());
        this._nextBtn.closest("li").hover(function() {
            $(this).stop().animate({right: -53}, 250);
        }, function() {
            $(this).stop().animate({right: -63}, 250);
        });
    },
    
    _enablePrev: function() {
        this._prevBtn = $(this._arrowContainer).find("li.previous a").click(this.getPrev());
        this._prevBtn.closest("li").hover(function() {
            $(this).stop().animate({left: -53}, 250);
        }, function() {
            $(this).stop().animate({left: -63}, 250);
        });
    },
    
    _enableKeys: function() {
        // bind the left and right arrow keys to advance the slideshow
        var obj = this;
        $(document).keydown(function(e) {
            if (e.keyCode == 37) { 
                obj.goPrev();
                return false;
            } else if (e.keyCode == 39) {
                obj.goNext();
                return false;
            }
        });
	},
	
	_disableKeys: function() {
		$(document).unbind();
	},
	
	_showBanner: function() {
		this._banner.stop().animate({opacity: 1}, 500, 'easeOutExpo');
	},
    
    _hideBanner: function() {
		this._banner.stop().animate({opacity: 0}, 100, 'easeOutExpo');
	},
	
	_cufonize: function() {
		Cufon.replace('.knockout_27', { fontFamily: 'Knockout 27 Junior Bantamwt' });
	}
});

