//
// Copyright (c) Art. Lebedev Studio | http://www.artlebedev.ru/
// Author - Leechy | leechy@design.ru
//


/*********************/
/*     variables     */
/*********************/


var sSliderDefaultMarkContent = '&nbsp;';
var sSliderDefaultPointerContent = '<div class="pointer-image"></div>';

// orientation
var sSliderVertical = 'vertical';
var sSliderHorizontal = 'horizontal';

// movement
var sSliderMoveFree = 'free';
var sSliderMoveSnap = 'snap';
var sSliderMoveMarks = 'marks-only';
	// movement types sorted by importance (increasing)
var aSliderMovement = [ sSliderMoveFree, sSliderMoveSnap, sSliderMoveMarks ];

// marks
var sSliderMarksEven = 'even';
var sSliderMarksProportional = 'proportional';
var sSliderMarkClass = 'mark';
var sSliderMarkSeriesClass = 'marks';
var sSliderHTMLMarks = 'marks-in-html';

var sSliderMarkPositionPrefix = 'p';

var iSliderMarkDefaultStep = 1;
var sSliderMarkStepPrefix = 's';

// other
var sSliderClassValuesDivider = '-';

// limits
var iSliderDefaultMin = 0;
var iSliderDefaultMax = 100;
var sSliderClassMinValue = 'min';
var sSliderClassMaxValue = 'max';
var sSliderLimits = sSliderClassMinValue + ' ' + sSliderClassMaxValue;



// generated content classes
var sSliderContainerCenterDivClass = 'centered';
var sSliderContainerInfoDivClass = 'info';

var sSliderMarksGridClass = 'grid';
var sSliderDefaultMarkClass = 'mark';
var sSliderStartMarkClass = 'start';
var sSliderEndMarkClass = 'end';
var sSliderPointersGridClass = 'pointers';
var sSliderPointerClass = 'pointer';
var sSliderCoverClass = 'cover';


// and even more
var aFormElemNames = ['input', 'select'];


// sliders
var sSliderIDPrefix = 'sldr';
var sSliderPointerIDPrefix = 'pntr';
var aSliders = new Array();
var iSliders = 0;


/**************************/
/*     slider objects     */
/**************************/

function SliderMark(
	sSliderID, iPointerID,
	bDisabled, bSelected, sValue, sPosValue,
	sLabelText, oElem, sClassName, oMarkElem, iValue, iPosValue,
	iStep
) {
	this.sSliderID = sSliderID;
	this.iPointer = iPointerID;

	this.bDisabled = bDisabled;
	this.bSelected = bSelected;
	this.sValue = sValue;
	this.sPosValue = sPosValue;
	this.iValue = ( iValue )? iValue : 0;
	this.iPosValue = ( iPosValue )? iPosValue : 0;
	this.iPos = 0;

	this.sText = sLabelText;
	this.oElem = oElem;
	var sElemClass = ( oElem )? oElem.className : null;
	this.sClassName = sClassName || sElemClass;
	this.oMarkElem = oMarkElem;

	this.iStep = ( iStep )? iStep : iSliderMarkDefaultStep;

	return this;
}

function SliderPointer(
	sSliderID, sPointerID, oElem, oPointerElem,
	sMovement, sMin, sMax, sValue
) {
	this.sSliderID = sSliderID;
	this.sPointerID = sPointerID;
	this.oElem = oElem;
	this.oPointerElem = oPointerElem;

	this.sMovement = sMovement;
	this.iMin = ( !isNaN( parseInt( sMin ) ) )? parseInt( sMin ) : null;
	this.iMax = ( !isNaN( parseInt( sMax ) ) )? parseInt( sMax ) : null;
	this.sValue = sValue;
	this.iValue = ( !isNaN( parseInt( sValue ) ) )? parseInt( sValue ) : 0;
	this.iPos = 0;

	return this;
}

function Slider( sSliderID, sOrientation, aPointers, aMarks, iMin, iMax ) {
	this.sSliderID = sSliderID;
	this.sOrientation = sOrientation;
	this.aPointers = aPointers;
	this.aMarks = aMarks;
	this.iMin = iMin;
	this.iMax = iMax;
	return this;
}



/********************************/
/*     marks class analysis     */
/********************************/

function getSliderMarkValue( aMarkValues ) {
	return aMarkValues[1] || aMarkValues[0];
}

function marksSort( aFirst, aSecond ) {
	var iFirst = aFirst[1] || aFirst[0];
	var iSecond = aSecond[1] || aSecond[0];
	return ( iSecond - iFirst );
}

function createMarksFromClassNames( oSlider, sSliderID, sClassNames, iPointerID, aMarks ) {
	/* get pointer limits */
	var aLimits = getNamedValuesArray( sSliderLimits, sClassNames );

	if ( !matchClass( oSlider, sSliderHTMLMarks ) ) {
		/* ordinary ticks */
		var aMarksValues = getValuesArrayByName( sSliderMarkClass, sClassNames );
		for ( var i in aMarksValues ) {
			var iStep = getIntValueByPrefix( aMarksValues[i], sSliderMarkStepPrefix );
			if ( !iStep || isNaN( iStep ) || iStep < 1 ) iStep = iSliderMarkDefaultStep;
			var sPosValue = getIntValueByPrefix( aMarksValues[i], sSliderMarkPositionPrefix );
			if ( !sPosValue || isNaN( sPosValue ) ) sPosValue = aMarksValues[i][1];
			aMarks[ aMarks.length ] = new SliderMark(
				sSliderID, iPointerID,
				false, false, aMarksValues[i][0], sPosValue,
				aMarksValues[i][0], null, aMarksValues[i][2], null, null, null,
				iStep
			);
		}
		

		/* periodical ticks */
		var iMinValue = parseInt( aLimits[ sSliderClassMinValue ] );
		var iMaxValue = parseInt( aLimits[ sSliderClassMaxValue ] );
		if ( !isNaN( iMinValue ) && !isNaN( iMaxValue ) ) {
			aMarksValues = getValuesArrayByName( sSliderMarkSeriesClass, sClassNames );
			if ( aMarksValues.length ) {
				aMarksValues.sort( marksSort );
				// calculating step (greatest common divisor)
				var aValues = new Array();
				for ( var i in aMarksValues ) aValues[i] = getSliderMarkValue( aMarksValues[i] );
				var iGCD = parseInt( getGCD( aValues ) );
				// creating ticks
				for ( var i = iMinValue; i <= iMaxValue; i += iGCD ) {
					for ( var j = 0; j < aMarksValues.length; j++ ) {
						if ( i % aValues[j] == 0 ) {
							var sValue = i;
							var sLabelText = aMarksValues[j][0]
							aMarks[ aMarks.length ] = new SliderMark(
								sSliderID, iPointerID,
								false, false, sValue, sValue,
								sLabelText, null, aMarksValues[j][2], null
							);
							break;
						}
					}
				}
			}
		}
	}
}



/*****************************/
/*     inputs dissection     */
/*****************************/

// select
function dissectSelect( oSlider, sSliderID, oSelect, aPointers, aMarks ) {
	/* create pointer */
	var iPointerID = aPointers.length;
	aPointers[ iPointerID ] = new SliderPointer(
		sSliderID, sSliderID + sSliderPointerIDPrefix + iPointerID, oSelect, null,
		sSliderMoveMarks, null, null, oSelect.options[ oSelect.selectedIndex ].value
	)

	/* create marks */
	for ( var i = 0; i < oSelect.options.length; i++ ) {
		aMarks[ aMarks.length ] = new SliderMark(
			sSliderID, iPointerID,
			oSelect.options[i].disabled, oSelect.options[i].selected, oSelect.options[i].value, oSelect.options[i].value,
			oSelect.options[i].text, oSelect.options[i], oSelect.options[i].className, null
		);
	}
}


// input[text]
function dissectTextInput( oSlider, sSliderID, oInput, aPointers, aMarks ) {
	/* get pointer limits */
	var aLimits = getNamedValuesArray( sSliderLimits, oInput.className );

	/* get movement type */
	var sMovement = sSliderMoveFree;
	var aParents = [ oSlider, oInput ];
	for ( var i in aParents ) for ( var j in aSliderMovement )
		if ( matchClass( aParents[i], aSliderMovement[j] ) ) sMovement = aSliderMovement[j];

	/* create pointer */
	var iPointerID = aPointers.length;
	aPointers[ iPointerID ] = new SliderPointer(
		sSliderID, sSliderID + sSliderPointerIDPrefix + iPointerID, oInput, null,
		sMovement, aLimits['min'], aLimits['max'], oInput.value
	)
	
	/* get marks from class names */
	createMarksFromClassNames( oSlider, sSliderID, oInput.className, iPointerID, aMarks );
}


// input[radio]
function dissectRadioInput( oSlider, sSliderID, oInput, aRadioInputs, aPointers, aMarks ) {
	if ( !aRadioInputs[ oInput.name ] ) {
		aRadioInputs[ oInput.name ] = aPointers.length;
		var iPointerID = aPointers.length;
		aPointers[ aRadioInputs[ oInput.name ] ] = new SliderPointer(
			sSliderID, sSliderID + sSliderPointerIDPrefix + iPointerID, oInput, null,
			sSliderMoveMarks, null, null, 0
		)
	}
	/* get text for mark label... from 'label' element */
	var sLabelText = '';
	if ( oInput.id ) {
		for ( var iLabelIdx = 0; ( oLabelElem = oSlider.getElementsByTagName('label')[iLabelIdx] ); iLabelIdx++ )
			if ( oLabelElem.getAttribute('for') == oInput.id ) { sLabelText = getTextValue( oLabelElem ); break; }
	}
	aMarks[ aMarks.length ] = new SliderMark(
		sSliderID, oInput,
		oInput.disabled, oInput.checked, oInput.value, oInput.value,
		sLabelText, oInput, oInput.className, null
	)
	/* set pointer value */
	if ( oInput.checked && aPointers[ aRadioInputs[ oInput.name ] ] )
		aPointers[ aRadioInputs[ oInput.name ] ].sValue = oInput.value;
}


/***************************/
/*     slider creation     */
/***************************/

function createSlider( oSlider ) {
	/* ID */
	var sSliderID = sSliderIDPrefix + iSliders;

	/* orientation */
	var sOrientation = ( matchClass( oSlider, sSliderVertical ) )? sSliderVertical : sSliderHorizontal;

	/* pointers and ticks */
	var aPointers = new Array();
	var aMarks = new Array();

	/* get slider limits */
	var aLimits = getNamedValuesArray( sSliderLimits, oSlider.className );
	var iMin = aLimits[ sSliderClassMinValue ];
	var iMax = aLimits[ sSliderClassMaxValue ];

	var aRadioInputs = new Array();

	/* analize inputs */
	for ( var i = 0; i < aFormElemNames.length; i++ ) {
		for ( var iElemIdx = 0; ( oFormElem = oSlider.getElementsByTagName( aFormElemNames[i] )[iElemIdx] ); iElemIdx++ ) {
			if ( aFormElemNames[i] == 'select' ) {
				dissectSelect( oSlider, sSliderID, oFormElem, aPointers, aMarks );
			} else if ( aFormElemNames[i] == 'input' && oFormElem.type.toLowerCase() == 'text' ) {
				dissectTextInput( oSlider, sSliderID, oFormElem, aPointers, aMarks );
			} else if ( aFormElemNames[i] == 'input' && oFormElem.type.toLowerCase() == 'radio' ) {
				dissectRadioInput( oSlider, sSliderID, oFormElem, aRadioInputs, aPointers, aMarks );
			}
		}
	}
	/* get marks from class names */
	createMarksFromClassNames( oSlider, sSliderID, oSlider.className, null, aMarks );

	/* create slider object */
	aSliders[ sSliderID ] = new Slider( sSliderID, sOrientation, aPointers, aMarks, iMin, iMax );
	iSliders++;

	/* create marks */
	var oMarks = buildSliderMarks( aSliders[ sSliderID ] );
	if ( oMarks ) oSlider.appendChild( oMarks );

	/* create pointers */
	var oPointers = buildSliderPointers( aSliders[ sSliderID ] );
	if ( oPointers ) oSlider.appendChild( oPointers );

	/* create 'cover' */
	var oCover = document.createElement('div');
	oCover.className = sSliderCoverClass;

	oCover.onmousedown = sliderMouseDown;
	oCover.onkeydown = sliderKeyDown;

	oSlider.appendChild( oCover );

//	oCover.tabIndex = 0;
	oCover.id = sSliderID;

	oSlider.unselectable = true;
}


// building marks
function compareSliderMarksPosValues( oMarkA, oMarkB ) {
	return oMarkA.iPosValue - oMarkB.iPosValue;
}

function findSliderMarkPosValue( oMark ) {
	if ( oMark.sPosValue && !isNaN( parseInt( oMark.sPosValue ) ) ) return parseInt( oMark.sPosValue );
	if ( oMark.sValue && !isNaN( parseInt( oMark.sValue ) ) ) return parseInt( oMark.sValue );
	return null;
}

function findSliderMarkValue( oMark ) {
	if ( oMark.sValue && !isNaN( parseInt( oMark.sValue ) ) ) return parseInt( oMark.sValue );
	if ( oMark.sPosValue && !isNaN( parseInt( oMark.sPosValue ) ) ) return parseInt( oMark.sPosValue );
	return null;
}

function calcSliderMarkPositions( oSlider ) {
	var bCreateMin = false;
	var bCreateMax = false;
	if ( oSlider.aMarks.length ) {
		var iMin = findSliderMarkPosValue( oSlider.aMarks[0] );
		var iMax = findSliderMarkPosValue( oSlider.aMarks[0] );
		for ( var i = 0; i < oSlider.aMarks.length; i++ ) {
			oSlider.aMarks[i].iValue = findSliderMarkValue( oSlider.aMarks[i] );
			oSlider.aMarks[i].iPosValue = findSliderMarkPosValue( oSlider.aMarks[i] );
			if ( oSlider.aMarks[i].iPosValue < iMin ) iMin = oSlider.aMarks[i].iPosValue;
			if ( oSlider.aMarks[i].iPosValue > iMax ) iMax = oSlider.aMarks[i].iPosValue;
		}
		if ( oSlider.iMin && oSlider.iMin < iMin ) { bCreateMin = true; iMin = oSlider.iMin; }
		if ( oSlider.iMax && oSlider.iMax > iMax ) { bCreateMax = true; iMax = oSlider.iMax; }
	} else {
		bCreateMin = true;
		bCreateMax = true;
		if ( oSlider.iMin ) iMin = oSlider.iMin;
			else { iMin = iSliderDefaultMin; oSlider.iMin = iSliderDefaultMin; }
		if ( oSlider.iMax ) iMax = oSlider.iMax;
			else { iMax = iSliderDefaultMax; oSlider.iMax = iSliderDefaultMax; }
	}
	oSlider.iMin = iMin;
	oSlider.iMax = iMax;
	if ( bCreateMin ) {
		oSlider.aMarks[ oSlider.aMarks.length ] = new SliderMark(
			oSlider.sSliderID, null,
			false, false, oSlider.iMin, oSlider.iMin,
			'', null, '', null, oSlider.iMin, oSlider.iMin
		)
	}
	if ( bCreateMax ) {
		oSlider.aMarks[ oSlider.aMarks.length ] = new SliderMark(
			oSlider.sSliderID, null,
			false, false, oSlider.iMax, oSlider.iMax,
			'', null, '', null, oSlider.iMax, oSlider.iMax
		)
	}
	oSlider.aMarks = oSlider.aMarks.sort( compareSliderMarksPosValues );
	var iInterval = oSlider.iMax - oSlider.iMin;
	for ( var i = 0; i < oSlider.aMarks.length; i++ ) {
		var iValue = oSlider.aMarks[i].iPosValue - oSlider.iMin;
		oSlider.aMarks[i].iPos = iValue / iInterval * 100;
	}
}

function buildSliderMarks( oSlider ) {
	var oGrid = document.createElement('div');
	oGrid.className = sSliderMarksGridClass;
	calcSliderMarkPositions( oSlider );

	for ( var i = 0; i < oSlider.aMarks.length; i++ ) {
		var sMarkClass = sSliderDefaultMarkClass;
		if ( oSlider.aMarks[i].sClassName ) sMarkClass += ' ' + oSlider.aMarks[i].sClassName;
		if ( i == 0 ) sMarkClass += ' ' + sSliderStartMarkClass;
		if ( i == oSlider.aMarks.length - 1 ) sMarkClass += ' ' + sSliderEndMarkClass;

		var oMarkContent = document.createElement('span');
//		var sMarkContent = oSlider.aMarks[i].sText || sSliderDefaultMarkContent;
		var sMarkContent = sSliderDefaultMarkContent;
		oMarkContent.innerHTML = sMarkContent;
		var oMark = createSliderContainer( null, sMarkClass, oMarkContent );
		
		if ( oSlider.sOrientation == sSliderVertical ) {
			oMark.style.marginTop = oSlider.aMarks[i].iPos + '%';
		} else {
			oMark.style.marginLeft = oSlider.aMarks[i].iPos + '%';
		}
		
		oGrid.appendChild( oMark );
	}

	return oGrid;
}


// building pointers
function buildSliderPointers( oSlider ) {
	var oGrid = document.createElement('div');
	oGrid.className = sSliderPointersGridClass;

	for ( var i = 0; i < oSlider.aPointers.length; i++ ) {
		var oPointerContent = document.createElement('div');
		oPointerContent.innerHTML = sSliderDefaultPointerContent;

		/* info */
		var oInfoDiv = document.createElement('div');
		oInfoDiv.id = oSlider.aPointers[i].sPointerID + 'info';
//		oInfoDiv.innerHTML = oSlider.aPointers[i].iValue;
		oInfoDiv.className = sSliderContainerInfoDivClass;

		var oPointer = createSliderContainer( oSlider.aPointers[i].sPointerID, sSliderPointerClass, oPointerContent, oInfoDiv );
		oSlider.aPointers[i].oPointerElem = oPointer;
		calcSliderPointerPositionFromValue( oSlider.aPointers[i] );

		if ( oSlider.sOrientation == sSliderVertical ) {
			oPointer.style.top = oSlider.aPointers[i].iPos + '%';
		} else {
			oPointer.style.left = oSlider.aPointers[i].iPos + '%';
		}

		oGrid.appendChild( oPointer );
	}

	return oGrid;
}


function createSliderContainer( sElemID, sClassNames, oContent, oInfoDiv ) {
	var oTable = document.createElement('table');
	if ( sElemID ) oTable.id = sElemID;
	oTable.className = sClassNames;
	var oTBody = document.createElement('tbody');
	var oTableRow = document.createElement('tr');
	var oTableCell = document.createElement('td');
	if ( oInfoDiv ) {
		var oInfoDivContainer = document.createElement('div');
		oInfoDivContainer.className = 'info-center';
		oTableCell.appendChild( oInfoDivContainer );
		oInfoDivContainer.appendChild( oInfoDiv );
	}
	var oCenterDiv = document.createElement('div');
	oCenterDiv.className = sSliderContainerCenterDivClass;
	if ( oContent ) oCenterDiv.appendChild( oContent );
	oTableCell.appendChild( oCenterDiv );
	oTableRow.appendChild( oTableCell );
	oTBody.appendChild( oTableRow );
	oTable.appendChild( oTBody );
	return oTable;
}


/****************************************/
/*     slider position and movement     */
/****************************************/

function calcSliderPointerPositionFromValue( oPointer ) {
	var oSlider = aSliders[ oPointer.sSliderID ];
	if ( oSlider ) {
		for ( var i = 0; i < oSlider.aMarks.length; i++ ) {
			if (
				oPointer.iValue == oSlider.aMarks[i].iValue
				|| !oSlider.aMarks[i + 1]
				|| ( i == 0 && oPointer.iValue < oSlider.aMarks[i].iValue )
			) {
				oPointer.iPos = oSlider.aMarks[i].iPos;
				return;
			}

			if (
				oPointer.iValue > oSlider.aMarks[i].iValue
				&& oPointer.iValue < oSlider.aMarks[i + 1].iValue
			) {
				var iInterval = oSlider.aMarks[i + 1].iValue - oSlider.aMarks[i].iValue;
				var iValue = oPointer.iValue - oSlider.aMarks[i].iValue;
				var iPos = iValue / iInterval;
				
				oPointer.iPos = ( oSlider.aMarks[i + 1].iPos - oSlider.aMarks[i].iPos ) * iPos + oSlider.aMarks[i].iPos;
				return;
			}
		}
	}
}

function calcSliderPointerValueFromPosition( oSlider, iNewPos ) {
	if ( oSlider ) {
		for ( var i = 0; i < oSlider.aMarks.length; i++ ) {
			if (
				iNewPos == oSlider.aMarks[i].iPos
				|| !oSlider.aMarks[i + 1]
				|| ( i == 0 && iNewPos < oSlider.aMarks[i].iPos )
			) {
				return oSlider.aMarks[i].iValue;
			}

			if (
				iNewPos > oSlider.aMarks[i].iPos
				&& iNewPos < oSlider.aMarks[i + 1].iPos
			) {
				var iInterval = oSlider.aMarks[i + 1].iPos - oSlider.aMarks[i].iPos;
				var iPos = iNewPos - oSlider.aMarks[i].iPos;
				var iValue = iPos / iInterval;
				var iNewPos = ( oSlider.aMarks[i + 1].iValue - oSlider.aMarks[i].iValue ) * iValue + parseInt( oSlider.aMarks[i].iValue );
				if ( oSlider.aMarks[i].iStep > 1 ) iNewPos = Math.round( iNewPos / oSlider.aMarks[i].iStep ) * oSlider.aMarks[i].iStep;
				return iNewPos;
			}
		}
	}

}

function moveActiveSliderPointer( iCurrentWindowPos ) {
	if ( oActiveSlider ) {
		var iNewPos = ( iCurrentWindowPos - iActiveSliderWindowOffset ) / iActiveSliderSize * 100;
		var iNewValue = calcSliderPointerValueFromPosition( oActiveSlider, iNewPos );
		var oPointer = oActiveSlider.aPointers[0]; // to be changed
		if ( Math.round( iNewValue ) != oPointer.iValue ) {
			oPointer.iValue = Math.round( iNewValue );
			changeSliderPointerValue( oPointer )
			calcSliderPointerPositionFromValue( oPointer );
			if ( oPointer.oPointerElem ) {
				if ( oActiveSlider.sOrientation == sSliderVertical ) {
					oPointer.oPointerElem.style.top = oPointer.iPos + '%';
				} else {
					oPointer.oPointerElem.style.left = oPointer.iPos + '%';
				}
			}
		}

		/*
		var oPointer = oActiveSlider.aPointers[0]; // to be changed
		if ( oPointer.oPointerElem ) {
			if ( oActiveSlider.sOrientation == sSliderVertical ) {
				oPointer.oPointerElem.style.top = iNewPos + '%';
			} else {
				oPointer.oPointerElem.style.left = iNewPos + '%';
			}
		}
		*/
	}
}

function changeSliderPointerValue( oPointer ) {
	// something's wrong with that
	oPointer.oElem.value = oPointer.iValue;
	if ( oPointer.oElem.onchange ) oPointer.oElem.onchange();
}

/***************************/
/*     event capturing     */
/***************************/

function returnFalse() { return false; }

var oActiveSlider = null;
var iActiveSliderSize = 0;
var iActiveSliderLayerPos = 0;
var iActiveSliderWindowPos = 0;
var iActiveSliderWindowOffset = 0;

function sliderMouseDown( evt ) {
	var oSlider = aSliders[ this.id ];
	if ( oSlider ) {
		if ( oSlider.sOrientation == sSliderVertical ) {
			iActiveSliderSize = this.offsetHeight;
			iActiveSliderLayerPos = ( window.event )? event.offsetY : evt.layerY;
			iActiveSliderWindowPos = ( window.event )? event.clientY : evt.pageY;
		} else {
			iActiveSliderSize = this.offsetWidth;
			iActiveSliderLayerPos = ( window.event )? event.offsetX : evt.layerX;
			iActiveSliderWindowPos = ( window.event )? event.clientX : evt.pageX;
		}
		iActiveSliderWindowOffset = iActiveSliderWindowPos - iActiveSliderLayerPos;
		oActiveSlider = oSlider;
		moveActiveSliderPointer( iActiveSliderWindowPos );
	}
	if ( evt && evt.stopPropagation ) evt.stopPropagation();
	returnFalse();
}

function sliderKeyDown( evt ) {
}


function moveMouse( evt ) {
	if ( oActiveSlider ) {
		if ( evt && evt.cancelable && evt.preventDefault ) evt.preventDefault();
		if ( window.event && event.cancelBubble ) event.cancelBubble = true;
		if ( oActiveSlider.sOrientation == sSliderVertical ) {
			var iCurrentWindowPos = ( window.event )? event.clientY : evt.pageY;
		} else {
			var iCurrentWindowPos = ( window.event )? event.clientX : evt.pageX;
		}
		moveActiveSliderPointer( iCurrentWindowPos );
		return false;
	}
}

function upMouse( evt ) {
	oActiveSlider = null;
}


/****************/
/*     init     */
/****************/

function initSliders() {

	for ( var iElemIdx = 0; ( oDivElem = document.getElementsByTagName('div').item( iElemIdx ) ); iElemIdx++ ) {
		if ( matchClass( oDivElem, 'slider' ) ) createSlider( oDivElem );
	}
	for ( var i in aSliders ) {
		var oElem = aSliders[i].aPointers[0].oElem;
		oGlobalPointer = aSliders[i].aPointers[0];
		if ( oElem && oElem.onchange ) oElem.onchange();
	}
	oGlobalPointer = null;
	
	addEvent(document, 'mousemove', moveMouse);
	addEvent(document, 'mouseup', upMouse);
}

addEvent(window, 'load', initSliders);





/*****************************/
/*     support functions     */
/*****************************/

function getNamedValuesArray( sNames, sValues, sDivider ) {
	sDivider = sDivider || sSliderClassValuesDivider;
	sValues = ' ' + sValues;
	var aValues = new Array();
	if ( sNames && sValues ) {
		aNames = sNames.split(/[|\s]/);
		for ( var i = 0; i < aNames.length; i++ ) {
			if ( aNames[i].length ) {
				var sName = ' ' + aNames[i] + sDivider;
				var iStartPos = sValues.indexOf( sName );
				if ( iStartPos >= 0 ) {
					iStartPos += sName.length;
					var iEndPos = sValues.indexOf( ' ', iStartPos );
					if ( iEndPos < 0 ) iEndPos = sValues.length;
					aValues[ aNames[i] ] = sValues.substring( iStartPos, iEndPos );
				} else aValues[ aNames[i] ] = null;
			}
		}
	}
	return aValues;
}

function getValuesArrayByName( sName, sValues, sDivider ) {
	sDivider = sDivider || sSliderClassValuesDivider;
	var aValues = new Array();
	sValues = ' ' + sValues;
	var sName = ' ' + sName + sDivider;
	var iStartPos = sValues.indexOf( sName );
	while ( iStartPos >= 0 ) {
		iStartPos += sName.length;
		var iEndPos = sValues.indexOf( ' ', iStartPos );
		if ( iEndPos < 0 ) iEndPos = sValues.length;
		var sTempValues = sValues.substring( iStartPos, iEndPos );
		aValues[ aValues.length ] = sTempValues.split( sDivider );
		iStartPos = sValues.indexOf( sName, iEndPos );
	}
	return aValues;
}

function getIntValueByPrefix( aValues, sPrefix ) {
	for ( var i = 0; i < aValues.length; i++ )
		if ( aValues[i].indexOf( sPrefix ) == 0 ) return parseInt( aValues[i].substr( sPrefix.length ) );
	return null;
}


/* reminder(s) */
function getREM( aValues, iDivider ) {
	var iREM = 0;
	for ( var i in aValues ) iREM += aValues[i] % iDivider;
	return iREM;
}

/* greatest common divisor */
function getGCD( aValues ) {
	var iMin = aValues[0];
	for ( var i in aValues ) if ( aValues[i] < iMin ) iMin = aValues[i];
	while ( iMin > 1 && getREM( aValues, iMin ) ) iMin--;
	return iMin;
}

