bsnSlider = function (e, opt)
{
	var slider =
	{
		inp : null,
		widgetw: 200,
		handle : null,
		handlew : 10,
		valfield : null, 
		dragstart : 0,
		mxstart : 0,
		mx : 0,
		nmin : 0,
		nmax : 190,
		vmin : 0,
		vmax : 100,
		decimals : 2,
		step: 0,
		snap: 0,
		suffix: "",
		handleOnChange: null,
		handleOnRelease: null,
		enabled: true,
	
		init : function ( e, opt )
		{
			// parse options
			//
			if (opt)
			{
				this.widgetw = opt.widgetw ? opt.widgetw : this.widgetw;
				this.vmin = opt.vmin ? opt.vmin : this.vmin;
				this.vmax = opt.vmax ? opt.vmax : this.vmax;
				this.step = opt.step ? opt.step : this.step;
				this.decimals = opt.decimals ? opt.decimals : this.decimals;
				this.suffix = opt.suffix ? opt.suffix : this.suffix;
				this.handleOnChange = opt.onChange ? opt.onChange : this.handleOnChange;
				this.handleOnRelease = opt.onRelease ? opt.onRelease : this.handleOnRelease;
			}
			
			this.nmax = this.widgetw - this.handlew;
			
			if (this.step)
			{
				// set snap
				this.snap = Math.round(  (this.nmax - this.nmin) / ((this.vmax - this.vmin) / this.step)  );
			}
		
			// save ref to & hide input
			//
			this.inp = $_(e)._;
			var sid = $_(e)._.id + "_slider";
			$_(e).hide().parent().appendElement( "div", {className:"bsnSlider", id:sid}, "<div class='handle'></div><div class='value'></div>" );
		
			var h = this.handle = $_(sid).childs(0)._;
			h.style["left"] = "0px";
			
			
			// get valfield
			//
			this.valfield = $_(sid).childs(1)._;
			
			
			// set start value
			//
			this.setHandleFromValue( this.inp.value );
		},
		
		
		
		enable : function ()
		{
			var p = this;
			this.enabled = true;
			this.handle.onmousedown = function (e)
			{
				p.startDrag(e);
				return false;
			};
		}	,



		disable : function ()
		{
			var p = this;
			this.enabled = false;
			this.handle.onmousedown = null;
		},
	
	
	
		startDrag : function (e)
		{
			if (!e) var e = window.event;
			this.mxstart = this.mx = e.pageX ? e.pageX : e.clientX;
			this.dragstart = this.getHandleX() - 0;
		
			var p = this;
			document.onmousemove = function (e) { p.onMMove(e) };
			document.onmouseup = function (e)
			{
				p.stopDrag(e);
			};
		},
	
	
	
		onMMove : function (e)
		{
			if (!e) var e = window.event;
			this.mx = e.pageX ? e.pageX : e.clientX;
			
			var x = this.snap  ?  Math.round((this.dragstart + this.mx - this.mxstart)/this.snap)*this.snap  :  this.dragstart + this.mx - this.mxstart
			this.setHandleX( x );
			this.setValueFromHandle();
		},
	
	
	
		stopDrag : function (e)
		{
			document.onmousemove = null;
			document.onmouseup = null;
			
			this.onRelease();
		},
	
	
	
		getHandleX : function ()
		{
			return this.handle.style['left'].substr( 0, this.handle.style['left'].length-2 );
		},
	
	
	
		setHandleX : function (x)
		{
			x = Math.max( Math.min( x, this.nmax ), this.nmin );
			this.handle.style["left"] = x + "px";
		},
	
	
	
		setValueFromHandle : function ()
		{
			var perc = this.getHandleX() / this.nmax;
			var val = this.vmin + ((this.vmax-this.vmin)*perc);
			val = this.step ? Math.round(val/this.step)*this.step : val;
			val = this.doDecimals(val);
		
			this.inp.value = val;
		
			this.valfield.innerHTML = "<span>"+val+this.suffix+"</span>";
			
			this.onChange();
		},
	
	
	
		setHandleFromValue : function (val)
		{
			// limit & decimals
			//
			Math.min( Math.max(val, this.vmin), this.vmax );
			val = this.step ? Math.round(val/this.step)*this.step : val;
			val = this.doDecimals( val );
		
			this.inp.value = val;
		
			var perc = (val-this.vmin) / (this.vmax-this.vmin);
			this.setHandleX( Math.round( (this.nmax-this.nmin)*perc ) );
		
			this.valfield.innerHTML = "<span>"+val+this.suffix+"</span>";
		},
	
	
	
		doDecimals : function (val)
		{
			if (this.decimals)
			{
				val = Math.round(val*(this.decimals*10))/(this.decimals*10);
			}
			return val;
		},
		
		
		
		onChange : function()
		{
			if (this.handleOnChange)
				this.handleOnChange( {obj:this, value:this.valfield.value} );
		},



		onRelease : function()
		{
			if (this.handleOnRelease)
				this.handleOnRelease( {obj:this, value:this.valfield.value} );
		}
	};
	
	
	
	slider.init(e,opt);
	
	
	
	return slider;
}



