
kff.widgets.Slider = function(element, options)
{
	this.options = $.extend({
		steps: 100,
		min: 0,
		max: 100,
		change: null,
		drag: null,
		dragStart: null,
		dragEnd: null,
		position: 0,
		axis: 'x',
		speed: 0
	}, options);
	this.$element = $(element);
	this.$scrollbar = null;
	this.scrollPosition = 0;
	this.position = this.options.position;
	this.axProps = this.options.axis == 'x' ? 
		{
			width: 'width',
			left: 'left',
			pageX: 'pageX'
		} :
		{
			width: 'height',
			left: 'top',
			pageX: 'pageY'
		};
};

// kff.extend(kff.widgets.Slider, kff.widgets.Widget);

kff.widgets.Slider.prototype.pixelToRange = function(pixel)
{
	var v = Math.round((pixel / this.paneWidth * this.span + this.options.min) / this.roundTo) * this.roundTo;
	if(v < this.options.min) v = this.options.min;
	if(v > this.options.max) v = this.options.max;
	return v;
}

kff.widgets.Slider.prototype.rangeToPixel = function(v)
{
	if(v < this.options.min) v = this.options.min;
	if(v > this.options.max) v = this.options.max;
	return Math.round((v - this.options.min) / this.span * this.paneWidth);	
}

kff.widgets.Slider.prototype.render = function()
{
	this.$sliderBox = $('<div class="kff-range-select"></div>').appendTo(this.$element);	
	this.$sliderPane = $('<div class="kff-slider-pane"></div>').appendTo(this.$sliderBox);
	this.$sliderHandle = $('<div class="kff-handle"></div>').appendTo(this.$sliderPane);	
	
	this.handleWidth = this.$sliderHandle[this.axProps.width]();
	this.paneWidth = this.$sliderPane[this.axProps.width]();

	this.span = this.options.max - this.options.min;
	this.roundTo = this.span / this.options.steps;
}

kff.widgets.Slider.prototype.init = function()
{
	var that = this;
	
	this.render();

	this.$sliderHandle.bind('mousedown', $.proxy(this.mouseDown, this));
	this.$sliderBox.bind('mousedown', $.proxy(this.mouseDownPane, this));
		
	this.setPosition(this.position);
}

kff.widgets.Slider.prototype.destroy = function()
{
	this.$sliderHandle.unbind().remove();
	this.$sliderPane.unbind().remove();
	this.$sliderBox.unbind().remove();
}

kff.widgets.Slider.prototype.getPosition = function()
{
	return this.position;
}

kff.widgets.Slider.prototype.setPosition = function(a)
{
	this.handleWidth = this.$sliderHandle.eq(0)[this.axProps.width]();
	this.paneWidth = this.$sliderPane[this.axProps.width]();

	this.position = a;
	this.change(this.position); 
	
	var apx = this.rangeToPixel(this.position);

	this.$sliderHandle.eq(0).css(this.axProps.left, apx - this.handleWidth / 2);								
}

kff.widgets.Slider.prototype.mouseDownPane = function(event)
{
	this.$activeHandle = this.$sliderHandle.eq(0);
	this.$activeHandle.css(this.axProps.left, event[this.axProps.pageX] - this.$sliderBox.offset()[this.axProps.left] - this.handleWidth / 2);
	this.downPosition = this.$activeHandle.position()[this.axProps.left] + this.handleWidth / 2;					
	this.newPosition = 0;
	this.oldPosition = this.position;
	this.downEvent = event;
			
	$('body').css({ cursor: 'pointer'});
	
	$(document).bind('mousemove', $.proxy(this.mouseMove, this));
	$(document).bind('mouseup', $.proxy(this.mouseUp, this));
	
	this.mouseMove(event);
		
	event.preventDefault();
	return false;
	
}

kff.widgets.Slider.prototype.mouseDown = function(event)
{
	this.$activeHandle = $(event.currentTarget);
	this.downPosition = this.$activeHandle.position()[this.axProps.left] + this.handleWidth / 2;					
	this.newPosition = 0;
	this.oldPosition = this.oldDragPosition = this.position;
	this.downEvent = event;
			
	$('body').css({ cursor: 'pointer'});
	
	$(document).bind('mousemove', $.proxy(this.mouseMove, this));
	$(document).bind('mouseup', $.proxy(this.mouseUp, this));
	
	event.preventDefault();
	return false;
}

kff.widgets.Slider.prototype.mouseMove = function(event)
{
	var deltaX = event[this.axProps.pageX] - this.downEvent[this.axProps.pageX];
	
	var newPositionPx = this.rangeToPixel(this.pixelToRange(this.downPosition + deltaX));
	
	if(newPositionPx < 0 ) newPositionPx = 0;
	if(newPositionPx > this.paneWidth) newPositionPx = this.paneWidth;
	
	var newPosition = this.pixelToRange(newPositionPx);
	
	if(newPosition != this.oldDragPosition)
	{
		this.position = newPosition;						
		this.drag(this.position);
		this.oldDragPosition = newPosition;
		var cssProps = {};
		cssProps[this.axProps.left] = newPositionPx - this.handleWidth / 2;
		this.$activeHandle.stop().animate(cssProps, this.options.speed, 'linear');
	}
	
	event.preventDefault();
	return false;
}

kff.widgets.Slider.prototype.mouseUp = function(event)
{
	$('body').css({ cursor: 'auto'});
	$(document).unbind('mousemove', this.mouseMove).unbind('mouseup', this.mouseUp);
	event.preventDefault();
	this.dragEnd(this.position);
	
	if(this.oldPosition != this.position)
	{
		
		this.change(this.position);
	}
	return false;
}

kff.widgets.Slider.prototype.drag = function(position)
{
	if(typeof this.options.drag == 'function') this.options.drag(position); 
}

kff.widgets.Slider.prototype.dragEnd = function(position)
{
	if(typeof this.options.dragEnd == 'function') this.options.dragEnd(position); 
}

kff.widgets.Slider.prototype.change = function(position)
{
	if(typeof this.options.change == 'function') this.options.change(position); 
}



kff.widgets.RangeSlider = function(element, options)
{
	this.options = $.extend({
		steps: 100,
		min: 0,
		max: 100,
		change: null,
		drag: null,
		dragStart: null,
		dragEnd: null,
		position: {a: 0, b: 100},
		axis: 'x'
	}, options);
	this.$element = $(element);
	this.$scrollbar = null;
	this.scrollPosition = 0;
	this.position = this.options.position;
	this.axProps = this.options.axis == 'x' ? 
		{
			width: 'width',
			left: 'left',
			pageX: 'pageX'
		} :
		{
			width: 'height',
			left: 'top',
			pageX: 'pageY'
		};
};

kff.extend(kff.widgets.RangeSlider, kff.widgets.Slider);

kff.widgets.RangeSlider.prototype.render = function()
{
	this.$sliderBox = $('<div class="kff-range-select"></div>').appendTo(this.$element);	
	this.$sliderPane = $('<div class="kff-slider-pane"></div>').appendTo(this.$sliderBox);
	this.$sliderBar = $('<div class="kff-slider-bar"></div>').appendTo(this.$sliderPane);
	this.$sliderHandles = $('<div class="kff-handle"></div><div class="kff-handle"></div>').appendTo(this.$sliderPane);	
	
	this.handleWidth = this.$sliderHandles.width();
	this.paneWidth = this.$sliderPane.width();

	this.span = this.options.max - this.options.min;
	this.roundTo = this.span / this.options.steps;
}

kff.widgets.RangeSlider.prototype.init = function()
{
	var that = this;
	
	this.render();

	this.$sliderHandles.bind('mousedown', $.proxy(this.mouseDown, this));
	this.$sliderBox.bind('mousedown', $.proxy(this.mouseDownPane, this));

	this.setPosition(this.position.a, this.position.b);
}

kff.widgets.RangeSlider.prototype.mouseDownPane = function(event)
{
	/* Zjištění nejližšího handlu */
	if(Math.abs(this.$sliderHandles.eq(0).offset()[this.axProps.left] + this.handleWidth / 2 - event[this.axProps.pageX]) < 
		Math.abs(this.$sliderHandles.eq(1).offset()[this.axProps.left] + this.handleWidth / 2 - event[this.axProps.pageX]))
	{
		this.$activeHandle = this.$sliderHandles.eq(0);
	}
	else this.$activeHandle = this.$sliderHandles.eq(1);
	
	this.$activeHandle.css(this.axProps.left, event[this.axProps.pageX] - this.$sliderPane.offset()[this.axProps.left] - this.handleWidth / 2);

	this.downPosition = this.$activeHandle.position()[this.axProps.left] + this.handleWidth / 2;		
	this.inactiveHandlePosition = this.$sliderHandles.not(this.$activeHandle).position()[this.axProps.left] + this.handleWidth / 2;			

	this.newPosition = 0;
	this.oldPosition = this.position;
	this.oldPositionBoth = {a: this.position.a, b: this.position.b};
	this.downEvent = event;
			
	$('body').css({ cursor: 'pointer'});
	
	$(document).bind('mousemove', $.proxy(this.mouseMove, this));
	$(document).bind('mouseup', $.proxy(this.mouseUp, this));
	
	this.mouseMove(event);
		
	event.preventDefault();
	return false;
	
}

kff.widgets.RangeSlider.prototype.mouseDown = function(event)
{
	this.$activeHandle = $(event.currentTarget);
	this.downPosition = this.$activeHandle.position()[this.axProps.left] + this.handleWidth / 2;		
	this.inactiveHandlePosition = this.$sliderHandles.not(event.currentTarget).position()[this.axProps.left] + this.handleWidth / 2;			
	this.newPosition = 0;
	this.oldPosition = this.position;
	this.oldPositionBoth = {a: this.position.a, b: this.position.b};
	this.downEvent = event;
			
	$('body').css({ cursor: 'pointer'});
	
	$(document).bind('mousemove', $.proxy(this.mouseMove, this));
	$(document).bind('mouseup', $.proxy(this.mouseUp, this));
	
	event.preventDefault();
	return false;
}

kff.widgets.RangeSlider.prototype.mouseMove = function(event)
{
	var deltaX = event[this.axProps.pageX] - this.downEvent[this.axProps.pageX];
	
	var newPosition = this.rangeToPixel(this.pixelToRange(this.downPosition + deltaX));
	
	if(newPosition < 0 ) newPosition = 0;
	if(newPosition > this.paneWidth) newPosition = this.paneWidth;
	
	if(newPosition != this.oldPosition)
	{
		
		this.position.a = newPosition < this.inactiveHandlePosition ? this.pixelToRange(newPosition) : this.pixelToRange(this.inactiveHandlePosition);
		this.position.b = newPosition >= this.inactiveHandlePosition ? this.pixelToRange(newPosition) : this.pixelToRange(this.inactiveHandlePosition);
		
		this.drag(this.position);
		 
		this.oldPosition = newPosition;
		this.$activeHandle.css(this.axProps.left, newPosition - this.handleWidth / 2);
		
		this.$sliderBar.css(this.axProps.left, (newPosition < this.inactiveHandlePosition ? newPosition : this.inactiveHandlePosition));
		this.$sliderBar.css(this.axProps.width, Math.abs(newPosition - this.inactiveHandlePosition));
	}
	
	event.preventDefault();
	return false;
	
}

kff.widgets.RangeSlider.prototype.mouseUp = function(event)
{
	$('body').css({ cursor: 'auto'});
	$(document).unbind('mousemove', this.mouseMove).unbind('mouseup', this.mouseUp);
	event.preventDefault();
	this.dragEnd(this.position); 
	if(this.oldPositionBoth.a != this.position.a || this.oldPositionBoth.b != this.position.b) this.change(this.position);
	return false;
}

kff.widgets.RangeSlider.prototype.destroy = function()
{
	this.$sliderHandles.unbind().remove();
	this.$sliderBar.unbind().remove();
	this.$sliderPane.unbind().remove();
	this.$sliderBox.unbind().remove();
}

kff.widgets.RangeSlider.prototype.getPosition = function()
{
	return this.position;
}

kff.widgets.RangeSlider.prototype.setPosition = function(a, b)
{
	this.handleWidth = this.$sliderHandles.eq(0).width();
	this.paneWidth = this.$sliderPane.width();

	this.position.a = a;
	this.position.b = b;

	this.change(this.position); 
	
	var apx = this.rangeToPixel(this.position.a);
	var bpx = this.rangeToPixel(this.position.b);

	this.$sliderHandles.eq(0).css(this.axProps.left, apx - this.handleWidth / 2);
	this.$sliderHandles.eq(1).css(this.axProps.left, bpx - this.handleWidth / 2);
						
	this.$sliderBar.css({
		left: apx, 
		width: bpx - apx
	});								
}

