


var myTextareaMonitorTimer = null;	// timer reference
var myTextareaMonitorTicks = 0; 	// the number of ticks that have occured
var myTextareaMonitorInterval = 100; 	// the number of milliseconds between ticks
var myTextareaMonitors = []; 		// two dimensional array containing data (body element, previous value, maximum length, maximum paste) about the textareas being monitored

var myTextareaMonitorAlerts = false;	// whether or not alerts will be shown to the users and, next, the text presented in each case ...
var myTextareaMonitorAlertPaste = 'Maximum paste size exceeded';
var myTextareaMonitorAlertLength = 'Maximum field length exceeded';



function startTextareaMonitorNoPaste(textareaID, maximumLength)
{
	startTextareaMonitor(textareaID, maximumLength, 0);
}



function startTextareaMonitor(textareaID, maximumLength, maximumPaste)
{
	var field = document.getElementById(textareaID);

	if ((field) && (field.type == 'textarea'))
	{
		var notFound = true;
		var i = 0;

		while ((i < myTextareaMonitors.length) && (notFound))
		{
			if ( myTextareaMonitors[i][0] == field )
			{
				notFound = false;
			}
			i++;
		}

		if (notFound)
		{
			// low priority timers, quick typing, key repeat etc. can add more than one character between tests so create a small buffer to accomodate

			var absoluteMinimumPaste = 40 / 1000 * myTextareaMonitorInterval; // based upon a 25 ms key repeat

			if (absoluteMinimumPaste > maximumPaste)
			{
				maximumPaste = absoluteMinimumPaste;
			}

			// add a new monitor

			var x = myTextareaMonitors.length;

			var monitor = [];

			monitor[0] = field; // testarea (html body) element
			monitor[1] = field.value;
			monitor[2] = maximumLength;
			monitor[3] = maximumPaste;

			myTextareaMonitors[x] = monitor;

			if (x == 0)
			{
				startTextareaMonitorTimer();
			}
		}
	}
}



function stopTextareaMonitor(textareaID)
{
	var field = document.getElementById(textareaID);

	if ((field) && (field.type == 'textarea'))
	{
		var newTextareaMonitors = [];

		for (var i=0; i<myTextareaMonitors.length; i++) // longwinded removal of field element as array.splice not widely supported
		{
			if ( myTextareaMonitors[i][0] == field )
			{
				// do nothing
			}
			else
			{
				newTextareaMonitors[newTextareaMonitors.length] = myTextareaMonitors[i];
			}
		}

		myTextareaMonitors = newTextareaMonitors;

		if ( myTextareaMonitors.length == 0 )
		{
			stopTextareaMonitorTimer();
		}
	}
}



function stopAllTextareaMonitors()
{
	var newTextareaMonitors = [];

	myTextareaMonitors = newTextareaMonitors;

	stopTextareaMonitorTimer();
}



function startTextareaMonitorTimer()
{
	scheduleTextareaMonitorTick();

}



function executeTextareaMonitorTick()
{
	myTextareaMonitorTicks++;

	testAllTextareaMonitors();

	scheduleTextareaMonitorTick();
}



function stopTextareaMonitorTimer()
{
	if ( myTextareaMonitorTimer )
	{
		clearTimeout(myTextareaMonitorTimer);
		myTextareaMonitorTimer = null;
	}
}



function scheduleTextareaMonitorTick()
{
	myTextareaMonitorTimer = setTimeout("executeTextareaMonitorTick();", myTextareaMonitorInterval);
}



function testAllTextareaMonitors()
{
	for (var i=0; i<myTextareaMonitors.length; i++)
	{
		var monitor = myTextareaMonitors[i];

		var currentLength  = monitor[0].value.length;
		var previousValue  = monitor[1];
		var previousLength = monitor[1].length;
		var maximumLength  = monitor[2];
		var maximumPaste   = monitor[3];

		// test limits

		if ( (currentLength - previousLength) > maximumPaste )
		{
			monitor[0].value = previousValue.substring(0, previousLength); // reset value to pre paste or pre drag-n-drop length
			if (myTextareaMonitorAlerts)
			{
				alert(myTextareaMonitorAlertPaste);
			}

		}
		else
		{
			if (currentLength > maximumLength)
			{
				monitor[0].value = previousValue.substring(0, maximumLength); // reset value to maximum length
				if (myTextareaMonitorAlerts)
				{
					alert(myTextareaMonitorAlertLength);
				}
			}
		}

		// remember value for next test

		monitor[1] = monitor[0].value;
		myTextareaMonitors[i] = monitor;
	}
}
