Dvintage.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?
		this.track.parentNode.removeChild(this.track);
	},
	reset: function () {
		this.box.scrollTop = 0;
		this.kill();
		this._initializeElements();
		this.update();
	}
})




/* --------------------------------------------------------------------------------- */

Dvintage.ScrollblockH = Class.create({
    initialize: function(box){
	    this.options = Object.extend({
      		offsetBy:{left:5,top:0},
			setBoxHeight: false,
			setBoxHeightAlterBy: 0,
			trackStyle:null
		}, arguments[1] || { });
		this.box = $(box);
		if (this.options.trackStyle) {
			this.track = new Element('div');
			this.track.setStyle(this.options.trackStyle);
		}
		else {
			this.track = new Element('div', {className: 'scrolltrackh'});
		}
		
		this.handle = new Element('div',{className:'scrollhandleh'});
		this._initializeElements();
		this.update();
	},
	_initializeElements: function () {
		this._insertTrack();
		this._insertHandle();
		this._wireSrollWheel();		
	},
	_insertHandle: function () {
		var handleWidth = (this.box.offsetWidth / this.box.scrollWidth) * this.box.offsetWidth;
		handleWidth = Math.round(handleWidth);
		this.track.insert(this.handle);
//		this.handle.setStyle({width:handleWidth+'px'})
	},
	_insertTrack: function () {
		this.track.setStyle({
			display:'none',
			top:this.options.offsetBy.top + this.box.offsetTop + this.box.offsetHeight + 'px'
		})
		
		this.outertrack = new Element('div', {className: 'scrolloutertrack'});
		this.outertrack.setStyle({
			display:'none',
			top:this.options.offsetBy.top + this.box.offsetTop + this.box.offsetHeight + 'px'
		})
		
		
		this.box.insert({after:this.track});
		this.box.insert({after:this.outertrack});

	},
	_wireSliderControl: function () {
		if (this.slider) {
			this.slider.dispose();
		}
		this.slider = new Control.Slider(this.handle, this.track, {
			axis:'horizontal',
			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);
		this.slider.setValueBy(-scroll_amount/5);
	},
	_slide: function (value) {
		var value = Math.round((this.box.scrollWidth - this.box.offsetWidth) * value)
		this.box.scrollLeft = value;
	},
	_showTrack: function () {
		this.track.show();
		this.outertrack.show();
	},
	_hideTrack: function () {
		this.track.hide();
		this.outertrack.hide();
	},
	
	slideToMiddle: function(){
		this.slider.setValueBy(.5);	
	},
	
	hasScrollBar:function() {
		return this.track.visible();
	},
	update: function() {
		if (this.options.setBoxHeight) {

			var availableWidth = document.viewport.getWidth() - this.box.viewportOffset()[0] + this.options.setBoxHeightAlterBy - 47;	// 47 is footerheight

			if (this.box.scrollWidth > availableWidth) {
				this.box.setStyle({width: availableWidth + 'px'})
			} else {
				this.box.setStyle({width: 'auto'})			
			}
			 
		}
		
		
		if (this.box.offsetWidth >= this.box.scrollWidth) {
			this._hideTrack();
		}
		else {
			this.track.setStyle({
				width: this.box.offsetWidth +  'px',
				top: this.box.offsetTop + this.box.offsetHeight + 10 + 'px'
			});
			this._showTrack()
		}
		
		this.box.scrollLeft = 0;
		this._wireSliderControl();
		
	},
	kill: function () {
		// are the eventhandlers killed as well?
		if (this.track.parentNode) {
			this.track.remove();
			this.outertrack.remove();
		}

	},
	reset: function () {
		this.box.scrollLeft = 0;
		this.kill();
		this._initializeElements();
		this.update();
	}
})






