function validate_form(form) {
    var valid = true;
    form.find('input, textarea, select').each(function() {
        if ($(this).hasClass('required') && !$(this).val().length) {
            $(this).addClass('missing');
            valid = false;
        } else {
            if ($(this).attr('rel')) {
                if ($(this).val().length > 0 && !validate_field($(this))) {
                    $(this).addClass('missing');
                    valid = false;
                } else {
                    $(this).removeClass('missing');
                }
            } else {
                $(this).removeClass('missing');
            }
        }
    });

    if (!valid) {
        form.find('.missing:first').focus();
    }

    return valid;
}

if (!_e_r) {
    var _e_r = new RegExp("^(?:[\\#\\$\\&'\\*\\+\\-\\/\\=\\?\\^\\_\\`\\{\\}\\|\\~a-zA-Z0-9-]+(?:\\.[\\#\\$\\&'\\*\\+\\-\\/\\=\\?\\^\\_\\`\\{\\}\\|\\~a-zA-Z0-9-]+)*@[a-zA-Z0-9-]{1,63}(?:\\.[a-zA-Z0-9-]{1,63})*\\.[a-zA-Z][a-zA-Z0-9-]{1,62})$");
}

function validate_field(field) {
    var type  = field.attr('rel');
    var value = field.val();

    var valid = true;
    var title = '';

    switch (type) {
        case 'email':
            if (!_e_r.test(value) || value.indexOf('@') >= 65) {
                valid = false;
                title = 'Invalid Email Address';
            }
            break;
        case 'phone':
            if (value.match(/[^\d]/)) {
                valid = false;
                title = 'Invalid Phone Number';
            }
            break;
        case 'web_address':
            if (!value.match(/^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i)) {
                valid = false;
                title = 'Invalid Web Address';
            }
            break;
    }

    if (!valid) {
        field.attr('title', title);
    } else {
        field.removeAttr('title');
    }

    return valid;
}
