/*----------------------------------------------------------------------------\

|                                Slider 1.02                                  |

|-----------------------------------------------------------------------------|

|                         Created by Erik Arvidsson                           |

|                  (http://webfx.eae.net/contact.html#erik)                   |

|                      For WebFX (http://webfx.eae.net/)                      |

|-----------------------------------------------------------------------------|

| A  slider  control that  degrades  to an  input control  for non  supported |

| browsers.                                                                   |

|-----------------------------------------------------------------------------|

|                Copyright (c) 2002, 2003, 2006 Erik Arvidsson                |

|-----------------------------------------------------------------------------|

| Licensed under the Apache License, Version 2.0 (the "License"); you may not |

| use this file except in compliance with the License.  You may obtain a copy |

| of the License at http://www.apache.org/licenses/LICENSE-2.0                |

| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |

| Unless  required  by  applicable law or  agreed  to  in  writing,  software |

| distributed under the License is distributed on an  "AS IS" BASIS,  WITHOUT |

| WARRANTIES OR  CONDITIONS OF ANY KIND,  either express or implied.  See the |

| License  for the  specific language  governing permissions  and limitations |

| under the License.                                                          |

|-----------------------------------------------------------------------------|

| Dependencies: timer.js - an OO abstraction of timers                        |

|               range.js - provides the data model for the slider             |

|               winclassic.css or any other css file describing the look      |

|-----------------------------------------------------------------------------|

| 2002-10-14 | Original version released                                      |

| 2003-03-27 | Added a test in the constructor for missing oElement arg       |

| 2003-11-27 | Only use mousewheel when focused                               |

| 2006-05-28 | Changed license to Apache Software License 2.0.                |

|-----------------------------------------------------------------------------|

| Created 2002-10-14 | All changes are in the log above. | Updated 2006-05-28 |

\----------------------------------------------------------------------------*/



Slider.isSupported = typeof document.createElement != "undefined" &&

	typeof document.documentElement != "undefined" &&

	typeof document.documentElement.offsetWidth == "number";

	var mouse_down = 0;



function Slider(oElement, oInput, sOrientation) {

	if (!oElement) return;

	this._orientation = sOrientation || "horizontal";

	this._range = new Range();

	this._range.setExtent(0);

	this._blockIncrement = 10;

	this._unitIncrement = 1;

	this._timer = new Timer(100);





	if (Slider.isSupported && oElement) {



		this.document = oElement.ownerDocument || oElement.document;



		this.element = oElement;

		this.element.slider = this;

		this.element.unselectable = "on";



		// add class name tag to class name

		this.element.className = this._orientation + " " + this.classNameTag + " " + this.element.className;



		// create line

		this.line = this.document.createElement("DIV");

		this.line.className = "line";

		this.line.id = "line";

		this.line.unselectable = "on";

		this.line.appendChild(this.document.createElement("DIV"));

		this.element.appendChild(this.line);



		// create handle

		this.handle = this.document.createElement("DIV");

		this.handle.className = "handle";

		this.handle.id = "handle";

		this.handle.unselectable = "on";

		this.handle.appendChild(this.document.createElement("DIV"));

		this.handle.firstChild.appendChild(

			this.document.createTextNode(String.fromCharCode(160)));

		this.element.appendChild(this.handle);

	}



	this.input = oInput;



	// events

	var oThis = this;

	this._range.onchange = function () {

		oThis.recalculate();

		if (typeof oThis.onchange == "function")

			oThis.onchange();

	};



	if (Slider.isSupported && oElement) {

		this.element.onfocus		= Slider.eventHandlers.onfocus;

		this.element.onblur			= Slider.eventHandlers.onblur;

		this.element.onmousedown	= Slider.eventHandlers.onmousedown;

		this.element.onmouseover	= Slider.eventHandlers.onmouseover;

		this.element.onmouseout		= Slider.eventHandlers.onmouseout;

		this.element.onkeydown		= Slider.eventHandlers.onkeydown;

		this.element.onkeypress		= Slider.eventHandlers.onkeypress;

		this.element.onmousewheel	= Slider.eventHandlers.onmousewheel;

		this.handle.onselectstart	=

		this.element.onselectstart	= function () { return false; };



		this._timer.ontimer = function () {

			oThis.ontimer();

		};



		// extra recalculate for ie

		window.setTimeout(function() {

			oThis.recalculate();

		}, 1);

	}

	else {

		this.input.onchange = function (e) {

			oThis.setValue(oThis.input.value);

		};

	}

}



Slider.eventHandlers = {



	// helpers to make events a bit easier

	getEvent:	function (e, el) {

		if (!e) {

			if (el)

				e = el.document.parentWindow.event;

			else

				e = window.event;

		}

		if (!e.srcElement) {

			var el = e.target;

			while (el != null && el.nodeType != 1)

				el = el.parentNode;

			e.srcElement = el;

		}

		if (typeof e.offsetX == "undefined") {

			e.offsetX = e.layerX;

			e.offsetY = e.layerY;

		}



		return e;

	},



	getDocument:	function (e) {

		if (e.target)

			return e.target.ownerDocument;

		return e.srcElement.document;

	},



	getSlider:	function (e) {

		var el = e.target || e.srcElement;

		while (el != null && el.slider == null)	{

			el = el.parentNode;

		}

		if (el)

			return el.slider;

		return null;

	},



	getLine:	function (e) {

		var el = e.target || e.srcElement;

		while (el != null && el.className != "line")	{

			el = el.parentNode;

		}

		return el;

	},



	getHandle:	function (e) {

		var el = e.target || e.srcElement;

		var re = /handle/;

		while (el != null && !re.test(el.className))	{

			el = el.parentNode;

		}

		return el;

	},

	// end helpers



	onfocus:	function (e) {

		var s = this.slider;

		s._focused = true;

		s.handle.className = "handle hover";

	},



	onblur:	function (e) {

		var s = this.slider

		s._focused = false;

		s.handle.className = "handle";

	},



	onmouseover:	function (e) {

		e = Slider.eventHandlers.getEvent(e, this);

		var s = this.slider;

		if (e.srcElement == s.handle)

			s.handle.className = "handle hover";

	},



	onmouseout:	function (e) {

		e = Slider.eventHandlers.getEvent(e, this);

		var s = this.slider;

		if (e.srcElement == s.handle && !s._focused)

			s.handle.className = "handle";

	},



	onmousedown:	function (e) {

		mouse_down = 1;

		e = Slider.eventHandlers.getEvent(e, this);

		var s = this.slider;

		if (s.element.focus)

			s.element.focus();



		Slider._currentInstance = s;

		var doc = s.document;



		if (doc.addEventListener) {

			doc.addEventListener("mousemove", Slider.eventHandlers.onmousemove, true);

			doc.addEventListener("mouseup", Slider.eventHandlers.onmouseup, true);

		}

		else if (doc.attachEvent) {

			doc.attachEvent("onmousemove", Slider.eventHandlers.onmousemove);

			doc.attachEvent("onmouseup", Slider.eventHandlers.onmouseup);

			doc.attachEvent("onlosecapture", Slider.eventHandlers.onmouseup);

			s.element.setCapture();

		}



		if (Slider.eventHandlers.getHandle(e)) {	// start drag

			Slider._sliderDragData = {

				screenX:	e.screenX,

				screenY:	e.screenY,

				dx:			e.screenX - s.handle.offsetLeft,

				dy:			e.screenY - s.handle.offsetTop,

				startValue:	s.getValue(),

				slider:		s

			};

		}

		else {

			var lineEl = Slider.eventHandlers.getLine(e);

			s._mouseX = e.offsetX + (lineEl ? s.line.offsetLeft : 0);

			s._mouseY = e.offsetY + (lineEl ? s.line.offsetTop : 0);

			s._increasing = null;

			s.ontimer();

		}

	},



	onmousemove:	function (e) {

		e = Slider.eventHandlers.getEvent(e, this);



		if (Slider._sliderDragData) {	// drag

			var s = Slider._sliderDragData.slider;



			var boundSize = s.getMaximum() - s.getMinimum();

			var size, pos, reset;



			if (s._orientation == "horizontal") {

				size = s.element.offsetWidth - s.handle.offsetWidth;

				pos = e.screenX - Slider._sliderDragData.dx;

				reset = Math.abs(e.screenY - Slider._sliderDragData.screenY) > 100;

			}

			else {

				size = s.element.offsetHeight - s.handle.offsetHeight;

				pos = s.element.offsetHeight - s.handle.offsetHeight -

					(e.screenY - Slider._sliderDragData.dy);

				reset = Math.abs(e.screenX - Slider._sliderDragData.screenX) > 100;

			}

			s.setValue(reset ? Slider._sliderDragData.startValue :

						s.getMinimum() + boundSize * pos / size);

			return false;

		}

		else {

			var s = Slider._currentInstance;

			if (s != null) {

				var lineEl = Slider.eventHandlers.getLine(e);

				s._mouseX = e.offsetX + (lineEl ? s.line.offsetLeft : 0);

				s._mouseY = e.offsetY + (lineEl ? s.line.offsetTop : 0);

			}

		}



	},



	onmouseup:	function (e) {

		mouse_down = 0;

		e = Slider.eventHandlers.getEvent(e, this);

		var s = Slider._currentInstance;

		var doc = s.document;

		if (doc.removeEventListener) {

			doc.removeEventListener("mousemove", Slider.eventHandlers.onmousemove, true);

			doc.removeEventListener("mouseup", Slider.eventHandlers.onmouseup, true);

		}

		else if (doc.detachEvent) {

			doc.detachEvent("onmousemove", Slider.eventHandlers.onmousemove);

			doc.detachEvent("onmouseup", Slider.eventHandlers.onmouseup);

			doc.detachEvent("onlosecapture", Slider.eventHandlers.onmouseup);

			s.element.releaseCapture();

		}



		if (Slider._sliderDragData) {	// end drag

			Slider._sliderDragData = null;

		}

		else {

			s._timer.stop();

			s._increasing = null;

		}

		Slider._currentInstance = null;

	},



	onkeydown:	function (e) {

		e = Slider.eventHandlers.getEvent(e, this);

		//var s = Slider.eventHandlers.getSlider(e);

		var s = this.slider;

		var kc = e.keyCode;

		switch (kc) {

			case 33:	// page up

				s.setValue(s.getValue() + s.getBlockIncrement());

				break;

			case 34:	// page down

				s.setValue(s.getValue() - s.getBlockIncrement());

				break;

			case 35:	// end

				s.setValue(s.getOrientation() == "horizontal" ?

					s.getMaximum() :

					s.getMinimum());

				break;

			case 36:	// home

				s.setValue(s.getOrientation() == "horizontal" ?

					s.getMinimum() :

					s.getMaximum());

				break;

			case 38:	// up

			case 39:	// right

				s.setValue(s.getValue() + s.getUnitIncrement());

				break;



			case 37:	// left

			case 40:	// down

				s.setValue(s.getValue() - s.getUnitIncrement());

				break;

		}



		if (kc >= 33 && kc <= 40) {

			return false;

		}

	},



	onkeypress:	function (e) {

		e = Slider.eventHandlers.getEvent(e, this);

		var kc = e.keyCode;

		if (kc >= 33 && kc <= 40) {

			return false;

		}

	},



	onmousewheel:	function (e) {

		e = Slider.eventHandlers.getEvent(e, this);

		var s = this.slider;

		if (s._focused) {

			s.setValue(s.getValue() + e.wheelDelta / 120 * s.getUnitIncrement());

			// windows inverts this on horizontal sliders. That does not

			// make sense to me

			return false;

		}

	}

};







Slider.prototype.classNameTag = "dynamic-slider-control",





Slider.prototype.setValue = function (v) {



	if(v > -1 && v < 10){

	this._range.setValue(v);

	this.input.value = this.getValue();

	}else{

		if(v == parseInt(v)){

			//document.getElementById('slider_info').innerHTML = 'Grab the slider or click the plan name to make a selection!';

			//setTimeout(s.onchange, 5000);

		}

	}



};









Slider.prototype.getValue = function () {

	return this._range.getValue();

};



Slider.prototype.setMinimum = function (v) {

	this._range.setMinimum(v);

	this.input.value = this.getValue();

};



Slider.prototype.getMinimum = function () {

	return this._range.getMinimum();

};



Slider.prototype.setMaximum = function (v) {

	this._range.setMaximum(v);

	this.input.value = this.getValue();

};



Slider.prototype.getMaximum = function () {

	return this._range.getMaximum();

};



Slider.prototype.setUnitIncrement = function (v) {

	this._unitIncrement = v;

};



Slider.prototype.getUnitIncrement = function () {

	return this._unitIncrement;

};



Slider.prototype.setBlockIncrement = function (v) {

	this._blockIncrement = v;

};



Slider.prototype.getBlockIncrement = function () {

	return this._blockIncrement;

};



Slider.prototype.getOrientation = function () {

	return this._orientation;

};



Slider.prototype.setOrientation = function (sOrientation) {

	if (sOrientation != this._orientation) {

		if (Slider.isSupported && this.element) {

			// add class name tag to class name

			this.element.className = this.element.className.replace(this._orientation,

									sOrientation);

		}

		this._orientation = sOrientation;

		this.recalculate();



	}

};



Slider.prototype.recalculate = function() {

	if (!Slider.isSupported || !this.element) return;



	var w = this.element.offsetWidth;

	var h = this.element.offsetHeight;

	var hw = this.handle.offsetWidth;

	var hh = this.handle.offsetHeight;

	var lw = this.line.offsetWidth;

	var lh = this.line.offsetHeight;



	// this assumes a border-box layout



	if (this._orientation == "horizontal") {

		this.handle.style.left = (w - hw) * (this.getValue() - this.getMinimum()) /

			(this.getMaximum() - this.getMinimum()) + "px";

		this.handle.style.top = (h - hh) / 2 + "px";



		this.line.style.top = (h - lh) / 2 + "px";

		this.line.style.left = hw / 2 + "px";

		//this.line.style.right = hw / 2 + "px";

		this.line.style.width = Math.max(0, w - hw - 2)+ "px";

		this.line.firstChild.style.width = Math.max(0, w - hw - 4)+ "px";

	}

	else {

		this.handle.style.left = (w - hw) / 2 + "px";

		this.handle.style.top = h - hh - (h - hh) * (this.getValue() - this.getMinimum()) /

			(this.getMaximum() - this.getMinimum()) + "px";



		this.line.style.left = (w - lw) / 2 + "px";

		this.line.style.top = hh / 2 + "px";

		this.line.style.height = Math.max(0, h - hh - 2) + "px";	//hard coded border width

		//this.line.style.bottom = hh / 2 + "px";

		this.line.firstChild.style.height = Math.max(0, h - hh - 4) + "px";	//hard coded border width

	}

};



Slider.prototype.ontimer = function () {

	var hw = this.handle.offsetWidth;

	var hh = this.handle.offsetHeight;

	var hl = this.handle.offsetLeft;

	var ht = this.handle.offsetTop;



	if (this._orientation == "horizontal") {

		if (this._mouseX > hl + hw &&

			(this._increasing == null || this._increasing)) {

			this.setValue(this.getValue() + this.getBlockIncrement());

			this._increasing = true;

		}

		else if (this._mouseX < hl &&

			(this._increasing == null || !this._increasing)) {

			this.setValue(this.getValue() - this.getBlockIncrement());

			this._increasing = false;

		}

	}

	else {

		if (this._mouseY > ht + hh &&

			(this._increasing == null || !this._increasing)) {

			this.setValue(this.getValue() - this.getBlockIncrement());

			this._increasing = false;

		}

		else if (this._mouseY < ht &&

			(this._increasing == null || this._increasing)) {

			this.setValue(this.getValue() + this.getBlockIncrement());

			this._increasing = true;

		}

	}



	this._timer.start();

};