// Scrollbar types
var SB_HORIZONTAL = 'horizontal';
var SB_VERTICAL   = 'vertical';


var getChildrenWidth = function(element, childrenSelector, includeMargins) {
	var el = $(element);
	if (!$defined(el)) return 0;
	
	var result = 0;
	var elements = ($defined(childrenSelector))?el.getElements(childrenSelector):el.getChildren();
	elements.each(function(child){
		result += child.getWidth() + child.getStyle('border-left-width').toInt() + child.getStyle('border-right-width').toInt();
		if (includeMargins == true){
			result += child.getStyle('margin-left').toInt() + child.getStyle('margin-right').toInt();
		}
	});
	return result;
}



var scrollers = new Class({
	slider: null,
	initialize: function(scroll,elements,size) {
		if (!$defined(scroll))   return false;
		if (!$defined(elements)) return false;

		this.scroll          = scroll;
		this.scroll_elements = elements;
		this.handle          = this.scroll.getElement('.handle');
		this.scrollbar       = this.handle.getParent();
		this.element_count   = this.scroll_elements.getChildren('li').length;

		if (this.scroll.hasClass(SB_HORIZONTAL)) {
			this.scroll.setStyle('width', ($defined(size))? size : 'auto');
			this.scroll_elements.setStyle('position', 'absolute');
			this.scroll_elements.setStyle('left', 0);
		} else {
			this.scroll.setStyle('height', ($defined(size))? size : 'auto');
			this.scroll_elements.setStyle('position', 'relative');
			this.scroll_elements.setStyle('top', 0);
		}

		this.scroll.getElements('a').each(function(a) {
			a.set('href', 'javascript\u003a\u003b');
			a.removeEvents('click');
		});

		// Set scrollbar dimmensions
		if (this.scroll.hasClass(SB_HORIZONTAL)) {
			var ulsize = getChildrenWidth(this.scroll_elements);
			this.scroll_elements.setStyle('width', (ulsize*1.2) + 'px');
			this.offset = this.scroll.getSize().x - (this.scrollbar.getPrevious('a.scroll').getSize().x + this.scrollbar.getNext('a.scroll').getSize().x) - 2;
			this.scroll_elements.getParent('.pad').setStyles({ 'width': (this.offset+6), 'margin': '0 auto' });
			this.spacing = ulsize - this.scroll_elements.getParent('.pad').getSize().x;
			this.scrollbar.setStyle('width', (this.offset > 0)? this.offset : 'auto');
			// Code for autosizing scrollbar handle
			var handleWidth = Math.round(this.scroll_elements.getParent('.pad').getSize().x * this.offset / ulsize);
			this.handle.setStyle('width', Math.max(handleWidth, 31));
		} else {
			if ($defined(size)) {
				this.scroll.setStyle('height', size);
			} else {
				this.scroll.setStyle('height', (this.scroll.getParent().getSize().y > 0)? this.scroll.getParent().getSize().y : 0);
			}
			this.offset = this.scroll.getSize().y - (this.scrollbar.getPrevious('a.scroll').getSize().y + this.scrollbar.getNext('a.scroll').getSize().y) - 2;
			this.spacing = this.scroll_elements.getSize().y - this.scroll_elements.getParent().getSize().y;
			this.scrollbar.setStyle('height', (this.offset > 0)? this.offset : 'auto');
			// Code for autosizing scrollbar handle
			var handleHeight = Math.round(this.scroll_elements.getParent().getSize().y * this.offset / this.scroll_elements.getSize().y);
			this.handle.setStyle('height', Math.max(handleHeight, 31));
		}

		// If elements fit in panel, hide scrollbar and do not create scroller handler
		if (this.spacing < 0) {
			this.scroll.setStyle('display', 'none');
			return; 
		}
		
		// Create scrollbar handler and store it inside the DOM element
		this.scroller();
		this.scroll.store('scrollbar_object', this);
	}, 

	scroller: function() {
		this.slider = null;
		this.slider = new Slider(this.scrollbar, this.handle, {
			steps: this.spacing,
			mode: (this.scroll.hasClass(SB_HORIZONTAL))?SB_HORIZONTAL:SB_VERTICAL,
			wheel: false, 
			onChange: function(step) {
				if (!$defined(step)){ return; }
				this.scroll_elements.setStyle((this.scroll.hasClass(SB_HORIZONTAL))?'left':'top', '-'+step+'px');
			}.bind(this)
		});

		this.scrollbar.getPrevious('a.scroll').addEvent('click', function(ev) {
			ev.stop();
			this.prevScroll();
		}.bind(this));
		this.scrollbar.getNext('a.scroll').addEvent('click', function(ev) {
			ev.stop();
			this.nextScroll();
		}.bind(this));
		this._adjustTooltips();
	}, 
	
	prevScroll: function() {
		if (this.slider.step > 0) 
			this.slider.set(this.slider.step - this.spacing / this.element_count);
	}, 
	
	nextScroll: function() {
		this.slider.set(this.slider.step + this.spacing / this.element_count);
	}, 
	
	_adjustTooltips: function() {
		this.scroll_elements.getElements('li').each(function(el){
			if($defined(el.retrieve('tooltip'))){
				el.retrieve('Tooltip').toolTipPosition(el,el.retrieve('tooltip'));
			}
		});
	}
});


var DOMScrollBar = new Class({
	
	element : new Element('div', { 
			'class': 'scrollbar'
			}).adopt(new Element('a', {
			'href': '#',
			'class': 'scroll up'
		}).grab(new Element('span', {
			'text': 'Scroll Up'
		})),
		new Element('div').grab(new Element('a', {
			'href':'#',
			'class':'scroll handle'
		}).grab(new Element('span', { 
			'text': 'Scroll Handle' }))),
		new Element('a', {
			'href':'#', 
			'class':'scroll down'
		}).grab(new Element('span', { 'text':'Scroll Down'}))
	), 

	initialize: function(container, createScroller, type, classes) {
		// Create a new element clone
		var clone = this.element.clone(true,true);
		
		if (type == SB_HORIZONTAL) 
			clone.addClass(SB_HORIZONTAL);

		if ($defined(container)) {
			// Destroy old scrollbar, if any
			var scrollbar = container.getElement('.scrollbar');
			if ($defined(scrollbar)){ scrollbar.dispose(); }
			// Append new scrollbar to container
			container.grab(clone);
		}

		// If wanted, add new scroller handler (Mootools slider)
		if (createScroller == true) {
			if (clone.getParent()) {
				new scrollers(clone, clone.getParent().getElement('ul'));
			}
		}
		return clone.addClass($defined(classes)?classes:'');
	}

});