var SimpleCarousel = new Class({
    Implements: [Options, Events],
    options: {
        slideInterval: 4000,
        transitionDuration: 700,
        startIndex: 0,
        rotateAction: "none",
        rotateActionDuration: 100,
        autoplay: true
    },
    initialize: function(container, slides, buttons, options){
        this.container = $(container);
        if(this.container.hasClass('hasCarousel')) return false;
        this.setOptions(options);
        this.container.addClass('hasCarousel');
        this.slides = $$(slides);
        this.buttons = $$(buttons);
        this.createFx();
        this.showSlide(this.options.startIndex);
        if(this.options.autoplay) this.autoplay();
        if(this.options.rotateAction != 'none') this.setupAction(this.options.rotateAction);
        return this;
    },
    toElement: function(){
        return this.container;
    },
    setupAction: function(action) {
        this.buttons.each(function(el, idx){
            $(el).addEvent(action, function() {
                this.slideFx.setOptions(this.slideFx.options, {duration: this.options.rotateActionDuration});
                if(this.currentSlide != idx) this.showSlide(idx);
                this.stop();
            }.bind(this));
        }, this);
    },
    createFx: function(){
        if (!this.slideFx) this.slideFx = new Fx.Elements(this.slides, {duration: this.options.transitionDuration});
        this.slides.each(function(slide){
            slide.setStyle('opacity',0);
        });
    },
    showSlide: function(slideIndex){
        var action = {};
        this.slides.each(function(slide, index){
            if(index == slideIndex && index != this.currentSlide){ //show
                action[index.toString()] = {
                    opacity: 1
                };
            } else {
                action[index.toString()] = {
                    opacity:0
                };
            }
        }, this);
        this.fireEvent('onShowSlide', slideIndex);
        this.currentSlide = slideIndex;
        this.slideFx.start(action);
        return this;
    },
    autoplay: function(){
        this.slideshowInt = this.rotate.periodical(this.options.slideInterval, this);
        this.fireEvent('onAutoPlay');
        return this;
    },
    stop: function(){
        $clear(this.slideshowInt);
        this.fireEvent('onStop');
        return this;
    },
    rotate: function(nextOrPrev){
        current = this.currentSlide;
        next = (current+1 >= this.slides.length) ? 0 : current+1;
        prev = (current-1 < 0) ? this.slides.length-1 : current-1;

        if(nextOrPrev == 'next' || nextOrPrev == undefined){
            this.showSlide(next);
            this.fireEvent('onRotate', next);
        }else{
            this.showSlide(prev);
            this.fireEvent('onRotate', prev);
        }
        return this;
    },
    showVideo: function(videoDiv){
        videoDiv.setStyle('display', 'block');
        this.slides.each(function(slide){
            slide.setStyles({
                'opacity': 1,
                'visibility': 'hidden'
            });
        });
    },

    hideVideo: function(videoDiv){
        videoDiv.setStyle('display', 'none');
        var current = this.currentSlide;
        this.slides.each(function(slide, index){
            if(index != current){
                slide.setStyle('opacity', 0);
            };
            slide.setStyle('visibility', 'visible');
        });
    }
});


var ThumbScroller = new Class({
	Extends: Fx.Scroll,

	scrollOptions: {
		thumbs: '.box',
		axis: 'x',
		thumbContainer: null,
		nav: {},
        startIndex: 0
    },

    initialize: function(element, scrollOptions) {
		this.parent(element, $merge(this.scrollOptions, scrollOptions));
        this.element.setStyle('overflow','hidden');
		this.computeDimensions();
        this.initNav();
		this.element.store('thumbscroller', this);
        this.toIndex(this.options.startIndex);
        this.lastScroll = null;
        return this;
	},

    computeDimensions: function() {
        this.thumbs = this.element.getElements(this.options.thumbs);
        this.setParentSize();
		this.positions = this.getLocations();
        return this;
    },

    isAtEnd: function(range) {
		range = range || this.getRange();
        return (range[range.length-1].index == this.thumbs.length-1 && range[range.length-1].type != 'partial');
	},
	isAtStart: function(range) {
		range = range || this.getRange()
		return (range[0].index == 0 && range[0].type != 'partial')
	},

	getLocations: function() {
		return this.thumbs.map(function(aThumb) {
			var tSize = aThumb.getComputedSize()[this.getDir('total')];
			var tStart = aThumb.getPosition(aThumb.getParent())[this.getDir('xy')];
			return {
				size: tSize,
				start: tStart,
				end: tSize + tStart
			}
		}, this);
	},

	initNav: function() {
		$$(this.options.nav.next).addEvent('click', this.toNextScreen.bind(this));
		$$(this.options.nav.previous).addEvent('click', this.toPreviousScreen.bind(this));
		$$(this.options.nav.start).addEvent('click', this.toStart.bind(this));
		$$(this.options.nav.end).addEvent('click', this.toEnd.bind(this));
	},

	getDir: function(type) {
		switch (type) {
			case 'total':
				if (this.options.axis == 'y') return 'totalHeight';
				return 'totalWidth';
			case 'dir':
				if (this.options.axis == 'y') return 'height';
				return 'width';
			case 'xy':
			default:
				if (this.options.axis == 'y') return 'y';
				return 'x';
		}
	},

	getStart: function(to) {
		if (this.options.axis == 'y')
			return [0,to];
		return [to,0];
	},

	getStartPx: function(index) {
		if (!index) return 0;
		return this.positions[index].start - (this.positions[index].start - this.positions[index-1].end);
	},

	setParentSize: function() {
		var parentElem = (this.options.thumbContainer) ? this.element.getElement(this.options.thumbContainer) : this.element.getElement(this.options.thumbs).getParent();
		var totalSize = 0;
		$each(this.thumbs, function(aThumb) {
			totalSize += aThumb.getComputedSize({styles: ['padding','border','margin']})[this.getDir('total')];
		},this);
		parentElem.setStyle(this.getDir('dir'), totalSize);
    },

	getRange: function(scrollStart) {
        scrollStart = scrollStart || this.element.getScroll()[this.getDir('xy')];
		var windowSize = this.element.getComputedSize({
			styles: ['padding']
		})[this.getDir('total')];
        var range = [];
        for (var x=0; x<this.positions.length; x++) {
			var tryRange = this.withinRange(this.positions[x], scrollStart, scrollStart + windowSize);
            if (tryRange) {
				range.push($merge(tryRange, {index: x}));
				if (tryRange.where == 'end') {
                    break;
                }
			}
		}
        return range;
	},

	withinRange: function(pos, viewStart, viewEnd) {
        if (pos.end > viewStart && pos.end <= viewEnd) {
			if (pos.start >= viewStart) {
				return {type: 'full'}
			} else {
				return {type: 'partial', where: 'start'};
			}
		} else if (pos.start >= viewStart && pos.start < viewEnd) {
			return {type: 'partial', where: 'end'};
		} else if (pos.start < viewStart && pos.end > viewEnd) {
			return {type: 'full'};
		}
		return false;
	},

	toNextScreen: function() {
		var range = this.getRange();
        if (range.getLast().type == 'partial' && range.length > 1) {
			this.start.run(this.getStart(this.getStartPx(range.getLast().index)), this);
		} else if ($(this.thumbs[range.getLast().index + 1])) {
			this.start.run(this.getStart(this.getStartPx(range.getLast().index+1)), this);
		} else {
			this.toEnd();
		}
        this.lastScroll = "next";
    },

	toPreviousScreen: function() {
		var range = this.getRange();
		var index = (range[0].type == 'partial' && range.length > 1) ? range[0].index : range[0].index - 1;
		if (!this.positions[index]) {
			this.toStart();
			return;
		}
		var startPos = this.positions[index].end - this.element.getComputedSize({styles: ['padding']})[this.getDir('total')];
		var pRange = this.getRange(startPos);
		var newIndex = (pRange[0].type=="partial" && pRange.length > 1) ? pRange[0].index+1 : pRange[0].index;
		this.start.run(this.getStart(this.getStartPx(newIndex)), this);
        this.lastScroll = "previous";
    },

	toIndex: function(index) {
		this.start.run(this.getStart(this.getStartPx(parseInt(index))), this);
	},

	toStart: function() {
		if (this.options.axis == 'y') this.toTop();
		else this.toLeft();
	},

	toEnd: function() {
		if (this.options.axis == 'y') this.toBottom();
		else this.toRight();
	}

});

window.addEvent('domready', function(){
    $$('.scrollShell').each(function(item, index){
    	item.getParent().setProperty('id', 'scroller'+index);
    	new ThumbScroller(item, {
            thumbs: 'li.promoBox',
            nav: {
                next: '#scroller'+index+' .arrowRight',
                previous: '#scroller'+index+' .arrowLeft'
            }
        }).addEvent('onComplete', function() {
            item.getParent().getElement('.arrowLeft').morph({'opacity':((this.isAtStart())?.3:1)});
            item.getParent().getElement('.arrowRight').morph({'opacity':((this.isAtEnd())?.3:1)});
        }).fireEvent('onComplete');
    });
});