/*
 * 
 * Lazzo.nl
 * 
 */

ComicHouse.Scrollblock = Class.create({
	
    initialize: function(box){
		
	    this.options = Object.extend({
      		offsetBy:{left:0,top:0},
			offsetTopImageBy:{left:0,top:0},
			offsetBottomImageBy:{left:0,top:0},
			setBoxHeight: false,
			setBoxHeightAlterBy: 0,
			setBoxHeightAdditionalElements:[],
			customClassName:'',
			trackStyle:null,
			leftAlign:false,
			callback:Prototype.emptyFunction
			
		}, 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: 'scrolltrack'+this.options.customClassName});
		}
		
		this.handle = new Element('div',{className:'scrollhandle'});
		
		this._initializeElements();
		this.update();
		
	},
	
	_initializeElements: function () {
		
		if (this.options.leftAlign) {
			this._insertArrowButtonsLeftAligned();
			this._insertTrackLeftAligned();
			
		} else {
			this._insertArrowButtons();
			this._insertTrack();
			
		}
		
		this._insertHandle();
		this._wireSrollWheel();
				
	},
	
	_insertArrowButtons: function(){
		
		var opt = this.options;
		
		var left = opt.offsetBy.left + this.box.offsetLeft + this.box.offsetWidth + opt.offsetTopImageBy.left + 'px';
		if (!this.scrolltop) {
			this.scrolltop = new Element('div').addClassName('scrolltop'+opt.customClassName);
			this.box.insert({after:this.scrolltop});	
			this.scrolltop.observe('mousedown', function(){this.slider.setValue(0);}.bind(this));
		}
		
		this.scrolltop.setStyle({display:'none',left:left,top:opt.offsetBy.top + opt.offsetTopImageBy.top + this.box.offsetTop + 'px'});
		if (!this.scrollbottom) {
			this.scrollbottom = new Element('div').addClassName('scrollbottom'+this.options.customClassName);
			this.box.insert({after:this.scrollbottom});
			this.scrollbottom.observe('mousedown', function(){this.slider.setValue(1);}.bind(this));
		}

		this.scrollbottom.setStyle({display:'none',left:left,top:opt.offsetBottomImageBy.top + this.box.offsetTop + this.box.offsetHeight - this.scrollbottom.getHeight() + 'px' });
		
	},

	_insertArrowButtonsLeftAligned: function(){
		
		var opt = this.options;
		
		var left = this.box.offsetLeft - opt.offsetBy.left - opt.offsetTopImageBy.left + 'px';
		this.scrolltop = new Element('div').addClassName('scrolltop'+opt.customClassName);
		this.box.insert({after:this.scrolltop});
		
		this.scrolltop.setStyle({
			display:'none',
			left:left, 
			top:opt.offsetBy.top + opt.offsetTopImageBy.top + this.box.offsetTop + 'px'
		});
		this.scrolltop.observe('mousedown', function(){this.slider.setValue(0);}.bind(this));

		this.scrollbottom = new Element('div').addClassName('scrollbottom'+opt.customClassName);
		this.box.insert({after:this.scrollbottom});
		this.scrollbottom.setStyle({
			display:'none',
			left:left, 
			top:opt.offsetBy.top + opt.offsetBottomImageBy.top + this.box.offsetTop + this.box.offsetHeight - this.scrollbottom.getHeight() + 'px'
		});
		this.scrollbottom.observe('mousedown', function(){this.slider.setValue(1);}.bind(this));
		
	},
	
	_insertHandle: function () {
	
		if (this.box.getHeight() == 0) {
			return;
		}
		
		var handleHeight = (this.box.offsetHeight / this.box.scrollHeight) * this.box.offsetHeight;
		handleHeight = Math.round(handleHeight) - 40;
		handleHeight = (handleHeight <= 30)? 30:handleHeight;

		this.track.insert(this.handle);
		this.handle.setStyle({height:handleHeight+'px'});
		
	},
	
	
	_insertTrackLeftAligned: function () {
		this.track.setStyle({
			display:'none',
			left:this.box.offsetLeft - this.options.offsetBy.left + 'px', 
			top:this.options.offsetBy.top + this.box.offsetTop + this.scrolltop.getHeight() + 'px'
		});
		this.box.insert({after:this.track});
	},
	
	_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 + this.scrolltop.getHeight() + '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) {
		var value = Math.round((this.box.scrollHeight - this.box.offsetHeight) * value);
		this.box.scrollTop = value;
		this.options.callback();
	},
	
	
	/*
	 * Get the current slider value. This might break in future Scripaculous updates.
	 */	
	getSliderValue: function() {
		
		return this.slider.value;
		
	},
	
	/*
	 * Set the current slider value. This might break in future Scripaculous updates.
	 */	
	setValue: function(value) {

		this.slider.setValue(value);
		
	},
	
	
	/*
	 * Interface to programmacaly move the scrollbar.
	 */
	setValueBy: function(value) {
		var scrollBy = (value+8) / this.box.scrollHeight; 
		//var value = Math.round((this.box.scrollHeight - this.box.offsetHeight) * value);
		this.slider.setValueBy(scrollBy);
		
	},
	
	showTrack: function () {
		this.scrolltop.show();
		this.track.show();
		this.scrollbottom.show();
	},
	
	hideTrack: function () {
		this.scrolltop.hide();
		this.track.hide();
		this.scrollbottom.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);
	},

	getScrollTop: function(){
		return this.box.scrollTop;
	},	

	setScrollTop: function(value){
		//this.box.scrollTop = value;
		this.slider.setValue(value);
	},	
	
	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.getHeight() - this.scrolltop.getHeight() - this.scrollbottom.getHeight() - this.options.offsetBy.top + 'px'
			});
			this.showTrack();
		}
		
		this._wireSliderControl();
		
	},
	kill: function () {
		// are the eventhandlers killed as well?
		if (this.track.parentNode) {
			this.track.parentNode.removeChild(this.track);
			this.scrolltop.remove(); this.scrollbottom.remove();
		}
				
	},
	
	reset: function () {
		this.box.scrollTop = 0;
		//this.kill();
		this._initializeElements();
		this.update();
	},
	
	setCallBack: function (callback) {

		this.options.callback = callback;

	}
});



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


ComicHouse.ScrollblockH = Class.create({
    initialize: function(box){
	    this.options = Object.extend({
      		offsetBy:{left:0,top:0},
			offsetTopImageBy:{left:0,top:0},
			offsetBottomImageBy:{left:0,top:0},
			setBoxHeight: false,
			setBoxHeightAlterBy: 0,
			trackStyle:null,
			customClassName:''
		}, 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._insertArrowButtons();
		this._wireSrollWheel();		
	},
	
	_insertArrowButtons: function(){
		if (!this.box) {return;}		
		var px = 'px';
		var opt = this.options;
		this.scrollarrowleft = new Element('div').addClassName('scrollarrowleft');
		this.box.insert({after:this.scrollarrowleft});
		this.scrollarrowleft.setStyle({
			
			display:'none',
			left:this.box.offsetLeft + px, 
			top:this.options.offsetBy.top + this.box.offsetTop + this.box.offsetHeight + px
			
		});
		this.scrollarrowleft.observe('mousedown', function(){this.slider.setValue(0);}.bind(this));

		this.scrollarrowright = new Element('div').addClassName('scrollarrowright'+this.options.customClassName);
		this.box.insert({after:this.scrollarrowright});
		var left = this.box.offsetLeft + this.box.offsetWidth - this.scrollarrowright.getWidth() + px;
		this.scrollarrowright.setStyle({
			
			display:'none',
			left:left,
			top:this.options.offsetBy.top + this.box.offsetTop + this.box.offsetHeight + px 
			
		});
		this.scrollarrowright.observe('mousedown', function(){this.slider.setValue(1);}.bind(this));
	},
	
	_insertHandle: function () {
		if (!this.box) {return;}
		var handleWidth = (this.box.offsetWidth / this.box.scrollWidth) * this.box.offsetWidth;
		handleWidth = Math.round(handleWidth) - 60;
		handleWidth = (handleWidth <= 30)? 30:handleWidth;
		
		this.track.insert(this.handle);
		this.handle.setStyle({position:'absolute',left:0, width:handleWidth+'px'});
	},
	_insertTrack: function () {
		if (!this.box) {return;}
		var px = 'px';
				
		this.track.setStyle({
			display:'none',
			left:this.box.offsetLeft + 12 + px,
			top:this.options.offsetBy.top + this.box.offsetTop + this.box.offsetHeight + px});
		
		this.outertrack = new Element('div', {className: 'scrolloutertrack'});
		this.outertrack.setStyle({
			display:'none',
			left:this.box.offsetLeft + px,
			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.scrollarrowleft.show();
		this.scrollarrowright.show();
		this.track.show();
		this.outertrack.show();
	},
	_hideTrack: function () {
		this.scrollarrowleft.hide();
		this.scrollarrowright.hide();
		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 - 70;	//

			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 -70 + '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.scrollarrowleft.remove(); this.scrollarrowright.remove();
		}

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




