NPL.Prototype.__ElementSet__.IMS = function ( pCommandStr )
{
	//	'autoscroll'
	if ( pCommandStr == 'autoscroll' )
	{
		//	Use the same algorithm from the gallery code.
		NPL_IMS._autoscroll_add(this);
	}
	//	'align-middle'
	else if ( pCommandStr == 'align-middle' )
	{
		NPL_IMS._align_middle(this);
	}
	else if ( pCommandStr == 'align-center' )
	{
		NPL_IMS._align_center(this);
	}
}

if ( typeof NPL_IMS != 'undefined' )
{
	if ( typeof _NPL_Dbg != 'undefined' ) { _NPL_Dbg('NPLib: "IMS" already defined.'); }
}
else
{
	var NPL_IMS = function ()
	{
		_autoscrollers = [];
		_onresize = [];
		_fudge = 15;
		return {
		
			_autoscroll_add: function ( pElement )
			{
				_autoscrollers.push(pElement);
				//	Interval period should probably be adjusted dynamically, depending on the number
				//	of elements we're watching for &etc.
				if ( _autoscrollers.length == 1 ) { window.setInterval(NPL_IMS._autoscroll_interval, 70); }
			},
			
			_autoscroll_remove: function ( pElement )
			{
			},
			
			_autoscroll_interval: function ()
			{
				var _mouseX = NPL.Mouse.x();
				var _mouseY = NPL.Mouse.y();
				for ( var _x = 0; _x < _autoscrollers.length; _x++ )
				{
					var _element = _autoscrollers[_x];
					//	Check mouse coordinates against various element coordinates.
					if ( _mouseX > (_element.left()-_fudge) && _mouseY > (_element.top()-_fudge) )
					{
						if ( _mouseX < (_element.left()+_element.width()+_fudge) && _mouseY < (_element.top()+_element.height()+15) )
						{
							//	OK, mouse inside an autoscroll'd element. Get to work.
							//	First, calculate the mouse position relative to the element's (displayed) width and height.
							//	FIXME: Opera 8 has a bug here because it appears to support scrollHeight vs. height() correctly,
							//	but not scrollWidth. No idea WTF it's doing.
							//	Opera 9 appears to have fixed this. Yay Opera.
							if ( _element.scrollHeight() > _element.height() )
							{
								var _scrollFudgeY = Math.floor(_element.height()*.08);
								var _ratioY = (_mouseY - _element.top() - _scrollFudgeY) / (_element.height() - (2*_scrollFudgeY));
								_ratioY = _ratioY > 1 ? 1 : _ratioY < 0 ? 0 : _ratioY;
								var _scrollDeltaY = _element.element().scrollTop - Math.floor((_element.scrollHeight() - _element.height()) * _ratioY);
								var _scrollDirectionY = _scrollDeltaY < 0 ? 1 : -1;
								_scrollDeltaY *= _scrollDirectionY * -1;
								if ( _scrollDeltaY < 5 )
								{
									if ( _ratioY == 0 )
									{
										_element.element().scrollTop = 0;
									}
									else if ( _ratioY == 1 )
									{
										_element.element().scrollTop = _element.scrollHeight() - _element.height();
									}
								}
								else
								{
									if ( _scrollDeltaY > 250 ) { _scrollDeltaY = 250; }
									_element.element().scrollTop = _element.element().scrollTop + _scrollDirectionY * Math.floor(.004*_scrollDeltaY*_scrollDeltaY+6);
								}
							}
							if ( _element.scrollWidth() > _element.width() )
							{
								var _scrollFudgeX = Math.floor(_element.width()*.08);
								var _ratioX = (_mouseX - _element.left() - _scrollFudgeX) / (_element.width() - (2*_scrollFudgeX));
								_ratioX = _ratioX > 1 ? 1 : _ratioX < 0 ? 0 : _ratioX;
								var _scrollDeltaX = _element.element().scrollLeft - Math.floor((_element.scrollWidth() - _element.width()) * _ratioX);
								var _scrollDirectionX = _scrollDeltaX < 0 ? 1 : -1;
								_scrollDeltaX *= _scrollDirectionX * -1;
								if ( _scrollDeltaX < 5 )
								{
									if ( _ratioX == 0 )
									{
										_element.element().scrollLeft = 0;
									}
									else if ( _ratioX == 1 )
									{
										_element.element().scrollLeft = _element.scrollWidth() - _element.width();
									}
								}
								else
								{
									//	Danger: Math with "magic values" ahead. Proceed with caution.
									if ( _scrollDeltaX > 250 ) { _scrollDeltaX = 250; }
									_element.element().scrollLeft = _element.element().scrollLeft + _scrollDirectionX * Math.floor(.004*_scrollDeltaX*_scrollDeltaX+6);
								}
							}
						}
					}
				}
			},
			
			_align_middle: function ( pElement )
			{
				//	Sets an element in the vertical center of its parent.
				var xParent = pElement.element().parentNode;
				if ( typeof xParent != 'undefined' )
				{
					xParent = NPL.Select(xParent);
					xMargin = Math.floor((xParent.height() - pElement.height())/2);
					pElement.style('margin-top', xMargin+'px');
					pElement.style('margin-bottom', xMargin+'px');
				}
			},
			
			_align_center: function ( pElement )
			{
				//	Sets an element in the horizontal center of its parent.
				var xParent = pElement.element().parentNode;
				if ( typeof xParent != 'undefined' )
				{
					xParent = NPL.Select(xParent);
					xMargin = Math.floor((xParent.width() - pElement.width())/2);
					pElement.style('margin-left', xMargin+'px');
					pElement.style('margin-bottom', xMargin+'px');
				}
			}
			
		}
	}();
}