// namespace
if ( !sliderfuncs ) var sliderfuncs = {};

/**
 * This function represents a slider class that can be instanciated for more than
 * one slider on a given page at the same time.
 * @constructor
 * @param id The name of a variable containing this object.
 */
sliderfuncs.SimpleSlider = function( id )
{
	this.id = id;
	
	// Holds the value of the slider.
	this.value = 0;
	
	// Holds the minimum value the slider can set.
	this.minVal = 0;
	
	// Holds the maximum value the slider can set.
	this.maxVal = 100;
	
	// Holds the step size. Values for the sliders will be set between minVal and maxVal in steps of stepSize.
	this.stepSize = 1;

	// HTML container into which the slider will be rendered. Typically a DIV.
	this.container = null;
	
	// True if the slider can be manipulated, False otherwise. 
	// In a false state, the slider will be rendered as grayed out.
	this.enabled = true;
	
	// True if the slider is read only and cannot be changed, False otherwise. 
	// In true state the slider will be rendered normally, but will not allow manipulation.
	this.readonly = false;
	
	// Holds the width of the slider if it is horizontally oriented, or height if it is vertically oriented.
	this.size = 90;
	
	this.orientation = 1;
	
	// Holds additional data that will be sent in the events. This is for convenience, and doesn't have to be used.
	this.additionalData = null;
	
	this.listeners = [];
	
	// Holds the mouse position when dragging starts.
	this.currentMousePos = null;
	
	// Hold the original value before dragging began.
	this.origVal = 0;
	
	
	this.setAdditionalData = function( data )
	{
		this.additionalData = data;
	}
	
	this.setMinVal = function( minVal )
	{
		this.minVal = minVal;
	}
	
	this.setMaxVal = function( maxVal )
	{
		this.maxVal = maxVal;
	}
	
	this.setStepSize = function( stepSize )
	{
		this.stepSize = stepSize;
	}
	
	this.addEventListener = function( listener )
	{
		this.listeners.push( listener );
	}
	
	this.getId = function()
	{
		return this.id;
	}
	
	this.setValue = function( newVal )
	{
		this.value = newVal;
	}
	
	this.getValue = function()
	{
		return this.value;
	}
	
	this.setContainer = function( newContainer )
	{
		this.container = newContainer;
	}
	
	this.setEnabled = function( newEnabled )
	{
		this.enabled = newEnabled;
	}
	
	this.getEnabled = function()
	{
		return this.enabled;
	}
	
	this.setReadonly = function( newReadonly )
	{
		this.readonly = newReadonly;
	}
	
	this.getReadonly = function()
	{
		return this.readonly;
	}
	
	this.init = function()
	{
		this.render();
		this.setPointerToValue();
		if ( this.enabled && !this.readonly )
		{
			this.makeDraggable();
		}
		else
		{
			this.makeUndraggable();
		}
	}

	this.startOverlayDrag = function( event )
	{
		//alert('start overlay drag');
		if ( !event )
		{
			event = window.event;
		}
		this.currentMousePos = [event.screenX,event.screenY];
		//alert('orig= ' + this.origVal + ", value= " + this.value);
		this.origVal = this.value;
		//alert('here');
		top.currentSlidingObject.calculateValue( event );
		//alert('value after calc(mouseover) ' + this.value);
		top.currentSlidingObject.setOverlayToValue();
		
		var sliderFrame = document.getElementById( "simpleSlider::" + this.id );
		
		sliderFrame.onmousemove = function( e ){
			
			top.currentSlidingObject.drag( e, true );
		
		}
		
		sliderFrame.onmouseout = function( e )
		{
			var goingToObj = null;
			
			if(e && e.relatedTarget) goingToObj = e.relatedTarget;
			else goingToObj = window.event.toElement;
			
			if(!isChildOf(goingToObj,sliderFrame))
			{
				top.currentSlidingObject.value = top.currentSlidingObject.origVal;
				top.currentSlidingObject.setOverlayToOrigValue();
				
				//alert(top.currentSlidingObject.value);
				
				var e = {};
				e.type = "layoutDragAbort";
				e.value = this.origVal;
				//alert('firing');
				top.currentSlidingObject.dispatchEvent( e );
				this.currentMousePos = null;
			
				sliderFrame.onmousemove = function( event ){return false;}
				sliderFrame.onmouseup = function( event ){return false;}
				sliderFrame.onmousemove = function( event ){return false;}
				//top.currentSlidingObject = null;
				document.body.focus();
			}
			
		}
				
	}
	this.calculateValue = function( event)
	{
		var pointerObj = document.getElementById( "simpleSliderPointer::" + top.currentSlidingObject.id );
		var pointerX = getPosX( pointerObj );
		
		var mouseX = event.clientX;// event.screenX;
		
		//document.title = "pointer: " + pointerX + ", mouseX: " + mouseX + ", clientX" + event.clientX;
		
		var difference = mouseX - pointerX;
		this.value = this.origVal + ((difference * (this.maxVal - this.minVal)) / this.size);
		
		
		
		if ( this.value < this.minVal )
		{
			this.value = this.minVal;
		}
		else if ( this.value > this.maxVal )
		{
			this.value = this.maxVal;
		}
		var mod = this.value % this.stepSize;
		if ( mod != 0 )
		{
			if ( mod < this.stepSize / 2 )
			{
				this.value -= mod;
			}
			else
			{
				this.value = this.value - mod + this.stepSize;
			}
		}
		
	}
	
	this.endDrag = function( event )
	{
		if ( !event )
		{
			event = window.event;
		}
		this.currentMousePos = null;
		document.onmousemove = null;
		document.onmouseup = null;
		//top.currentSlidingObject = null;
		this.origVal = this.value;
		document.body.focus();
		var e = {};
		e.type = "DragEnd";
		e.value = this.value;
		this.dispatchEvent( e );
	}
	
	this.dispatchEvent = function( event )
	{
		event.additionalData = this.additionalData;
		event.slider = this;
		for ( var i = 0; i < this.listeners.length; i++ )
		{
			this.listeners[i]( event );
		}
	}
	
	this.drag = function( event, dragOnlyLayout)
	{
		
		if ( !event )
		{
			event = window.event;
		}
		if ( this.currentMousePos )
		{
			var difference = 0;
			if(dragOnlyLayout)
			{
				var pointerObj = document.getElementById( "simpleSliderPointer::" + top.currentSlidingObject.id );
				var pointerX = getPosX( pointerObj );
				var mouseX = event.clientX;
				
				difference = mouseX - pointerX;
			}
			else
			{
				difference = event.screenX - this.currentMousePos[0];
			}
			
			this.value = this.origVal + ((difference * (this.maxVal - this.minVal)) / this.size);
			if ( this.value < this.minVal )
			{
				this.value = this.minVal;
			}
			else if ( this.value > this.maxVal )
			{
				this.value = this.maxVal;
			}
			var mod = this.value % this.stepSize;
			if ( mod != 0 )
			{
				if ( mod < this.stepSize / 2 )
				{
					this.value -= mod;
				}
				else
				{
					this.value = this.value - mod + this.stepSize;
				}
			}
			
			
			
			if( !dragOnlyLayout )
			{	
				this.setPointerToValue();
			}

			this.setOverlayToValue();
			
			// Send an event to the listeners			
			
				var e = {};
				if( dragOnlyLayout )
					e.type = "LayoutDrag";
				else
					e.type = "Drag";
				e.value = this.value;
				this.dispatchEvent( e );
			
		}
	}
	
	
	
	this.makeDraggable = function()
	{
		var pointerObj = document.getElementById( "simpleSliderPointer::" + this.id );
		pointerObj.style.cursor = "pointer";

		pointerObj.ondrag = function( event ){ return false; };
		pointerObj.ondragstart = function( event ){ return false; };
		pointerObj.ondragend = function( event ){ return false; };
		
		
		/* onmouseover overlay cover */
		var sliderFrame = document.getElementById( "simpleSlider::" + this.id );
		
		sliderFrame.style.cursor = 'pointer';
		
		
		sliderFrame.onmouseover = function (event){
			
			var comingFromObj = null;
			if( event && event.relatedTarget) comingFromObj = event.relatedTarget;
			else comingFromObj = window.event.fromElement;
			
			var varId = this.id.substring( this.id.indexOf("::") + 2, this.id.length );
			var sliderObj = eval(varId);
			top.currentSlidingObject = sliderObj;
			
			
			/*
			 * handle mouseover within the slider.
			 * */
			if(isChildOf(comingFromObj,sliderFrame)) return;
			
			
			/*
			 * mouse is hovering on the slider. set initial state.
			 */
			sliderObj.startOverlayDrag( event );
			
		}
		
		
		sliderFrame.onmousedown = function( event )
		{
			var overElement = null; 
			if(event && event.target) 	overElement = event.target;
			else if(window.event) 		overElement = window.event.srcElement;
			if(overElement && overElement.id && ( overElement.id.indexOf("simpleSliderPointer") > - 1 ) ) return;
			
			
			
			var varId = this.id.substring( this.id.indexOf("::") + 2, this.id.length );
			var sliderObj = eval(varId);
			top.currentSlidingObject = sliderObj;
			
			top.currentSlidingObject.setPointerToValue();
			top.currentSlidingObject.endDrag( event );
		}
		
	}
	this.makeUndraggable = function()
	{
		var pointerObj = document.getElementById( "simpleSliderPointer::" + this.id );
		pointerObj.style.cursor = "default";
		pointerObj.onmousedown = null;
		pointerObj.ondrag = null;
		pointerObj.ondragstart = null;
		pointerObj.ondragend = null;
	}
	
	this.render = function()
	{
		var sliderHtml = '<div class="simpleSliderBox" style="width:' + this.size + 'px;" id="simpleSlider::' + this.id + '">' +
							'	<div class="sliderOverlay" id="simpleSliderOverlay::' + this.id + '" style="width:' + ((this.size / (this.maxVal - this.minVal))*(this.value - this.minVal)) + 'px;"></div>' +
							'	<div class="sliderPointer" id="simpleSliderPointer::' + this.id + '"></div>' +
						 '</div>';
		this.container.innerHTML = sliderHtml;
	}
	
	this.setPointerToValue = function()
	{
		var sliderObj = document.getElementById( "simpleSlider::" + this.id );
		var pointerObj = document.getElementById( "simpleSliderPointer::" + this.id );
		var xPosition = getPosX( sliderObj );
		var yPosition = getPosY( sliderObj );
		pointerObj.style.left = (xPosition - 4) + ((this.size / (this.maxVal - this.minVal))*(this.value - this.minVal)) + "px";
		pointerObj.style.top = (yPosition + 10) + "px";
	}
	
	this.setOverlayToValue = function()
	{
		//alert(this.value);
		var overlay = document.getElementById( "simpleSliderOverlay::" + this.id );
		overlay.style.width = ((this.size / (this.maxVal - this.minVal))*(this.value - this.minVal)) + "px";
	}
	this.setOverlayToOrigValue = function()
	{
		//alert("orig: " + this.origVal + ", value: " + this.value);
		var overlay = document.getElementById( "simpleSliderOverlay::" + this.id );
		overlay.style.width = ((this.size / (this.maxVal - this.minVal))*(this.origVal - this.minVal)) + "px";
	}
	
	
	this.valToName = function( val )
	{
		if ( val == -1 )
		{
			return "";
		}
		if ( val >= 0 && val < 1 )
		{
			return "Terrible";
		}
		if ( val >= 1 && val < 2 )
		{
			return "Awful";
		}
		if ( val >= 2 && val < 3  )
		{
			return "Bad";
		}
		if ( val >= 3 && val < 4 )
		{
			return "Poor";
		}
		if ( val >= 4 && val < 5  )
		{
			return "Disappointing";
		}
		if ( val >= 5 && val < 6 )
		{
			return "So-so";
		}
		if ( val >= 6 && val < 7  )
		{
			return "Okay";
		}
		if ( val >= 7 && val < 8 )
		{
			return "Good";
		}
		if ( val >= 8 && val < 9  )
		{
			return "Great";
		}
		if ( val >= 9 && val < 10  )
		{
			return "Amazing";
		}
		if ( val == 10 )
		{
			return "Must See";
		}
	}
}