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

	kScroll

	Version: 0.1
	Author: Thiago Carvalho <thiago.carvalho at teadigital.com.br>
	Based on Scrollbar by Enrique Erne (http://mild.ch)
	
	Allows creating a CSS customized scrollbar with divs, to control
	scrolling of another div element.
	Support resizing of the scrollable div element.
	
	License: MIT License.
	
	Requires:
		Mootools 1.2.4
		Mootools more [Fx.Scroll, Slider]
	
----------------------------------------------------------------------- */


function k_debug(x) {
	//console.log(x);
}

var KScroll = new Class({
	
	Extends: Slider,

	options: {
		scroll: {
			wheelStops: false/*
			onStart: $empty,
			onComplete: $empty*/
		},
		slider: {
			mode: 'horizontal',
			wheel: false/*
			onChange: $empty(intStep),
			onComplete: $empty(strStep)*/
		},
		knob: {/*
			onStart: $empty*/
		}
	},

	initialize: function(options){
		this.knob = $(options.elements.knob).set('tween', options.knob);
		this.slider = $(options.elements.slider);
		this.scroller = $(options.elements.scroller);
		
		this.calculateVars(options);
		this.parent(this.slider, this.knob, $extend(this.options.slider, options.slider));
		
		k_debug('scrollerLength:     ' + this.scrollerLength);
		k_debug('sliderLength:       ' + this.sliderLength);
		k_debug('knobLength:         ' + this.knobLength);
		k_debug('usableSliderLength: ' + this.usableSliderLength);
		k_debug('ratio:              ' + this.ratio);
		
		this.scroll = new Fx.Scroll(this.scroller, $extend(this.options.scroll, options.scroll));
		this.scroller.removeEvents('mousewheel');
		this.scroller.addEvent('mousewheel', function(event){
			this.element.fireEvent('mousewheel', event);
		}.bind(this));
		
		if(options.elements.go_back && options.elements.go_forward) {
			if(options.elements.go_steps) {
				this.go_steps = options.elements.go_steps;
			} else {
				this.go_steps = 10;
			}
			
			var back = $(options.elements.go_back);
			var fwd = $(options.elements.go_forward);
			
			var scrollAmount = this.usableSliderLength / this.go_steps;
			
			back.removeEvents('click');
			back.addEvent('click', function(amount) {
					this.move2(-scrollAmount);
				}.bind(this, scrollAmount)
			);
			
			fwd.removeEvents('click');
			fwd.addEvent('click', function(amount) {
					this.move2(amount);
				}.bind(this, scrollAmount)
			);
		}
		
		// -------------------------------
		// handles container resizing
		// -------------------------------
		var check_resize = function(options) {
			if((this.scrollerLength != this.scroller.getScrollSize()[this.axis] - this.scroller.getSize()[this.axis]) ||
					(this.sliderLength != this.slider.getScrollSize()[this.axis])) {
				this.calculateVars(options);
			}
		};
		
		check_resize.periodical(200, this, options);
	},
	
	calculateVars: function(options) {
		this.scrollerLength = this.scroller.getScrollSize()[this.axis] - this.scroller.getSize()[this.axis];
		this.sliderLength = this.slider.getScrollSize()[this.axis];
		this.knobLength = this.knob.getScrollSize()[this.axis];
		//this.knob.setStyle('width',(this.slider.getSize()[this.axis] * this.scroller.getSize()[this.axis] / this.scroller.getScrollSize()[this.axis]) + 'px');
		this.usableSliderLength = this.sliderLength - this.knobLength;
		this.ratio = this.scrollerLength / this.usableSliderLength;
	},
	
	move2: function(amount){
		k_debug('move2() : amount: ' + amount); 
		this.set(this.knob.getPosition(this.slider)[this.axis] + amount);
	},

	set: function(position){
		k_debug('set() : position: ' + 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.knob.tween(this.property, position).get('tween').chain(function(){
			this.fireEvent('complete', Math.round(position * this.ratio) + '');
		}.bind(this));
	},

	move: function(position){
		k_debug('move() : position: ' + 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(){
		k_debug('draggedKnob()');
		this.parent();
		if (this.options.mode === 'vertical') {
			this.scroll.cancel().set(0, this.step*this.scrollerLength/100);
		}
		else {
			this.scroll.cancel().set(this.step*this.scrollerLength/100);
		}
	},

	clickedElement: function(event){
		k_debug('clickedElement() : event: ' + 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){
		k_debug('scrolledElement() : event: ' + event);
		var mode = (this.options.mode == 'horizontal') ? (event.wheel < 0) : (event.wheel > 0);
		this.move2(mode ? -this.stepSize * 100 : this.stepSize * 100);
		event.stop();
	},
	
	// returns knob and scrolled area to the start
	restartScroll: function(event) {
		this.move(0);
		this.knob.setStyle(this.property, 0);
	}

});

