/*
 +--------------------------------------------------------------+
 |                                                              |
 | cSlider v1.0                                                 |
 |                                                              |
 | by Bastian Sackermann - http://samisdat.org                  |
 |                                                              |
 | More Informations avaible at                                 |
 | http://samisdat.org/cSlider/                                 |
 |                                                              |
 | Licensed under the Creative Commons BY-NC-SA 3.0 License     |
 | http://creativecommons.org/licenses/by-nc-sa/3.0/            |
 |                                                              |
 +--------------------------------------------------------------+
 */
var DefaultOpts = {
    outerMenu: '.outerMenu',
    innerMenu: '.innerMenu',
    handle: '.bar',
    track: '.track',
    trackWrap: '.trackStyle',
    itemCat: 'h3',
    itemContainer: 'ul',
    itemElem: 'li',
    skipPrev: '.trackWrap .left',
    skipNext: '.trackWrap .right'
}

var cSlider = Class.create({
    initialize: function(id, opts){
        this.elem = $(id);
        this.elem.addClassName('script');
        this.opts = Object.extend(Object.extend({}, DefaultOpts), opts ||{});
        this.addTrack();
        
        this.outerMenu = this.elem.select(this.opts.outerMenu)[0];
        this.innerMenu = this.elem.select(this.opts.innerMenu)[0];
        this.handle = this.elem.select(this.opts.handle)[0];
        this.track = this.elem.select(this.opts.track)[0];
        
        this.scanMenu(id);
        this.slider = new Control.Slider(this.handle, this.track, {
            sliderValue: 0,
            range: $R(0, this.innerMenu.getWidth() - this.outerMenu.getWidth()),
            onSlide: this.slided.bind(this),
            onChange: this.slided.bind(this)
        });
        
        this.elem.select(this.opts.skipPrev)[0].observe('click', this.step.bindAsEventListener(this, 'back'));
        this.elem.select(this.opts.skipNext)[0].observe('click', this.step.bindAsEventListener(this, 'forward'));
        
    },
    addTrack: function(){
        var html = "" +
        "<div class='trackWrap'>" +
        "<div class='left'></div>" +
        "<div class='center'></div>" +
        "<div class='right'></div>" +
        "<div class='track'>" +
        "<div class='bar'>" +
        "<div class='left'></div>" +
        "<div class='center'></div>" +
        "<div class='right'></div>" +
        "</div>" +
        "</div>" +
        "</div>";
        this.elem.insert(html);
    },
    scanMenu: function(id){
        var itemCats = this.elem.select(this.opts.itemCat);
        this.track.insert({after: '<div class="barText"></div>'});
        this.itemsCats = [];
        this.items = [];
        var widthAll = 0;
        var startItemCat = 0;
        var index = 0;
        if (itemCats.length > 0) {
            for (var i = 0; i < itemCats.length; i++) {
                this.itemsCats[i] = {};
                this.itemsCats[i].title = itemCats[i].innerHTML.stripTags();        
                var width = 0;
                var items = this.elem.select(this.opts.itemContainer)[i].select(this.opts.itemElem);
                for (var x = 0; x < items.length; x++) {
                    this.items[index] = {
                        start: startItemCat + width,
                        width: items[x].getWidth()
                    }
                    index++;
                    width += items[x].getWidth();
                }
                this.itemsCats[i].width = width;
                this.itemsCats[i].start = startItemCat;
                startItemCat += width;
                widthAll += this.itemsCats[i].width
            }
        }
        else {
            this.itemsCats = false;
            var width = 0;
            var items = this.elem.select(this.opts.itemElem);
            for (var i = 0; i < items.length; i++) {
                this.items[index] = {
                    start: width,
                    width: items[i].getWidth()
                }
                index++;
                width += items[i].getWidth();
            }
            widthAll += width;
        }
        this.innerMenu.setStyle({
            width: widthAll + 'px'
        });
        var trackWidth = this.innerMenu.getWidth() - this.outerMenu.getWidth();
        var menu2track = (widthAll - this.outerMenu.getWidth()) / (this.track.getWidth() - this.handle.getWidth());
        var posLeft = 0;
        for (var i = 0; i < itemCats.length; i++) {
            if (this.itemsCats[i].start < this.innerMenu.getWidth() - this.outerMenu.getWidth()) {
                posLeft = parseInt(this.itemsCats[i].start / menu2track);
            }
            else {
                posLeft = this.track.getWidth() - 100;
            }
            var style = 'style="position:absolute;top:0;left:' + posLeft + 'px;"';
            this.elem.select('.barText')[0].insert('<div ' + style + '>' + this.itemsCats[i].title + '</div>');
            this.elem.select('.barText div')[i].observe('click', this.skipTo.bindAsEventListener(this, this.itemsCats[i]));
        }
    },
    step: function(evt, mode){
        var visible = [];
        var startPos = -1 * parseInt(this.innerMenu.getStyle('left'));
        var endPos = startPos + this.outerMenu.getWidth();
        for (var i = 0; i < this.items.length; i++) {
            if (this.items[i].start >= startPos && (this.items[i].start + this.items[i].width) < endPos) {
                visible.push(i);
            }
        }
        var skipTo = 0;
        if (mode == 'forward') {
            skipTo = this.items[visible.last() + 1].start;
        }
        if (mode == 'back') {
            skipTo = (this.items[visible.first() - 1].start + this.items[visible.first()].width - this.outerMenu.getWidth());
        }
        this.move(skipTo);
    },
    skipTo: function(evt, item){
        this.move(item.start);
    },
    move: function(to){
        new Effect.Move(this.innerMenu, {
            duration: 0.3,
            x: -to,
            mode: 'absolute',
            afterUpdate: this.updateValue.bind(this)
        });
    },
    updateValue: function(){
        var left = parseInt(this.innerMenu.getStyle('left'),10) * -1;
        this.slider.setValue(left);
    },
    slided: function(v){
        this.innerMenu.setStyle({
            left: -v + 'px'
        });
    }
});

document.observe("dom:loaded", function(){
    $$('.cSlider').each(function(cSliderElem){
        new cSlider(cSliderElem);
    })
});
