function validate(group) {
	var marker = true;
	$("*[validate=" + group + "]").each(function(i, elm) {
		if (check(elm)) {
			$(elm).highlight();
			if (marker) $(elm).focus();
			marker = false;
		}
		else
			$(elm).unhighlight();
	});
	return marker;
}

function revalidate() {
	if (!check(this))
		$(this).unhighlight();
	else
		$(this).highlight();
}

function check(elm) {
	var jelm = $(elm);

	var listsize = jelm.find("input:radio, input:checkbox").size();
	if (jelm.attr("disabled") || listsize > 0 && listsize == jelm.find("input:radio:disabled, input:checkbox:disabled").size())
		return "";

	//if empty value only perform required validation
	if (jelm.val() == "" && jelm.find("input:radio:checked, input:checkbox:checked").size() == 0)
		return jelm.attr("wanted") ? "wanted" : "";

	if (jelm.attr("regular") && jelm.attr("validExpress") && !new RegExp(jelm.attr("validExpress"), "m").test(jelm.val()))
		return "regular";

	if (jelm.attr("regular") && jelm.attr("invalidExpress") && new RegExp(jelm.attr("invalidExpress"), "m").test(jelm.val()))
		return "regular";

	if (jelm.attr("compare") && $("[name="+jelm.attr("compareTo")+"][validate="+jelm.attr("validate")+"]").val() != jelm.val())
		return "compare";

	if (jelm.attr("custom") && !new Function(jelm.attr("customFn")).call(elm))
		return "custom";

	if (jelm.attr("invalid") && jelm.val() == jelm.attr("invalidVal"))
		return "invalid";
}


function showAlert() {
    var ctrl = $(this);
    var top = ctrl.offset().top - 4;
    var left = ctrl.offset().left + ctrl.width()+2;
    $(".alertbox").remove();
    $("body").append("<div class='alertbox' style='top:" + top + "px; left:" + left + "px;'><div>" + ctrl.attr(check(this)) + "</div></div>");
}

function hideAlert() {
    $(".alertbox").remove();
}

(function($) { $.fn.highlight = function() {
	this.addClass("highlight").focus(showAlert).blur(hideAlert).change(revalidate);
}})(jQuery);

(function($) { $.fn.unhighlight = function() {
	this.removeClass("highlight").unbind("focus", showAlert).unbind("blur", hideAlert);
}})(jQuery);
