/*
---
 
name: Scrollbar
description: A simple Apple-style productbrowser, that extends Slider using a container with Fx.Scroll.

version: 0.9.9
copyright: Enrique Erne (http://mild.ch)
license: MIT License
authors:
- Enrique Erne

requires: [Core/Class, Core/Element.Event, Core/Element.Dimensions, Core/Fx.Tween, Core/Fx.Transitions, Core/Selectors, More/Fx.Scroll, More/Slider]

provides: ScrollBar
 
...
*/

Elements.implement({
	        getTotalSize: function(){
	            var obj = {
	                'size': {'x': 0,'y': 0},
	                'scrollSize': {'x': 0,'y': 0},
	                'scroll': {'x': 0,'y': 0
	                }
	            };
	                this.each(function(item){
	                    obj = {
	                        'size': {
	                            'x': obj.size.x + item.getSize().x,
	                            'y': obj.size.y + item.getSize().y
	                        },
	                        'scrollSize': {
	                            'x': obj.scrollSize.x + item.getScrollSize().x,
	                            'y': obj.scrollSize.y + item.getScrollSize().y
	                        },
	                        'scroll': {
	                            'x': obj.scroll.x + item.getScroll().x,
	                            'y': obj.scroll.y + item.getScroll().y
	                        }
	                    };
	                });
	            return obj;
	        }
	    });

var ScrollBar = new Class({
	
	Extends: Slider,

	options: {
		scroll: {
			wheelStops: false/*
			onStart: $empty,
			onComplete: $empty*/
		},
		slider: {
			mode: 'horizontal',
			wheel: true/*
			onChange: $empty(intStep),
			onComplete: $empty(strStep)*/
		},
		knob: {/*
			onStart: $empty*/
		},
		knobOffset: 1,
		arrows: false,
		arrowLeft: 'left-arrow',
		arrowRight: 'right-arrow',
		desc: false
	},

	initialize: function(scroller, slider, knob, options){
		$extend(this.options, options);
		this.knob = document.id(knob).set('tween', options.knob);
		this.slider = document.id(slider);
		this.scroller = document.id(scroller);
		this.scrollElement = this.scroller.getFirst();
		this.p = 0;
		this.parent(this.slider, this.knob, $extend(this.options.slider, options.slider));
		var myElements = new Elements(this.scrollElement.getChildren());
		this.steps = (myElements.getTotalSize().size[this.axis]+this.scrollElement.getChildren().length*this.options.knobOffset) - this.scroller.getSize()[this.axis];
		this.scroll = new Fx.Scroll(this.scroller, $extend(this.options.scroll, options.scroll));
		this.mSize = myElements.getTotalSize().size[this.axis]+this.scrollElement.getChildren().length*this.options.knobOffset;
		if ((myElements.getTotalSize().size[this.axis]+this.scrollElement.getChildren().length*this.options.knobOffset) <= this.scroller.getSize()[this.axis]) {
			this.slider.setStyle('display', 'none');
			if (this.options.desc && document.id(this.options.desc)) document.id(this.options.desc).setStyle('display', 'none');
			if (this.options.arrows) {document.id(this.options.arrowLeft).setStyle('display', 'none'); document.id(this.options.arrowRight).setStyle('display', 'none');}
		} else {
			if (this.options.slider.wheel) { 
				this.scroller.addEvent('mousewheel', function(event){
					this.element.fireEvent('mousewheel', event);
				}.bind(this));
			}
		}
		this.ratio = this.steps / (this.slider.getSize()[this.axis] - this.knob.getSize()[this.axis]);
		if (this.options.arrows) {
			this.al = document.id(this.options.arrowLeft);
			this.ar = document.id(this.options.arrowRight);
			
			this.al.addEvent('click', function(event){
				s = this.p - this.scrollElement.getFirst().getComputedSize({styles: ['padding','border','margin']})[this.axis == 'x'?'totalWidth':'totalHeight']*3;
				this.set2(this.knob.getPosition(this.slider)[this.axis] - this.half, s);
			}.bind(this));
			
			this.ar.addEvent('click', function(event){
				s = this.p + this.scrollElement.getFirst().getComputedSize({styles: ['padding','border','margin']})[this.axis == 'x'?'totalWidth':'totalHeight']*3;
				this.set2((this.knob.getPosition(this.slider)[this.axis] == 1?0:this.knob.getPosition(this.slider)[this.axis]) + this.half, s);
			}.bind(this));
		}
	},
	
	move2: function(amount){
		this.set(this.knob.getPosition(this.slider)[this.axis] + amount);
	},

	set: function(position){
		if($type(position) === 'element') position = position.getPosition(this.scrollElement)[this.axis] / this.ratio;
		position = position.limit(-this.options.offset, this.full -this.options.offset);
		this.move(position * this.ratio);
		this.p = position * this.ratio;
		this.knob.tween(this.property, position).get('tween').chain(function(){
			this.fireEvent('complete', Math.round(position * this.ratio) + '');
		}.bind(this));
	},
	
	set2: function(position, s){
		if($type(position) === 'element') position = position.getPosition(this.scrollElement)[this.axis] / this.ratio;
		position = position.limit(-this.options.offset, this.full -this.options.offset);
		this.p = s;
		m = this.mSize - this.scrollElement.getFirst().getComputedSize({styles: ['padding','border','margin']})[this.axis == 'x'?'totalWidth':'totalHeight']*3;
		if (s > m) this.move(m);
		else this.move(s);
		this.knob.tween(this.property, position).get('tween').chain(function(){
			this.fireEvent('complete', Math.round(position * this.ratio) + '');
		}.bind(this));
	},

	move: function(position){
		var to = $chk(position) ? position : this.step;
		if (this.options.mode === 'vertical') this.scroll.cancel().start(0, to);
		else this.scroll.cancel().start(to, 0);
	},

	draggedKnob: function(){
		this.parent();
		if (this.options.mode === 'vertical') this.scroll.cancel().set(0, this.step);
		else this.scroll.cancel().set(this.step);
		this.p = this.scroll.element.scrollLeft;
	},

	clickedElement: function(event){
		if (event.target === this.knob){
			this.knob.get('tween').cancel();
			return;
		}
		var position = event.page[this.axis] - this.element.getPosition()[this.axis] - this.half;
		position = position.limit(-this.options.offset, this.full -this.options.offset);
		this.set(position);
	},
	
	scrolledElement: function(event){
		var mode = (this.options.mode == 'horizontal') ? (event.wheel < 0) : (event.wheel > 0);
		this.move2(mode ? -this.stepSize * 19 : this.stepSize * 19);
		event.stop();
	}

});

