/*
	DESCRIPTION:
	Maxlength character limiter. Displays an orange div below a form field, showing in realtime the number 
	of characters left before reaching the maxlength for that field.
	
	For this functionality to work, you must specify this following in your parent template:
				#set( $JS_Maxlength = true )
	
	This functionality is used by the #CreateTextField Velocity macro. It can also be activated manually for 
	any textarea or input of type text. For manual addition, add "maxlength_NUM" to the class name of your field,
	where NUM is an integer representing the maxlength you want to impose on that field. 
	
	NOTE: When manually activating this maxlength functionality for an input of type text, you'll still need to 
	give that element a maxlength attribute. For textarea elements, the limitation is imposed automatically
	via javascript so you won't need to do anything other than add the class name.
*/
var containerMaxCharLimit = null;
var regexMaxCharLimit = /(^|\s+)maxlength_(\d+)($|\s+)/;
addLoadEvent(function () {
	var mainForm = document.getElementById("main");
	var theList = getElementsByClassName(regexMaxCharLimit, "input", mainForm);
	var secondList = getElementsByClassName(regexMaxCharLimit, "textarea", mainForm);
	theList = theList.concat(secondList);
	for (var i=0; i < theList.length; i++) {
		if (!containerMaxCharLimit) { // Create the container if it doesn't exist yet.
			containerMaxCharLimit = createNewElement("div", null, "maxCharLimit");
			document.body.insertBefore(containerMaxCharLimit, document.body.firstChild);
		}
		addEventHandler(theList[i], "focus", showMaxCharLimit);
		addEventHandler(theList[i], "keydown", showMaxCharLimit);
		addEventHandler(theList[i], "keypress", showMaxCharLimit);
		addEventHandler(theList[i], "keyup", showMaxCharLimit);
		addEventHandler(theList[i], "blur", showMaxCharLimit);
	}
});
function showMaxCharLimit(ev){
	if (!ev) var ev = window.event;
	var catalyst = getEventCatalyst(ev);
	if (!ev.type) return false;
	var event_type = ev.type.toLowerCase();
	if (event_type.indexOf("focus") != -1) {
		var coords = getObjPos(catalyst);
		if(isIE){
		  containerMaxCharLimit.style.left = coords.x;
		  containerMaxCharLimit.style.top = coords.y + catalyst.offsetHeight;	  
		}else{
		  containerMaxCharLimit.style.left = coords.x+'px';
		  containerMaxCharLimit.style.top = (coords.y + catalyst.offsetHeight)+'px';
		}
	}
	if (!containerMaxCharLimit) return true;
	if (event_type.indexOf("blur") != -1) {
		containerMaxCharLimit.style.display = "none";
		return true;
	}
	if (catalyst.maxLength && catalyst.maxLength > 0)
		var limit = catalyst.maxLength;
	else if (document.getElementById(catalyst.id + "_MaxCharLimit"))
		var limit = document.getElementById(catalyst.id + "_MaxCharLimit").value;
	else if (catalyst.className && (catalyst.className.indexOf("maxlength_") != -1) )
		var limit = catalyst.className.match(regexMaxCharLimit)[2];
	else
		var limit = 128;
	var actualChars = isIE ? catalyst.value.length : catalyst.value.replace(/\n/g, "**").length;
	var num = parseInt(limit) - actualChars;
	if( num < 0 ) num = 0;
	containerMaxCharLimit.innerHTML = "还可以输入"+num+"个字符.(最多"+limit+"个字符)";
	containerMaxCharLimit.style.display = "block";
	
	if (catalyst.nodeName.toLowerCase() == "textarea") {
		if (event_type.indexOf("keydown") != -1) return textarea_limiter(catalyst, limit, ev);
		else if (event_type.indexOf("keyup") != -1) return textarea_limiter(catalyst, limit);
	}
}
// If two args, impose a maximum character on a form input field (for use with textareas).
// If three args, prevent cut & paste operations from circumventing the max char limit.
function textarea_limiter(theField, maxlen, e) {
	if (arguments.length == 3) {
		if (getStringTrueLength(theField.value) >= maxlen) {
			if(!isKeyEventAllowed(e)) {
				theField.value = theField.value.substring(0, maxlen);
				return false;
			}
		}
	} else if (arguments.length == 2) {
		if (getStringTrueLength(theField.value) > maxlen) {
			if (!isIE) {
				extraLen = countNewlineChars(theField.value, maxlen);
				maxlen -= extraLen;
				errorLen = countNewlineChars(theField.value, maxlen);
				while( (extraLen - errorLen) > 0 ) {
					maxlen += (extraLen - errorLen);
					extraLen = errorLen;
					errorLen = countNewlineChars(theField.value, maxlen);
				}
			}
			theField.value = theField.value.substring(0, maxlen);
			return false;
		}
	}
	return true;
}

// In IE, line breaks in a textarea are counted as 2 chars. In all other browsers, they're counted as 1 char. The broker counts them
// as 2 characters. Thus, for all browsers other than IE, we cannot rely on javascript's built-in "length" method to tell
// us the real length of textarea's value. This function will return the "true length", accommodating that extra unread character
// for non-IE browsers.
function getStringTrueLength(theString) {
	return (isIE) ? theString.length : theString.replace(/\n/g, "**").length;
}
// Returns true for certain key events when an input field is at its maxchar limit, to allow user manipulation of 
// what's been typed. Returns false for all other keys.
function isKeyEventAllowed(e) {
	if (window.event) theKey = e.keyCode;
	else if (e.which) theKey = e.which;
	else return;
	// Allow ALT, CTRL, SHIFT, arrows, HOME, END, PGUP, PGDOWN, DEL and BACKSPACE keys.
	return (e.altKey || e.ctrlKey || e.shiftKey || theKey == 8 || theKey == 46 || (theKey >= 33 && theKey <= 40));
}
// Returns the number of newline characters found in a substring.
function countNewlineChars(theString, maxlen) {
	return (theString.substring(0, maxlen).replace(/\n/g, "**").length - theString.substring(0, maxlen).length);
}
