jQuery.fn.think_validation = function(vOptions) {
	//validation
	function isValid(fieldToValidate, successAction)
	{		
	    var postData = $(vOptions.formId).serialize() + "&validate_json_request=true&validate_json_field=" + fieldToValidate; //live data
		//var postData = "&validate_json_request=true&validate_json_field=" + fieldToValidate; //stub testing
		
		$.ajax({
			type: "POST",
			contentType: "application/json; charset=utf-8",
			url: vOptions.urlString,
			data: postData,
			dataType: "json",
			contentType: "application/x-www-form-urlencoded",
			error : function(errorData,errorData1)
			{
				if(fieldToValidate)
				{
					return false;
				}
				else
				{
					successAction();
				}
			},
			success : function(returnedData)
			{			
				var i = returnedData.validation.field.length;
				var valFlag = 0;
				while(i--)
				{
					var mainMessage = returnedData.validation.error_message_info;
					var fieldId = returnedData.validation.field[i].field_id;
					var inlineMess = returnedData.validation.field[i].message;
					var success = returnedData.validation.field[i].success;
								
					if(fieldToValidate==='' && !success)
					{					
						valFlag += 1;
					}
					if(success)
					{
						inlineMessage(fieldId,inlineMess,success);
						checkForErrors();
					}
					else
					{
						inlineMessage(fieldId,inlineMess,success);
						if(mainMessage) { displayError(mainMessage); }
					}
				}
				if(fieldToValidate==='' && valFlag===0)
				{
					successAction();
				}
			}
		});  
	};
	//check for other errors on page
	function checkForErrors()
	{
		if($("." + vOptions.parentMessageClass).parent().hasClass(vOptions.errorClass)===false && document.getElementById(vOptions.mainMessageId))
		{
			$("#" + vOptions.mainMessageId).remove();
		}
	};
	//display inline message next to field
	function inlineMessage(fieldId,inlineMess,success)
	{
		var parentClass;
		success ? parentClass = vOptions.successClass : parentClass = vOptions.errorClass;
		
		$("#" + fieldId).parents(".frmRow").addClass(parentClass);
		//if($("#" + fieldId).siblings().children().hasClass(vOptions.parentMessageClass)===true)
		if($("#" + fieldId).parents(".frmRow").children("label:first").children("span").hasClass(vOptions.parentMessageClass)===true)
		{	
			$("#" + fieldId).parents(".frmRow").children("." + vOptions.parentMessageClass).replaceWith($(inlineMess)); // ADD ARIA SUPPORT
			//$("#" + fieldId).next().replaceWith($(inlineMess).ariaState('live','polite'));
		}
		else
		{
			$(inlineMess).appendTo($("#" + fieldId).parents(".frmRow").children("label:first")); // ADD ARIA SUPPORT
			//$("#" + fieldId).siblings("label").append($(inlineMess));
			//$(inlineMess).insertAfter("#" + fieldId).ariaState('live','polite');
		}
	};
	//display error message block at top of page
	function displayError(mainMessage)
	{
		if(document.getElementById(vOptions.mainMessageId))
		{	
			$("#" + vOptions.mainMessageId).replaceWith($(mainMessage)); // ADD ARIA SUPPORT
			//$("#iError").replaceWith($(mainMessage).ariaState('live','assertive'));
		}
		else
		{
			$(mainMessage).prependTo("#" + vOptions.mainMessageParentId); // ADD ARIA SUPPORT
			//$(mainMessage).insertAfter("#primary").ariaState('live','assertive');
		}
	};
	//set event on fields
	if(vOptions.validateAll)
	{
		//catch on submit and validate all fields
		$(this).click(function(e) {
			
			var _this = $(this);
			
			if(!_this.data('valid'))
			{
				e.preventDefault();
				
				// pass empty field id to validate all fields
				isValid('', function()
				{
					_this.data('valid', true);
					_this.click();
				});
			}
			
	        
		});
	}
	else
	{
		$(this).blur(function () {
			if(($(this).siblings().hasClass("texthelp")==true) && ($(this).siblings(".texthelp").html() == $(this).val()))
			{
				return false;	
			}
			if(!($(this).val())) //check for null/empty value in field
			{
				if($(this).siblings().children().hasClass(vOptions.parentMessageClass)===true)
				{
					$(this).parent().find("." + vOptions.parentMessageClass).remove();
					$(this).parent().removeClass(vOptions.successClass);
					$(this).parent().removeClass(vOptions.errorClass);
					checkForErrors();
				}
				return false;
			}
			else
			{
				isValid(escape(this.name));
			}
		});
	};
	//end validation
};
