/**
 * Some modules allow users to define extra validation rules defined in a hook.
 * (e.g hook_webform_validation_validators()). To support these custom rules,
 * clientside validation has its own hook, hook_clientside_validation_rule_alter.
 * We had to use an 'alter' hook because module_invoke and module_invoke_all
 * does not support passing arguments by reference, drupal_alter does.
 *
 * If you want to add support for your custom validation rules defined for
 * webform_validation, fapi_validation or field_validation, you can use this
 * hook. Every validation rule that is defined for any of these modules and
 * is not implemented as standard by clientside_validation is passed through to
 * this hook (given that the related clientside validation module is enabled and
 * that clientside validation is enabled for the specific form).
 *
 * The first parameter to this hook is an array. This array, consitently named
 * $js_rules, is passed by reference throughout the entire module and is the key
 * to the entire functionality of this module.
 *
 * The second parameter is the form element or webform component (dependend on
 * third parameter)
 *
 * The third parameter, named $context, is a structured array. It consists of
 * the following keys:
 *  'type':       The type of form validation we are dealing with. Can be either
 *                'webform', 'fapi', 'field_validation' or 'element_validate'.
 *  'rule':       An array representing the webform validation, fapi validation or
 *                field validation rule. Only present when 'type' is 'webform', 'fapi'
 *                or 'field_validation'.
 *  'functions':  An array of functions found in the '#element_validate' of the element.
 *                Only present if type is 'element_validate'.
 *  'message':    The default error message for when this rule does not pass
 *                validation.Only present when 'type' is 'webform', 'fapi'
 *                or 'field_validation'.
 *
 * @param array $js_rules
 * An array structured like this:
 * $js_rules[$inputname][$rulename] = $parameters;
 * $js_rules[$inputname]['messages'][$rulename] = $message;
 * Where $inputname is the name attribute of the input element, $rulename is
 * the name of the rule (e.g. 'email'), $parameters is either TRUE (e.g. for
 * 'email') or an array (e.g. for 'range': array(2, 10) or 'max_length' array(10)) and
 * $message is the error message displayed when the validation does not pass.
 * @param array $element
 * Either a form element or a webform component.
 * @param array $context
 * A structured array consiting of the following keys:
 *  'type':       The type of form validation we are dealing with. Can be either
 *                'webform', 'fapi', 'field_validation' or 'element_validate'.
 *  'rule':       An array representing the webform validation, fapi validation or
 *                field validation rule. Only present when 'type' is 'webform', 'fapi'
 *                or 'field_validation'.
 *  'functions':  An array of functions found in the '#element_validate' of the element.
 *                Only present if type is 'element_validate'.
 *  'message':    The default error message for when this rule does not pass
 *                validation.Only present when 'type' is 'webform', 'fapi'
 *                or 'field_validation'.
 *
 * In the example below we use validations that are already implemented as usage
 * examples. In the example the following rules are implemented for clientside
 * validation:
 *  - minimum length for webform_validation
 *  - specific characters for fapi_validation
 *  - regular expression for field_validation
 */
function hook_clientside_validation_rule_alter(&$js_rules, $element, $context)
{
    switch ($context['type']) {
        case 'webform':
            if ($context['rule']['validator'] == 'min_length') {
                _clientside_validation_set_minmaxlength($component['element_name'], $component['element_title'], $context['rule']['data'], '', $js_rules, $context['message']);
            }
            break;
        case 'fapi':
            if ($context['rule']['callback'] == 'fapi_validation_rule_chars') {
                _clientside_validation_set_specific_values($element['#name'], $element['#title'], $context['params'], $js_rules);
            }
            break;
        case 'field_validation':
            if ($context['rule']['validator'] == 'regex') {
                _clientside_validation_set_regex($element['#name'], $element['#title'], $js_rules, $context['rule']['data'], $context['message']);
            }
            break;
        case 'element_validate':
            if (in_array('_container_validate', $context['functions'])) {
                _clientside_validation_set_not_equal($element['textfield_one']['#name'], $element['textfield_one']['#title'], array('form_key' => $element['textfield_two']['#name'], 'name' => $element['textfield_two']['#title']), $js_rules, t("The two fields cannot have the same value"));
            }
            break;
        default:
            break;
    }
}
/**
 * Some modules allow users to define extra validation rules defined in a hook.
 * (e.g hook_webform_validation_validators()). To support these custom rules,
 * clientside validation has its own hook, hook_clientside_validation_rule_alter.
 * We had to use an 'alter' hook because module_invoke and module_invoke_all
 * does not support passing arguments by reference, drupal_alter does.
 *
 * If you want to add support for your custom validation rules defined for
 * webform_validation, fapi_validation or field_validation, you can use this
 * hook. Every validation rule that is defined for any of these modules and
 * is not implemented as standard by clientside_validation is passed through to
 * this hook (given that the related clientside validation module is enabled and
 * that clientside validation is enabled for the specific form).
 *
 * The first parameter to this hook is an array. This array, consitently named
 * $js_rules, is passed by reference throughout the entire module and is the key
 * to the entire functionality of this module.
 *
 * The second parameter is the form element or webform component (dependend on
 * third parameter)
 *
 * The third parameter, named $context, is a structured array. It consists of
 * the following keys:
 *  'type':     The type of form validation we are dealing with. Can be either
 *              'webform', 'fapi' or 'field_validation'.
 *  'rule':     An array representing the webform validation, fapi validation or
 *              field validation rule.
 *  'message':  The default error message for when this rule does not pass
 *              validation.
 *
 * @param array $js_rules
 * An array structured like this:
 * $js_rules[$inputname][$rulename] = $parameters;
 * $js_rules[$inputname]['messages'][$rulename] = $message;
 * Where $inputname is the name attribute of the input element, $rulename is
 * the name of the rule (e.g. 'email'), $parameters is either TRUE (e.g. for
 * 'email') or an array (e.g. for 'range': array(2, 10) or 'max_length' array(10)) and
 * $message is the error message displayed when the validation does not pass.
 * @param array $element
 * Either a form element or a webform component.
 * @param array $context
 * A structured array consiting of the following keys:
 *  'type':     The type of form validation we are dealing with. Can be either
 *              'webform', 'fapi' or 'field_validation'.
 *  'rule':     An array representing the webform validation, fapi validation or
 *              field validation rule.
 *  'message':  The default error message for when this rule does not pass
 *              validation.
 *
 * In the example below we use validations that are already implemented as usage
 * examples. In the example the following rules are implemented for clientside
 * validation:
 *  - minimum length for webform_validation
 *  - specific characters for fapi_validation
 *  - regular expression for field_validation
 */
function hook_clientside_validation_rule_alter(&$js_rules, $element, $context)
{
    switch ($context['type']) {
        case 'webform':
            if ($context['rule']['validator'] == 'min_length') {
                _clientside_validation_set_minmaxlength($component['element_name'], $component['element_title'], $context['rule']['data'], '', $js_rules, $context['message']);
            }
            break;
        case 'fapi':
            if ($context['rule']['callback'] == 'fapi_validation_rule_chars') {
                _clientside_validation_set_specific_values($element['#name'], $element['#title'], $context['params'], $js_rules);
            }
            break;
        case 'field_validation':
            if ($context['rule']['validator'] == 'regex') {
                _clientside_validation_set_regex($element['#name'], $element['#title'], $js_rules, $context['rule']['data'], $context['message']);
            }
            break;
        default:
            break;
    }
}