Ext.apply(Ext.Slider.Vertical, {
	onDrag: function(e){
		var pos = this.innerEl.translatePoints(this.tracker.getXY());
		var bottom = this.innerEl.getHeight() - pos.top;
		this.setValue(this.minValue + Math.round(bottom / this.getRatio()), false);
		this.fireEvent('drag', this, e);
	},
	onClickChange: function(local){
		if(local.left > this.clickRange[0] && local.left < this.clickRange[1]){
			var bottom = this.innerEl.getHeight() - local.top;
			this.setValue(this.minValue + Math.round(bottom / this.getRatio()), undefined, true);
		}
	}
});

Ext.ux.SliderPanel = Ext.extend(Ext.Panel, {
	border: false,
	
    initComponent: function() {
		// Setup our element
		this.el = this.applyTo;
		
		// Get the base element info
		var content_element = Ext.getDom(this.el);
		var content_html = content_element.innerHTML;
		var content_style = content_element.getAttribute('style');
		
		// Create a content panel
		var content = new Ext.Panel({
			columnWidth: 1,
			height: this.height,
			border: false,
			html: '<div style="' + content_style + '">' + content_html + '</div>'
		});
		
		// Create the slider
		var slider = new Ext.Slider({
			width: 20,
			height: this.height,
			vertical: true,
			minValue: 0 - (Ext.get(this.el).getHeight() - this.height),
			maxValue: 0,
			value: 0,
			hidden: (Ext.get(this.el).getHeight() > this.height ? false : true),
			listeners: {
				'drag': function() {
					content.body.scrollTo('top', slider.getValue() * -1);
				},
				'changecomplete': function() {
					content.body.scrollTo('top', slider.getValue() * -1, true);
				}
			}
		});
		
		// Apply config options
		Ext.apply(this, {
			layout: 'column',
			items: [
				content,
				slider
			]
        });
		
		// Remove style and html from the base element
		content_element.removeAttribute('style');
		content_element.innerHTML = '';
		
		Ext.ux.SliderPanel.superclass.initComponent.call(this);
    }
});
 
// Register xtype
Ext.reg('sliderpanel', Ext.ux.SliderPanel);