// Add mouse wheel support to prototype
Object.extend(Event, {
        wheel:function (event){
                var delta = 0;
                if (!event) event = window.event;
                if (event.wheelDelta) {
                        delta = event.wheelDelta/120;
                        if (window.opera) delta = -delta;
                } else if (event.detail) { delta = -event.detail/3;}
                return delta; //Safari Round
        }
});

Odessa.Scrollblock = Class.create({
    initialize: function(box){
	    this.options = Object.extend({
      		offsetBy:{left:5,top:0},
			setBoxHeight: false,
			setBoxHeightAlterBy: 0,
			setBoxHeightAdditionalElements:[],
			trackStyle:null
		}, arguments[1] || { });
		this.box = box;
		this.backgroundOffset = -2483;		// bar is height:5000
		if (this.options.trackStyle) {
			this.track = new Element('div');
			this.track.setStyle(this.options.trackStyle);
		}
		else {
			this.track = new Element('div', {className: 'scrolltrack'});
		}
		this.handle = new Element('div',{className:'scrollhandle'});
		this._initializeElements();
		this.update();
	},
	_initializeElements: function () {
		this._insertTrack();
		this._insertHandle();
		this._wireSrollWheel();		
	},
	_insertHandle: function () {
		this.track.appendChild(this.handle);
	},
	_insertTrack: function () {
		this.track.setStyle({
			display:'none',
			left:this.options.offsetBy.left + this.box.offsetLeft + this.box.offsetWidth + 'px', 
			top:this.options.offsetBy.top + this.box.offsetTop + 'px', 
			backgroundPosition: 'center ' + this.backgroundOffset + 'px'
		})
		this.box.insert({after:this.track})	
	},
	_wireSliderControl: function () {
		if (this.slider) {
			this.slider.dispose();
		}
		this.slider = new Control.Slider(this.handle, this.track, {
			axis:'vertical',
			onSlide: function(value){
				// TEMP FIX! BUG IN SCRIPTACULUS??
				if (value==1)
					return;
				this._slide(value);
			}.bind(this),
			onChange: function(value){
				this._slide(value);			
			}.bind(this)}
		 );
	},
	_wireSrollWheel: function () {
		Event.observe(this.box, 'mousewheel', this._scrollWheel.bindAsEventListener(this), true);
		Event.observe(this.box, 'DOMMouseScroll', this._scrollWheel.bindAsEventListener(this), true);
	},
	_scrollWheel: function (event) {
		var scroll_amount = Event.wheel(event);
		var deltaHeight = this.box.scrollHeight - this.box.offsetHeight;
		this.slider.setValueBy(-scroll_amount/(deltaHeight/15));
	},
	_slide: function (value) {
//		c(value)
		var value = Math.round((this.box.scrollHeight - this.box.offsetHeight) * value)
		this.box.scrollTop = value;
		this.track.setStyle({backgroundPosition: 'center ' + parseInt(this.backgroundOffset + this.handle.offsetTop) + 'px'});		
	},
	showTrack: function () {
		this.track.show();
	},
	hideTrack: function () {
		this.track.hide();
	},
	hasScrollBar:function() {
		return this.track.visible();
	},
	/* returns a real between 0 and 1 */
	getScrollHeight: function(){
		return this.box.scrollTop / (this.box.scrollHeight - this.box.offsetHeight);
	},
	/* uses a real between 0 and 1 */
	setScrollHeight: function(value){
		this._slide(value);
	},
	setScrollHeight: function(value){
		return this.box.scrollTop;
	},
	update: function(){
		
		if (this.options.setBoxHeight) {

			var heights = 0;
			this.options.setBoxHeightAdditionalElements.map(function(element){
				if (element) {
					heights += element.getHeight();
				}
			})
			var availableHeight = document.viewport.getHeight() - this.box.viewportOffset()[1] + this.options.setBoxHeightAlterBy - heights;

			if (this.box.scrollHeight > availableHeight) {
				this.box.setStyle({height: availableHeight + 'px'})
			} else {
				this.box.setStyle({height: 'auto'})			
			}
			
		}

		if (this.box.offsetHeight >= this.box.scrollHeight) {
			this.box.scrollTop = 0;
			this.hideTrack();
		}
		else {
			this.track.setStyle({
				height: this.box.offsetHeight + 'px'
			});
			this.showTrack()
		}
		
		this._wireSliderControl();
		
	},
	kill: function () {
		// are the eventhandlers killed as well?
		if (this.track.parentNode) {
			this.track.parentNode.removeChild(this.track);
		}
	},
	reset: function () {
		this.box.scrollTop = 0;
		this.kill();
		this._initializeElements();
		this.update();
	}
})
