/**
  * event.layerX and event.layerY are broken and deprecated in WebKit
  * this is a patch to fix that
  */
(function(){
    // remove layerX and layerY
    var all = $.event.props,
        len = all.length,
        res = [];
    while (len--) {
      var el = all[len];
      if (el != 'layerX' && el != 'layerY') res.push(el);
    }
    $.event.props = res;
}());

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, clickableWindow) {
        
        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._slides = this._container.find("ul.slideshow");
        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._slides.find("li").clone();
        this._length = this._slideCopy.length;
        
        var visibleSlide = $(this._slides.find("li").get(1));
        
        this._window.scrollLeft(
            $(this._slides.find("li").get(1)).position().left
        );
        this._slides.prepend(this._slides.find("li:last").remove());

        var obj = this;
        obj._indicator.find("li").click(function(e) {
            obj.moveHeader($(this).index());
        });
        
        if (clickableWindow) {
            obj._window.bind('click', function() {
                obj.goNext();
            });
        }

        obj._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) {
        var obj = this;
            
        obj._prevIndex = obj._currIndex;
        obj._currIndex = index;
        
        obj._reshuffle(index);

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

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

        var currLI = this._slides.find("li").get(1);
            prevLI = this._slides.find("li[data-order='"+ obj._prevIndex +"']")[0];

        var position = $(currLI).position().left;
        
        obj._window.scrollLeft($(prevLI).position().left);
        obj._currentPosition = position;

        obj.updateBanner(index, direction);
        obj._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);                    
                link.click(function() { window.location = 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],
            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(index) {
        var obj = this;
        
        if (index !== 0) {
            var prevs = $(obj._slides.find("li[data-order='" + (index - 1) + "']")).prevAll();
        
            for (var i = prevs.length; i >= 0; i--) {
                obj._slides.append($(prevs[i]).remove());
            }
            
        } else {
            var sorted = obj._slides.find("li").sort(function(a, b) {
                return $(a).attr('data-order') - $(b).attr('data-order'); 
            });

            obj._slides.html(sorted);
            obj._slides.prepend(obj._slides.find("li:last").remove());
        }
    },
    
    _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);
        
        this._container.after(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());
    },
    
    _enablePrev: function() {
        this._prevBtn = $(this._arrowContainer).find("li.previous a").click(this.getPrev());
    },
    
    _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' });
    }
});

