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 = true;	// 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';
var myTextareaMonitorAlertsCount = 0;

// disable the text area monitor for an interval
function disableTextareaMonitor(){
	myTextareaMonitorAlerts = false;
}

// enable the text area monitor
function enableTextareaMonitor(){
	myTextareaMonitorAlerts = true;
}

function startTextareaMonitorNoPaste(textareaID, maximumLength)
{
	startTextareaMonitor(textareaID, maximumLength, 0);
}

function startTextareaMonitor(textareaID, maximumLength, maximumPaste)
{
	var field = document.getElementById(textareaID);
	if ((field) && (field.type == 'textarea')) 
	{
		startTextareaMonitorWithField(field, maximumLength, maximumPaste);
	}
}

function startTextareaMonitorWithField(field, maximumLength, maximumPaste)
{
	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 )
		{
			if (myTextareaMonitorAlerts)
			{
				monitor[0].value = previousValue.substring(0, previousLength); // reset value to pre paste or pre drag-n-drop length
				alert(myTextareaMonitorAlertPaste);
			}
		}
		else
		{
			if (currentLength > maximumLength)
			{
				if (myTextareaMonitorAlerts)
				{
					monitor[0].value = previousValue.substring(0, maximumLength); // reset value to maximum length
					alert(myTextareaMonitorAlertLength);
				}
			}
		}

		// remember value for next test

		monitor[1] = monitor[0].value;
		myTextareaMonitors[i] = monitor;
	}
	enableTextareaMonitor();
}
