Type.registerNamespace('SfUI');

SfUI.SfSlider = function(settings)
{
	this._settings = settings;
	
	this._enabled = true;
	this._thumbLength = -1;
	this._rangeMin = 0;
	this._rangeMax = 100;
	this._physicalMin = -1;
	this._physicalMax = -1;
	this._elementThumb = null;
	this._elementThumbImage = null;
	this._elementGuide = null;
	this._isPositionInitialized = false;
	this._events = null;
	this._onMouseMoveDelegate = null;
	this._onMouseUpDelegate = null;
	
	this._Initialize();
}

SfUI.SfSlider.DragEventType = 
{
	BeginDrag : "BeginDrag",
	EndDrag : "EndDrag",
	DragMove : "DragMove"
}

SfUI.SfSlider.Orientation =
{
	Horizontal : "Horizontal",
	Vertical : "Vertical"
}

SfUI.SfSlider.prototype =
{
	SetEnabled : function(enable)
	{
		this._enabled = enable;
	},
	
	SetRange : function(min, max)
	{
		this._rangeMin = min;
		this._rangeMax = max;
	},
	
	SetPosition : function(position)
	{
		this._SetLogicalPosition(position);
	},
	
	IsPositionInitialized : function()
	{
		return this._isPositionInitialized;
	},
	
	InitializePosition : function()
	{
		this._elementThumb = $(this._settings.NamePrefix + "_thumb");
		this._elementGuide =  $(this._settings.NamePrefix + "_positionGuide");
		
		this._thumbLength = this._GetThumbLength();
		this._physicalMin = this._GetPhysicalMin();
		this._physicalMax = this._physicalMin + this._GetPhysicalLength();
		
		if (typeof (this._physicalLeft) == 'undefined' || this._physicalMax == 0)
		{
			this._isPositionInitialized = false;
		}
		else
		{
			this._isPositionInitialized = true;
		}
	},
	
	AddClickHandler : function(handler)
	{
		this._events.addHandler('Click', handler);
	},
	
	RemoveClickHandler : function(handler)
	{
		this._events.removeHandler('Click', handler);
	},
	
	AddDragHandler : function(handler)
	{
		this._events.addHandler('Drag', handler);
	},
	
	RemoveDragHandler : function(handler)
	{
 		this._events.removeHandler('Drag', handler);
	},
	
	_Initialize : function()
	{
		this.InitializePosition();
		if (this._enabled == true)
		{
			Event.observe(this._elementThumb, 'mousedown', this._BeginDrag.bindAsEventListener(this), true);
			Event.observe(this._elementGuide, 'click', this._GuideOnClick.bindAsEventListener(this), true);
			this._onMouseMoveDelegate = this._OnMove.bindAsEventListener(this);
			this._onMouseUpDelegate = this._OnUp.bindAsEventListener(this);
		}
		
		this._InitializeThumbOver();
		this._events = new Sys.EventHandlerList();
	},
	
	_InitializeThumbOver : function()
	{
		if (this._settings.ImageInfo.ThumbOverImage != null)
		{
			Event.observe(this._elementThumb, 'mouseover', this._ThumbImageOver.bind(this));
			Event.observe(this._elementThumb, 'mouseout', this._ThumbImageOut.bind(this));
		}
	},
	
	_ThumbImageOver : function()
	{
		this.InitializePosition();
		this._elementThumb.style.backgroundImage = 'url(' + this._settings.ImageInfo.ThumbOverImage +')';
	},
	
	_ThumbImageOut : function()
	{
		this._elementThumb.style.backgroundImage = 'url(' + this._settings.ImageInfo.ThumbImage + ')';
	},
	
	_GetThumbLength : function()
	{
		if (this._settings.Orientation == SfUI.SfSlider.Orientation.Horizontal)
		{
			return parseInt(this._elementThumb.getStyle('width'));
		}
		else
		{
			return parseInt(this._elementThumb.getStyle('height'));
		}
	},
	
	_GetPhysicalMin : function()
	{
		if (this._settings.Orientation == SfUI.SfSlider.Orientation.Horizontal)
		{
			return this._GetPhysicalLeft();
		}
		else
		{
			return this._GetPhysicalTop();
		}
	},
	
	_GetPhysicalLength : function()
	{
		if (this._settings.Orientation == SfUI.SfSlider.Orientation.Horizontal)
		{
			return parseInt(this._elementGuide.getStyle('width'));
		}
		else
		{
			//! bug in IE
			return parseInt(this._elementGuide.getStyle('height'));
		}
	},
	
	_ParsePx : function(arg)
	{
		var retVal;
		var re = /\d+px/i;
		if (arg.match(re))
		{
			retVal = arg.substr(0, arg.length-2);
		}
		else
		{
			retVal = arg;
		}
		return Number(retVal);
	},

	_GetPhysicalLeft : function()
	{
		var physicalLeft = this._elementGuide.offsetLeft;
		var par = this._elementGuide.offsetParent;
		while (par)
		{
			physicalLeft += par.offsetLeft;
			par = par.offsetParent;
		}
		return physicalLeft;
	},
	
	_GetPhysicalTop : function()
	{
		var physicalTop = this._elementGuide.offsetTop;
		var par = this._elementGuide.offsetParent;
		while (par)
		{
			physicalTop += par.offsetTop;
			par = par.offsetParent;
		}
		return physicalTop;
	},

	_LogicalToPhysical : function(logicalLength)
	{
		var physicalLength, totalLogicalLength, totalPhysicalLength;
		
		totalLogicalLength = this._rangeMax-this._rangeMin;
		totalPhysicalLength = this._physicalMax-this._physicalMin;
		
		if (totalLogicalLength==0)
		{
			physicalLength = 0;
		}
		else
		{
			physicalLength = (totalPhysicalLength) * logicalLength;
			physicalLength = physicalLength/(totalLogicalLength);
		}

		var physicalPosition;
		if (this._settings.Orientation == SfUI.SfSlider.Orientation.Horizontal)
		{
			physicalPosition = this._physicalMin + physicalLength;
		}
		else
		{
			physicalPosition = this._physicalMax - physicalLength;
		}
		
		return physicalPosition;
	},
	
	_PhysicalToLogical : function(physicalPosition)
	{
		var logicalLength, totalLogicalLength, totalPhysicalLength;
		
		totalLogicalLength = this._rangeMax-this._rangeMin;
		totalPhysicalLength = this._physicalMax-this._physicalMin;
		
		if (totalLogicalLength==0 || totalPhysicalLength==0)
		{
			logicalLength=0;
		}
		else if (physicalPosition < this._physicalMin)
		{
			if (this._settings.Orientation == SfUI.SfSlider.Orientation.Horizontal)
			{
				logicalLength = 0;
			}
			else
			{
				logicalLength = totalLogicalLength;
			}
		}
		else if (physicalPosition > this._physicalMax)
		{
			if (this._settings.Orientation == SfUI.SfSlider.Orientation.Horizontal)
			{
				logicalLength = totalLogicalLength;
			}
			else
			{
				logicalLength = 0;
			}
		}
		else
		{
			var physicalLength;
			if (this._settings.Orientation == SfUI.SfSlider.Orientation.Horizontal)
			{
			    physicalLength = physicalPosition - this._physicalMin;
			}
			else
			{
				physicalLength = this._physicalMax - physicalPosition;
			}
			
			logicalLength = (totalLogicalLength) * physicalLength;
			logicalLength = logicalLength/(totalPhysicalLength);
		}
		
		return logicalLength;
	},
	
	_SetPhysicalPosition : function(position)
	{
	    if (position < this._physicalMin)
	    {
			position = this._physicalMin;
		}
	    if (position > this._physicalMax)
	    {
			position = this._physicalMax;
		}
		
		if (this._settings.Orientation == SfUI.SfSlider.Orientation.Horizontal)
		{
			this._elementThumb.style.left = '' + (position - this._physicalMin - this._thumbLength/2) + 'px';
		}
		else
		{
			this._elementThumb.style.top = '' + (position - this._physicalMin - this._thumbLength/2) + 'px';
		}
	},
	
	_SetLogicalPosition : function(position)
	{
		if (position < this._rangeMin)
		{
			position = this._rangeMin;
		}
		if (position > this._rangeMax)
		{
			position = this._rangeMax;
		}
		
		this._SetPhysicalPosition(this._LogicalToPhysical(position));
	},
	
	_GuideOnClick : function(evt)
	{
		this.InitializePosition();
		this._PostClickEvent(this._GetLogicalPositionFromEvent(evt));
	},
	
	_GetPhysicalPositionFromEvent : function(evt)
	{
		if (this._settings.Orientation == SfUI.SfSlider.Orientation.Horizontal)
		{
			return evt.pageX;
		}
		else
		{
			return evt.pageY;
		}
	},
	
	_GetLogicalPositionFromEvent : function(evt)
	{
		var physicalPos = this._GetPhysicalPositionFromEvent(evt);
		return this._PhysicalToLogical(physicalPos);
	},
	
	_PostClickEvent : function(logicalPosition)
	{
		var args = new Object();
 		args.Position = logicalPosition;
		var handler = this._events.getHandler('Click');
		if (handler == null)
		{
			return;
		}
		handler(this, args);
	},
	
	_PostDragEvent : function(type, logicalPosition)
	{
		var args = new Object();
		args.DragEventType = type;
 		args.Position = logicalPosition;
		var handler = this._events.getHandler('Drag');
		if (handler == null)
		{
			return;
		}
		handler(this, args);
	},
	
	_BeginDrag : function(evt)
	{
		Event.observe(document, 'mousemove', this._onMouseMoveDelegate, true);
		Event.observe(document, 'mouseup', this._onMouseUpDelegate, true);
		Event.stop(evt);

		this._PostDragEvent(SfUI.SfSlider.DragEventType.BeginDrag, this._GetLogicalPositionFromEvent(evt));
	},

	_OnUp : function (evt)
	{
		var logicalPosition = this._GetLogicalPositionFromEvent(evt);

		Event.stopObserving(document, 'mousemove', this._onMouseMoveDelegate, true);
		Event.stopObserving(document, 'mouseup', this._onMouseUpDelegate, true);
		Event.stop(evt);
		
		this._PostDragEvent(SfUI.SfSlider.DragEventType.EndDrag, logicalPosition);
	},
		
	_OnMove : function(evt)
	{
		var logicalPosition = this._GetLogicalPositionFromEvent(evt);
		
		Event.stop(evt);
		
		if (logicalPosition < this._rangeMin || logicalPosition > this._rangeMax)
		{
			return;
		}

		this._PostDragEvent(SfUI.SfSlider.DragEventType.DragMove, logicalPosition);
	}

}
SfUI.SfSlider.registerClass('SfUI.SfSlider');

SfUI.SfDiscreteSlider = function(settings)
{
	this._settings = settings;
	
	SfUI.SfDiscreteSlider.initializeBase(this, [this._settings]);
	
	this._points = null;
	
	this._DivideIntoPoints();
}

SfUI.SfDiscreteSlider.prototype =
{	
	SetPointNumber : function(pointNumber)
	{
		this.SetPosition(this._points[pointNumber]);
	},
	
	FindClosestPointNumber : function(pos)
	{
		var closestPoint = 0;
		var minDistance = Math.abs(this._points[0] - pos);
		for (var i=1; i<this._points.length; ++i)
		{
			var distance = Math.abs(this._points[i] - pos);
			if (distance < minDistance)
			{
				minDistance = distance;
				closestPoint = i;
			}
		}
		
		return closestPoint;
	},

	_DivideIntoPoints : function()
	{
		var min = this._rangeMin;
		var max = this._rangeMax;
		
		var length = max - min;
		var numSegments = this._settings.NumPoints - 1;
		var segmentLength = length / numSegments;
		
		this._points = new Array(this._settings.NumPoints);
		
		this._points[0] = min;
		for (var i=1; i<=numSegments; ++i)
		{
			this._points[i] = min + i*segmentLength;
		}
	}
}
SfUI.SfDiscreteSlider.registerClass('SfUI.SfDiscreteSlider', SfUI.SfSlider);



