(function ($, window, undefined) {
    var regex = {
	email: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i,
	guid: /^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$/i,
	phone: /^[\d]{7}(x[\d]{1,5})?$|^[\d]{10}(x[\d]{1,5})?$|^[\d]{11}(x[\d]{1,5})?$/,
	stripPhone: /[^\dx]+/gi,
	lastBr: /^<br\/>$/
    },
    icon = {
	loading: '<span class="icon loading"></span>',
	error: '<span class="icon msg_error"></span>',
	success: '<span class="icon check"></span>'
    };

    //Validation helpers
    app.validateField = function(elm) {
	if (!elm.dataset || !elm.dataset.validate) return true;

	var $e = $(elm).removeClass('invalid'),
	    $out = $e.nextAll('.validateOutput').first(),
	    name = $e.attr('placeholder'),
	    rules = $e.data('validate'),
	    emsg, val = $e.val(), err = '';

	$out.html(icon.loading).css('left', $e.position().left + $e.outerWidth() + 5);

	//if we have rules then validate
	emsg = rules.errorMessage;

	if (rules.required === true && val == '')
	    err += name + ' is required.<br/>';

	if (rules.required === true && $e.is(':checkbox') && !$e.is(':checked'))
	    err += name + ' must be checked.<br/>';

	if (rules.charCount && $.isArray(rules.charCount) && 
	    (val.length < rules.charCount[0] || val.length > rules.charCount[1])) {
	    err += name + ' must be between ' + rules.charCount[0] + ' and ' + rules.charCount[1] + ' characters.<br/>';
	}

	if (rules.match && $(rules.match).length && val !== $(rules.match).val())
	    err += name + ' must match ' + $(rules.match).attr('placeholder') + '<br/>';

	if (rules.type !== undefined) {
	    var res = true;
	    switch (rules.type) {
		case 'email':
		    if (val.match(regex.email) === null)
			err += 'Please enter a valid email address.<br/>';
		    break;
		case 'guid':
		case 'uuid':
		    if (val.length !== 36 || val.match(regex.guid) === null)
			err += 'Please enter a valid guid.<br/>';
		    break;
		case 'phone':
		    var stripped = val.replace(regex.stripPhone, '');

		    if (stripped.match(regex.phone) === null)
			err += 'Please enter a valid phone number.<br/>';
		    break;
	    }
	}

	if (rules.regex !== undefined && val.match(rules.regex) === null)
	    err = name + ' is invalid.<br/>';

	if (err != '') {
	    $e.addClass('invalid');
	    err = (emsg ? emsg : err.replace(regex.lastBr, ''));
	    $out.html(icon.error);
	    $out.find('span.icon.msg_error').qtip({
		style: {
		    classes: app.qtip.style
		},
		content: {
		    text: err
		},
		show: {
		    ready: true
		},
		hide: false,
		position: {
		    my: 'left center',
		    at: 'right center'
		}
	    });
	} 
	else $out.html(icon.success);

	return (err == '');
    }

    app.validateForm = function(form) {
	var $f = $(form),
	    $c = $f.find('*'),
	    pass = true;

	$c.each(function(i, elm) {
	    if(!app.validateField(elm)) pass = false;
	});

	return pass;
    }
})(jQuery, window);    
