var ScrollBar = new Class({
Implements: [Options, Events],
options: {
bars: {
x: false,
y: true
},
drag: true,
slowdown: true,
relativeTo: false,
slider: [],
scrollbars: []
},
initialize: function(element, options){
this.setOptions(options);
this.element = $(element);
this.sliders = [];
this.elements = [];
if(this.options.scrollDelay)
this.scrFx = new Fx.Scroll(this.element, $merge({
duration: 300,
link: 'cancel',
transition: 'quint:out'
}, this.options.scrollDelay));
if((this.options.bars.y || this.options.bars == 'auto') && this.options.drag)
this.makeDraggable('vertical');
this.update();
},
destroy: function(){
if(this.options.drag && this.drag)
this.drag.detach();
this.slider.detach();
this.slider.element.destroy();
},
update: function(){
$$(this.elements).destroy();
if(this.element.getScrollSize().y > this.element.getSize().y){
if(this.options.drag){

this.drag.attach();
}
if(this.options.bars.y || this.options.bars == 'auto'){
this.stepY = this.element.getScrollSize().y - this.element.getSize().y;
this.makeSlider('vertical');
}
if(this.options.bars.x || this.options.bars == 'auto'){
this.stepX = this.element.getScrollSize().x - this.element.getSize().x;
this.makeSlider('horizontal');
}
} else {
if(this.options.drag)
this.drag.detach();
}
},
makeSlider: function(direction){
var scrollbar = new Element('div', {
'class': 'scrollbar-' + direction
}).injectAfter(this.element);
if(direction == 'vertical')
scrollbar.setStyles({
height: this.element.getComputedSize().height
});
else
scrollbar.setStyles({
width: this.element.getComputedSize().width
});
var knob = new Element('div', {
'class': 'knob-' + direction
}).inject(scrollbar);
var pos = scrollbar.position($merge({
relativeTo: this.options.relativeTo ? $(this.options.relativeTo) : this.element,
edge: direction == 'vertical' ? 'topRight' : 'bottomLeft',
position: direction == 'vertical' ? 'topRight' : 'bottomLeft'
}, this.options.scrollbars[direction]));
this.elements.push(scrollbar, knob);
var change = function(step){
var x = direction == 'horizontal' ? step : 0;
var y = direction == 'vertical' ? step : 0;
this.element.scrollTo(~~x, ~~y);
};
this.slider = new Slider(scrollbar, knob, $merge({
steps: direction == 'vertical' ? this.stepY : this.stepX,
mode: direction
}, this.options.slider[direction])).set(0);
if(this.options.scrollDelay)
this.slider.addEvent('complete', (function(step){
var x = direction == 'horizontal' ? step : 0;
var y = direction == 'vertical' ? step : 0;
this.scrFx.start(~~x, ~~y);
}).bind(this));
else
this.slider.addEvent('change', (function(step){
change.bind(this, step)();
}).bind(this));
this.element.addEvent('mousewheel', (function(e){
e = new Event(e).stop();
var step = this.slider.step - e.wheel * 30;
this.slider.set(step);
if(this.options.scrollDelay)
change.bind(this, step)();
}).bind(this));
this.sliders[direction] = this.slider;
},
makeDraggable: function(direction){
var modifiers = direction == 'horizontal' ? {x: 'scrollLeft', y: false} : {x: false, y: 'scrollTop'};
this.drag = new Drag(this.element, {
modifiers: {x: 'scrollLeft', y: 'scrollTop'},


invert: true,
style: false,
bounce: .5,
friction: .01,
onBeforeStart: function(){
this.element.setStyle('cursor', 'url(/shared/img/cursor/grabdown.png), move');
},
onStart: function(el, e){
},
onDrag: (function(el, e){
if(this.element.getScrollSize().y > this.element.getSize().y)
this.sliders[direction].set(this.element.getScroll().y);
}).bind(this),
onComplete: (function(){
this.element.setStyle('cursor', 'url(/shared/img/cursor/grab.png), move');
}).bind(this)
});
$$('input', 'select', 'textarea').addEvent('mousedown', (function(e){
e.target.focus();
this.drag.detach();
var attach = (function(){
this.drag.attach().start(e);
e.target.removeEvent('blur', attach);
}).bind(this);
e.target.addEvent('blur', attach);
}).bind(this));
}
});
