YUI().use('anim', 'base', 'array-extras', 'node', 'event', 'transition', 'history', function (Y) {
	
	Y.namespace('tm').Scrollbar = Y.Base.create("Scrollbar", Y.Base, [], {
	
		initializer: function(config) {
			
			Y.on('mousewheel', Y.bind(function() {
				this.updateContentToHandle();
			}, this));

			Y.on('resize', Y.bind(function() {
				this.adjustHandleSize();
				this.updateContentToHandle();
			}, this));

			var dragOffset = null;			
			this.get('scrollbar').on('mousedown', function(e) {
				e.preventDefault();
				var position = e.pageY - this.get('scrollbar').getY();
				if (e.target === this.get('scrollbarHandle')) {
					dragOffset = e.target.getY() - e.pageY
				} else {
					dragOffset = this.get('scrollbarHandleMinHeight') / -2;
				}
				this.set('scrollbarScrollTop', position + dragOffset);
				this.updateHandleToContent();
			}, this);
			
			Y.on('mouseup', Y.bind(function() {
				dragOffset = null;
			}, this));

			Y.on('mousemove', Y.bind(function(e) {
				if (dragOffset !== null) {
					this.set('scrollbarScrollTop', e.pageY - this.get('scrollbar').getY() + dragOffset);
					this.updateHandleToContent();		
				}
			}, this));
			
			this.adjustHandleSize();
			this.updateContentToHandle();
		},
		
		adjustHandleSize: function() {
			var scale = this.get('contentFullHeight') / this.get('contentVisibleHeight');
							
			if (scale === 1) {
				this.get('scrollbar').setStyle('display', 'none');
			} else {
				this.get('scrollbar').setStyle('display', 'block');
				this.set('scrollbarHandleHeight', parseInt(this.get('scrollbarHeight') / scale, 10));
			}
		},
		
		updateHandleToContent: function() {
			this.set('contentPosition', this.get('handlePosition'));
		},
		
		updateContentToHandle: function() {
			this.set('handlePosition', this.get('contentPosition'));
		}		
		
	}, {
	
		ATTRS: {
		
			contentContainer: {
				writeOnce: true
			},
			
			scrollbar: {
				writeOnce: true
			},	
			
			scrollbarHandle: {
				writeOnce: true
			},
			
			scrollbarHandleMinHeight: {
				value: 20,
				getter: function(value) {
					if (this.get('scrollbarHandleFixHeight')) {
						return this.get('scrollbarHandleFixHeight');
					} else {
						return value;
					}
				}
			},
			
			scrollbarHandleFixHeight: {
				value: null
			},
			
			contentPosition: {
				getter: function() {
					var range = this.get('contentFullHeight') - this.get('contentVisibleHeight');
					return this.get('contentScrollTop') / range;
				},
				setter: function(value) {
					var range = this.get('contentFullHeight') - this.get('contentVisibleHeight');
					this.set('contentScrollTop', parseInt(value * range, 10));
				}
			},
			
			handlePosition: {
				getter: function() {
					var range = this.get('scrollbarHeight') - this.get('scrollbarHandleHeight');
					return this.get('scrollbarScrollTop') / range;
				},
				setter: function(value) {
					var range = this.get('scrollbarHeight') - this.get('scrollbarHandleHeight');
					this.set('scrollbarScrollTop', parseInt(value * range, 10));
				}			
			},
			
			contentVisibleHeight: {
				readonly: true,
				getter: function() {
					return this.get('contentContainer').get('offsetHeight');
				}
			},
			
			contentFullHeight: {
				readonly: true,
				getter: function() {
					return this.get('contentContainer').get('scrollHeight');
				}
			},
			
			contentScrollTop: {
				getter: function() {
					return this.get('contentContainer').get('scrollTop');
				},
				setter: function(value) {
					this.get('contentContainer').set('scrollTop', value);
				}				
			},
			
			scrollbarHeight: {
				readonly: true,
				getter: function() {
					return parseInt(this.get('scrollbar').getStyle('height'), 10);
				}
			},
			
			scrollbarHandleHeight: {
				getter: function() {
					return parseInt(this.get('scrollbarHandle').getStyle('height'), 10);
				},
				setter: function(value) {
					if (value < this.get('scrollbarHandleMinHeight')) {
						//console.log('scrollbarHandleHeight to small: ' + value);
						value = this.get('scrollbarHandleMinHeight');
					}
					//console.log(this.get('scrollbarHandleFixHeight'));
					if (this.get('scrollbarHandleFixHeight')) {
						value = this.get('scrollbarHandleFixHeight');
					} else if (value > this.get('scrollbarHeight')) {
						//console.log('scrollbarHandleHeight to big: ' + value);
						value = this.get('scrollbarHeight');
					}
					this.get('scrollbarHandle').setStyle('height', value + 'px');
				}
			},
			
			scrollbarScrollTop: {
				getter: function() {
					return parseInt(this.get('scrollbarHandle').getStyle('top'), 10);
				},
				setter: function(value) {
					var max = this.get('scrollbarHeight') - this.get('scrollbarHandleHeight');
					if (value < 0) {
						//console.log('scrollbarScrollTop to small: ' + value);
						value = 0;
					} 					
					if (value > max) {
						//console.log('scrollbarScrollTop to big: ' + value);
						value = max;
					} 
					this.get('scrollbarHandle').setStyle('top', value + 'px');
				}
			}
			
		}		
	});


	Y.on("load", function() {
		// scrollbar
		(function() {				
			new Y.tm.Scrollbar({
				contentContainer: Y.one('div#scrollable'),
				scrollbarHandle: Y.one('div#scrollbarHandle'),
				scrollbar: Y.one('div#scrollbar')
				// scrollbarHandleFixHeight: 60
			});
		})();
	}); 
});
