// Title: tigra slider control
// Description: See the demo at url
// URL: http://www.softcomplex.com/products/tigra_slider_control/
// Version: 1.0 (commented source)
// Date: 02/15/2006
// Tech. Support: http://www.softcomplex.com/forum/
// Notes: This script is free. Visit official site for further details.
// These patterns I picked up from a bit of web searching and for all I know
// could be quite incorrect. Please email dave@ruske.net if there are other
// patterns that should be supported.
var patterns = new Array ( 
	"###,###,###,###",					// US/British
	"###.###.###.###",					// German
	"### ### ### ###",					// French
	"###'###'###'###",					// Swiss
	"#,##,##,##,##,###",				// Indian
	"####\u5104 ####\u4E07 ####", 		// Japanese/Chinese
	"############"						// no formatting
	);

// A little function to take an integer string, strip out current formatting,
// and reformat it according to a pattern string. '#' characters in the pattern
// are substituted with digits from the integer string, other pattern characters
// are output literally into the returned string.
function formatInteger( integer, pattern )
{
	var result = '';
	integer = integer + '';

	integerIndex = integer.length - 1;
	patternIndex = pattern.length - 1;

	while ( (integerIndex >= 0) && (patternIndex >= 0) )
	{
		var digit = integer.charAt( integerIndex );
		integerIndex--;
		
		// Skip non-digits from the source integer (eradicate current formatting).
		if ( (digit < '0') || (digit > '9') )  continue;
	
		// Got a digit from the integer, now plug it into the pattern.
		while ( patternIndex >= 0 )
		{
			var patternChar = pattern.charAt( patternIndex );
			patternIndex--;
			
			// Substitute digits for '#' chars, treat other chars literally.
			if ( patternChar == '#' )
			{
				result = digit + result;
				break;
			}
			else
			{
				result = patternChar + result;
			}
		}
	}
	
	return result;
}

function slider (a_init, a_tpl, s_target) {

	this.f_setValue  = f_sliderSetValue;
	this.f_getPos    = f_sliderGetPos;
	
	if (this.n_style==null)
	{
		this.n_style = 'border: 0;background-image:url(' + this.s_imgControl + ');';
	}
	if (this.s_style==null)
	{
		this.s_style = '';
	}
	var b_inline = true;
	if (s_target!=null)
	{
		b_inline = false;
	}

	// register in the global collection	
	if (!window.A_SLIDERS)
		window.A_SLIDERS = [];
	this.n_id = window.A_SLIDERS.length;
	window.A_SLIDERS[this.n_id] = this;

	// save config parameters in the slider object
	var s_key;
	if (a_tpl)
		for (s_key in a_tpl)
			this[s_key] = a_tpl[s_key];
	for (s_key in a_init)
		this[s_key] = a_init[s_key];


		this.n_pix2value = this.n_pathLength / (this.n_maxValue - this.n_minValue);
		if (this.n_value == null)
			this.n_value = this.n_minValue;


	// generate the control's HTML
	if (b_inline)
	{
		document.write(
		'<div style="width:' + this.n_controlWidth + 'px;height:' + this.n_controlHeight + 'px;' + this.n_style + '" id="sl' + this.n_id + 'base">' +
		'<img src="' + this.s_imgSlider + '" width="' + this.n_sliderWidth + '" height="' + this.n_sliderHeight + '" border="0" style="' + this.s_style + 'position:relative;left:' + this.n_pathLeft + 'px;top:' + this.n_pathTop + 'px;z-index:' + this.n_zIndex + ';cursor:hand;visibility:hidden;" name="sl' + this.n_id + 'slider" id="sl' + this.n_id + 'slider" onmousedown="return f_sliderMouseDown(' + this.n_id + ')"/></div>'
		);
	}
	else
	{
		document.getElementById(s_target).innerHTML += 
		'<div style="width:' + this.n_controlWidth + 'px;height:' + this.n_controlHeight + 'px;' + this.n_style + '" id="sl' + this.n_id + 'base">' +
		'<img src="' + this.s_imgSlider + '" width="' + this.n_sliderWidth + '" height="' + this.n_sliderHeight + '" border="0" style="' + this.s_style + 'position:relative;left:' + this.n_pathLeft + 'px;top:' + this.n_pathTop + 'px;z-index:' + this.n_zIndex + ';cursor:hand;visibility:hidden;" name="sl' + this.n_id + 'slider" id="sl' + this.n_id + 'slider" onmousedown="return f_sliderMouseDown(' + this.n_id + ')"/></div>'
		;
	}
	
	this.e_base   = get_element('sl' + this.n_id + 'base');
	this.e_slider = get_element('sl' + this.n_id + 'slider');
	
	// safely hook document/window events
	if (document.onmousemove != f_sliderMouseMove) {
		window.f_savedMouseMove = document.onmousemove;
		document.onmousemove = f_sliderMouseMove;
	}
	if (document.onmouseup != f_sliderMouseUp) {
		window.f_savedMouseUp = document.onmouseup;
		document.onmouseup = f_sliderMouseUp;
	}
	// preset to the value in the input box if available
	var e_input = this.s_form == null
		? get_element(this.s_name)
		: document.forms[this.s_form]
			? document.forms[this.s_form].elements[this.s_name]
			: null;
	
	this.f_setValue(e_input && e_input.value != '' ? e_input.value : null, 1);
	this.e_slider.style.visibility = 'visible';
	if (this.n_pathLeft==-17)
	{
		f_sliderMMObj(this.n_id,-17,0);
	}
}

function f_sliderSetValue (n_value, b_noInputCheck) {
	if (n_value == null)
		n_value = this.n_value == null ? this.n_minValue : this.n_value;
	if (isNaN(n_value))
		return false;

	// round to closest multiple if step is specified
	if (this.n_step)
		n_value = Math.round((n_value - this.n_minValue) / this.n_step) * this.n_step + this.n_minValue;


	// smooth out the result
	if (n_value % 1)
		n_value = Math.round(n_value * 1e5) / 1e5;

	
	if (n_value < this.n_minValue)
		n_value = this.n_minValue;
	if (n_value > this.n_maxValue)
		n_value = this.n_maxValue;

		
	var partner = false;
	var partnerd = '<=';
	if (this.n_leftpartner!=null)
	{
		partner = window.A_SLIDERS[this.n_leftpartner];
		partnerd = '<';
	}
	if (this.n_rightpartner!=null)
	{
		partner = window.A_SLIDERS[this.n_rightpartner];
		partnerd = '>';
	}
	if (partner)
	{
		if (eval('' + partner.n_value + partnerd + n_value + '')==false)
		{
			eval('n_value=' + partner.n_value);
		}
	}

	if (this.n_initialized == undefined)
	{
		if (partnerd=='<')
		{
			if (this.n_value!=this.n_maxValue)
			{		
				n_value = this.n_maxValue * positionSlope(this.n_value,this.n_minValue,this.n_maxValue,7,1.5);
			}
		}
		else
		{
			if (this.n_value!=this.n_minValue)
			{
				n_value = this.n_maxValue * positionSlope(this.n_value,this.n_minValue,this.n_maxValue,7,.5);
			}
		}
		this.n_initialized = true;
	}
	this.n_value = n_value;
	
	// move the slider
	if (this.b_vertical)
		this.e_slider.style.top  = (this.n_pathTop + this.n_pathLength - Math.round((n_value - this.n_minValue) * this.n_pix2value)) + 'px';
	else
		this.e_slider.style.left = (this.n_pathLeft + Math.round((n_value - this.n_minValue) * this.n_pix2value)) + 'px';


			if (this.b_log==true)
			{

				var cWidth = this.b_vertical
							? this.n_pathLength - parseInt(this.e_slider.style.top)
							: parseInt(this.e_slider.style.left) - this.n_pathLeft;
				var mWidth = this.n_pathLength;
				var mPercent = (cWidth / mWidth);

				var mValue = slopePosition(mPercent,this.n_minValue,this.n_maxValue,7);

				n_value = this.n_minValue  + (this.n_maxValue - this.n_minValue) * mValue;

				// round to closest multiple if step is specified
				if (this.n_step)
					n_value = Math.round((n_value - this.n_minValue) / this.n_step) * this.n_step + this.n_minValue;

				// smooth out the result
				if (n_value % 1)
					n_value = Math.round(n_value * 1e5) / 1e5;

			}

	// save new value
	var e_input;
	if (this.s_form == null) {
		e_input = get_element(this.s_name);
		if (!e_input)
			return b_noInputCheck ? null : f_sliderError(this.n_id, "Can not find the input with ID='" + this.s_name + "'.");
	}
	else {
		var e_form = document.forms[this.s_form];
		if (!e_form)
			return b_noInputCheck ? null : f_sliderError(this.n_id, "Can not find the form with NAME='" + this.s_form + "'.");
		e_input = e_form.elements[this.s_name];
		if (!e_input)
			return b_noInputCheck ? null : f_sliderError(this.n_id, "Can not find the input with NAME='" + this.s_name + "'.");
	}
	e_input.value = n_value;

	e_input = null;
	if (this.s_display != null)
	{
		e_input = document.getElementById(this.s_display);
		if (this.b_formatinteger!=null && this.b_formatinteger==true)
		{
			if (e_input!=null) e_input.innerHTML = formatInteger(n_value,'###,###,###,###');
		}
		else
		{
			if (e_input!=null) e_input.innerHTML = n_value;
		}
	}

}

function positionSlope(value,min,max,p,add)
{
	if (min==0)
	{
		min = 1;
	}
	if (max==0)
	{
		max = 1;
	}
	
	var r = Math.round(max/min);
	var x = (value-min) / (max-min);
	var li = 0;
	var si = 0.00;
	if (value > r)
	{
		si = 40;
	}
	for (i=si;i<100.00;i=i+1)
	{
		y = slopePosition(i/100.00,min,max,p);
		if (y>x)
		{
			i = 101.00;
		}
		else
		{
			ly = y;
			li = i
		}
	}
	return (li+add)/100.00;
}
function slopePosition(percentage,min,max,power)
{
	if (min==0)
	{
		min = 1;
	}
	if (max==0)
	{
		max = 1;
	}
	var ratio = Math.round(max/min);
	return (percentage / ratio) + Math.pow(percentage,power);
}

// get absolute position of the element in the document
function f_sliderGetPos (b_vertical, b_base) {
	var n_pos = 0,
		s_coord = (b_vertical ? 'Top' : 'Left');
	var o_elem = o_elem2 = b_base ? this.e_base : this.e_slider;
	
	while (o_elem) {
		n_pos += o_elem["offset" + s_coord];
		o_elem = o_elem.offsetParent;
	}
	o_elem = o_elem2;

	var n_offset;
	while (o_elem.tagName != "BODY") {
		n_offset = o_elem["scroll" + s_coord];
		if (n_offset)
			n_pos -= o_elem["scroll" + s_coord];
		o_elem = o_elem.parentNode;
	}
	return n_pos;
}

function f_sliderMouseDown (n_id) {
	window.n_activeSliderId = n_id;
	return false;
}

function f_sliderMouseUp (e_event, b_watching) {
	if (window.n_activeSliderId != null) {
		var o_slider = window.A_SLIDERS[window.n_activeSliderId];
		var offset = 0;

		if (o_slider.n_collisionEdge=='right')
		{
			offset = o_slider.n_sliderWidth;
		}
		else
		{
			offset = 0;
		}

		o_slider.f_setValue(o_slider.n_minValue + (o_slider.b_vertical
			? (o_slider.n_pathLength - parseInt(o_slider.e_slider.style.top) + o_slider.n_pathTop)
			: (parseInt(o_slider.e_slider.style.left) - o_slider.n_pathLeft)) / o_slider.n_pix2value);			

		if (!b_watching && o_slider.f_onmouseup != null)
		{
			eval(o_slider.f_onmouseup);
		}

		if (b_watching)	return;
		window.n_activeSliderId = null;
	}
	if (window.f_savedMouseUp)
	{
		return window.f_savedMouseUp(e_event);
	}

}

function f_sliderMouseMove (e_event) {

	if (!e_event && window.event) e_event = window.event;

	// save mouse coordinates
	if (e_event) {
		window.n_mouseX = e_event.clientX + f_scrollLeft();
		window.n_mouseY = e_event.clientY + f_scrollTop();
	}

	// check if in drag mode
	if (window.n_activeSliderId != null) {
		var o_slider = window.A_SLIDERS[window.n_activeSliderId];

		var n_pxOffset;
		if (o_slider.b_vertical) {
			var n_sliderTop = window.n_mouseY - o_slider.n_sliderHeight / 2 - o_slider.f_getPos(1, 1) - 3;
			// limit the slider movement
			if (n_sliderTop < o_slider.n_pathTop)
				n_sliderTop = o_slider.n_pathTop;
			var n_pxMax = o_slider.n_pathTop + o_slider.n_pathLength;
			if (n_sliderTop > n_pxMax)
				n_sliderTop = n_pxMax;
			o_slider.e_slider.style.top = n_sliderTop + 'px';
			n_pxOffset = o_slider.n_pathLength - n_sliderTop + o_slider.n_pathTop;
		}
		else {
			var n_sliderLeft = window.n_mouseX - o_slider.n_sliderWidth / 2 - o_slider.f_getPos(0, 1) - 3;
			// limit the slider movement
			if (n_sliderLeft < o_slider.n_pathLeft)
				n_sliderLeft = o_slider.n_pathLeft;
			var n_pxMax = o_slider.n_pathLeft + o_slider.n_pathLength;
			if (n_sliderLeft > n_pxMax)
				n_sliderLeft = n_pxMax;



			o_slider.e_slider.style.left = n_sliderLeft + 'px';
			n_pxOffset = n_sliderLeft - o_slider.n_pathLeft;

		}
		if (o_slider.b_watch)
			 f_sliderMouseUp(e_event, 1);

		return false;
	}
	
	if (window.f_savedMouseMove)
		return window.f_savedMouseMove(e_event);
}

function f_sliderMMObj(slideri,nmX,nmY)
{
		var o_slider = window.A_SLIDERS[slideri];
		var n_pxOffset;
		if (o_slider.b_vertical) {
			var n_sliderTop = nmY - o_slider.n_sliderHeight / 2 - o_slider.f_getPos(1, 1) - 3;
			// limit the slider movement
			if (n_sliderTop < o_slider.n_pathTop)
				n_sliderTop = o_slider.n_pathTop;
			var n_pxMax = o_slider.n_pathTop + o_slider.n_pathLength;
			if (n_sliderTop > n_pxMax)
				n_sliderTop = n_pxMax;
			o_slider.e_slider.style.top = n_sliderTop + 'px';
			n_pxOffset = o_slider.n_pathLength - n_sliderTop + o_slider.n_pathTop;
		}
		else {
			var n_sliderLeft = nmX - o_slider.n_sliderWidth / 2 - o_slider.f_getPos(0, 1) - 3;
			// limit the slider movement
			if (n_sliderLeft < o_slider.n_pathLeft)
				n_sliderLeft = o_slider.n_pathLeft;
			var n_pxMax = o_slider.n_pathLeft + o_slider.n_pathLength;
			if (n_sliderLeft > n_pxMax)
				n_sliderLeft = n_pxMax;
			o_slider.e_slider.style.left = n_sliderLeft + 'px';
			n_pxOffset = n_sliderLeft - o_slider.n_pathLeft;
		}
		return false;
}


// get the scroller positions of the page
function f_scrollLeft() {
	return f_filterResults (
		window.pageXOffset ? window.pageXOffset : 0,
		document.documentElement ? document.documentElement.scrollLeft : 0,
		document.body ? document.body.scrollLeft : 0
	);
}
function f_scrollTop() {
	return f_filterResults (
		window.pageYOffset ? window.pageYOffset : 0,
		document.documentElement ? document.documentElement.scrollTop : 0,
		document.body ? document.body.scrollTop : 0
	);
}
function f_filterResults(n_win, n_docel, n_body) {
	var n_result = n_win ? n_win : 0;
	if (n_docel && (!n_result || (n_result > n_docel)))
		n_result = n_docel;
	return n_body && (!n_result || (n_result > n_body)) ? n_body : n_result;
}

function f_sliderError (n_id, s_message) {
	alert("Slider #" + n_id + " Error:\n" + s_message);
	window.n_activeSliderId = null;
}

get_element = document.all ?
	function (s_id) { return document.all[s_id] } :
	function (s_id) { return document.getElementById(s_id) };


