var ThumbScroller = new Class({
Extends: Fx.Scroll,

scrollOptions: {
    thumbs: '.promoBox',
    axis: 'x',
    thumbContainer: null,
    nav: {
        next: '.arrowRight',
        previous: '.arrowLeft',
        start: '.start',
        end: '.end'
    }
},

initialize: function(element, scrollOptions) {
    this.parent(element, $merge(scrollOptions, this.scrollOptions));
    this.thumbs = this.element.getElements(this.options.thumbs);
    this.positions = this.getLocations();
    this.setParentSize();
    this.initNav();
    this.element.store('thumbscroller', this);
    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')];
        var tEnd = tSize + tStart;
        return {
            start: tStart,
            end: tEnd,
            size: tSize
        }
    }, 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 parent = (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);
    parent.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 = [];
    var x;
    for (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();
    }
},

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);
},

toIndex: function(index) {
    this.start.run(this.getStart(this.getStartPx(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();
}

});
