var StepSlider = new Class({
   
    Implements: [Options, Events],
    
    options: {
        wrapper: null,
        direction: 'horizontal',
        step: 1,
        itemSize: 0,
        itemCount: 0,
        fx: null,
        buttons: [ null, null ],
        buttonsEnable: function(button, enable, immediately) {
			button.fade(enable ? (immediately ? 'show' : 'in') : (immediately ? 'hide' : 'out'));
		}
    },
    
    element: null,
    axis: 'x',
    coordinate: 'left',
    dimension: 'width',
    steps: 1,
    current: 0,
    
    // Constructor
    initialize: function(element, options) {
        
        // Setup
        this.setOptions(options);
        this.element = document.id(element);
        this.setup();
        return this;
        
    },
    
    setup: function() {
        
        var o = this.options;
        if (o.direction == 'vertical') {
            this.axis = 'y';
            this.coordinate = 'top';
            this.dimension = 'height';
        }
        
        // Setup wrapper and element styles
        if (!o.wrapper) o.wrapper = this.options.wrapper = this.element.getParent();
        o.wrapper.setStyles({
            'position': (this.options.wrapper.getStyle('position') == 'absolute') ? 'absolute' : 'relative',
            'overflow': 'hidden' });
        this.element.setStyles({
            'position': 'relative',
            'overflow': 'hidden' });
        if (o.fx) this.element.set('tween', o.fx);
        
        // Get items size and count
        var items = this.element.getChildren();
        o.itemCount = this.options.itemCount = items.length;
        if (o.itemCount > 1) {
            o.itemSize = this.options.itemSize = items[1].getPosition(this.element.setStyle(this.dimension, 10000))[this.axis];
            this.element.setStyle(this.dimension, (o.itemCount + 2) * o.itemSize + 1000);
            var overflow = (o.wrapper.getSize()[this.axis] / (o.itemSize * o.step)).floor();
            this.steps = ((o.itemCount / o.step).ceil().max(1) - (overflow - 1).max(0)).max(1);
        }
        
        // Buttons, if any
        if (o.buttons[0]) this.options.buttons[0] = document.id(o.buttons[0]).addEvent('click', this.back.bind(this));
        if (o.buttons[1]) this.options.buttons[1] = document.id(o.buttons[1]).addEvent('click', this.forward.bind(this));
        
        return this.go(this.current, true);
        
    },
    
    // Slide it!
    go: function(step, setup, set) {
        this.current = step.limit(0, this.steps - 1);
		if (set) this.element.get('tween').set(this.coordinate, - this.current * this.options.itemSize * this.options.step);
        else this.element.tween(this.coordinate, - this.current * this.options.itemSize * this.options.step);
        this.fireEvent('slide', this.current);
        if (this.options.buttons[0]) this.options.buttonsEnable(this.options.buttons[0], this.current != 0, setup);
        if (this.options.buttons[1]) this.options.buttonsEnable(this.options.buttons[1], this.current != this.steps - 1, setup);
        return this;
    },
    
    // Getters
    getWrapper: function() { return this.options.wrapper; },
    getSteps:   function() { return this.steps; },
    getCurrent: function() { return this.current; },

    // Some aliases for go()
    back:     function() { return this.go(this.current - 1); },
    forward:  function() { return this.go(this.current + 1); },
    previous: function() { return this.back(); },
    next:     function() { return this.forward(); }
    
});
