<?php
/**
 * An abstract class for validators.
 *
 * This class provides a way of validating a value against a sequence of
 * validators.
 */
abstract class validator_macro extends validator_reverse
{
    /**
     * @var array The sequence of validators.
     */
    protected $macro;

    ////////////////////////////////////////////////////////////////////////////
    // Construct and destruct functions.

    /**
     * @param array $macro The sequence of validators.
     * @param string (optional) $error The error message.
     * @param boolean (optional) $reverse Whether the validator is in reverse
     * mode or not.
     */
    public function __construct(array $macro, $error = null, $reverse = false)
    {
        parent::__construct($error, $reverse);
        $this->clear();
        
        foreach ($macro as $k => $v)
        {
            $this->set($v, $k);
        }
    }

    ////////////////////////////////////////////////////////////////////////////
    // Overload functions.

    ////////////////////////////////////////////////////////////////////////////
    // Interface functions.
    
    /**
     * Sets a validator.
     * 
     * @param validator $validator The validator.
     * @param string (optional) $name The validator name.
     * @return validator_macro A fluent interface.
     */
    public function set(validator $validator, $name = null)
    {
        if ($name === null)
        {
            $this->macro[] = $validator;
        }
        else
        {
            $this->macro[$name] = $validator;
        }
        
        return $this;
    }

    /**
     * Clears one or all validators.
     * 
     * @param string (optional) $name The validator name.
     * @return validator_macro A fluent interface.
     */
    public function clear($name = null)
    {
        if ($name === null)
        {
            $this->macro = array();
        }
        else
        {
            unset($this->macro[$name]);
        }
        
        return $this;
    }
    
    ////////////////////////////////////////////////////////////////////////////
    // Internal functions.
}
