var Scroller = new Class({
    Implements: Events,
    Implements: Options,
    el: null,
    inner: null,
    inner_coords: null,
    fx: null,
    objs: null,
    total: null,
    totalWidth: null,
    current: null,
    count: 1,
    iteration: 0,
    busy: false,
    interval: null,
    options: {
        sliderId: 'scroller',
        objPrefix: 'obj',
        objWidth: null,
        duration: 500,
        timeout: 0,
        opacity: 0.3,
        clones: 1,
        transition: Fx.Transitions.Quad.easeInOut
    },
    initialize: function(id,options) {
        this.el = $(id); 
        this.setOptions(options);
        this.setup();
        this.setInterval(); 
    },
    setup: function() {
        this.fx = new Fx.Scroll(this.options.sliderId,{
            duration: this.options.duration,
            transition: this.options.transition,
            onComplete: function() {
                this.completed(); 
            }.bind(this)
        });
        this.objs = this.el.getElements('a');
        this.inner = this.el.getElement('div'); 
        this.inner_coords = this.inner.getCoordinates(); 
        for(var i=0; i<this.options.clones; i++) {
            this.inner.adopt(this.objs.clone());
        }
        this.inner.setStyle('width',this.options.objWidth*(this.objs.length*(this.options.clones+1))+this.options.objWidth); 
        this.total = this.objs.length;
        var objs = this.el.getElements('a'); 
            objs.each(function(item,index){
                if(index==0) {
                    item.setProperty('id','sliderIndex'); 
                }
                item.addEvent('mouseover',function(){
                    this.mouseenter(item); 
                }.bind(this));
                item.addEvent('mouseout',function(){
                    this.mouseleave(item); 
                }.bind(this));
                if(index<this.total) {
                    var coords = item.getCoordinates();  
                    this.totalWidth += coords.width; 
                }
             },this);
        this.all_objs = objs; 
    },
    setInterval: function() {
        if(this.options.timeout>0) {
            this.interval = this.advance.periodical(this.options.timeout,this,true); 
        } 
    },
    mouseenter: function(el) {
        this.interval = $clear(this.interval); 
        this.all_objs.each(function(item,index){
            if(item!=el) {
                item.setStyle('opacity',this.options.opacity);
            }
        },this);
    },
    mouseleave: function(el) {
        this.setInterval();
        this.all_objs.each(function(item,index){
            item.setStyle('opacity',1);
        });
    },
    advance: function() {
        if(this.busy) {return false;}
        this.busy = true; 
        this.current = this.current ? this.current.getNext() : this.inner.getFirst().getNext(); 
        this.fx.toElement(this.current); 
    },
    next: function() {
        this.interval = $clear(this.interval); 
        this.advance();
    },
    completed: function() {
        var ceiling = this.iteration==0 ? this.total : this.total+1; 
        if(this.count==ceiling) {
            this.count = 1; 
            this.iteration++;
            this.current = null; 
            this.fx.set(0); 
        } else {
            this.count++; 
        } 
        this.busy = false; 
    }
});
