<?php
/**
 * core.framework
 *
 * @category  Core
 * @package   Core_Validate
 * @copyright Copyright (c) 2011. Burza d.o.o. (http://web.burza.hr/en/)
 * @license   proprietary
 */

/**
 * Validator base class.
 *
 * @category   Core
 * @package    Core_Validate
 * @subpackage NotEmpty
 * @copyright  Copyright (c) 2011. Burza d.o.o. (http://web.burza.hr/en/)
 * @license    proprietary
 */
abstract class Core_Validate_Abstract implements Core_Validate_Interface, Core_Angular_Directive_Interface
{
    /**
     * @var Zend_Translator
     */
    protected $_translator;
    
    /**
     * @var string
     */
    protected $_name;

    /**
     * @var string
     */
    protected $_defaultErrorMessage = 'Invalid entry';

    /**
     * @var string
     */
    protected $_errorMessage;

    /**
     * @var string
     */
    protected $_angularType;

    /**
     * @var mixed
     */
    protected $_angularConfig;
    
    /**
     * @var Core_Plugin_Interface
     */
    protected $_parent;

    protected $_context;
    
    /**
     * @param mixed $value
     *
     * @return bool
     */
    abstract protected function _isValid($value);

    /**
     * @param array $options
     */
    public function __construct($options = null)
    {
        if (is_array($options)) {
            $this->setOptions($options);
        }
    }
    
    
    /**
     * @param Zend_Translate $translator
     * 
     * @return \Core_Validate_Abstract
     */
    public function setTranslator(Zend_Translate $translator)
    {
        $this->_translator = $translator;
        return $this;
    }
    
    /**
     * @return Zend_Translate
     */
    public function getTranslator()
    {
        if (null === $this->_translator) {
            $parent = $this->getParent();
            if (null !== $parent) {
                $this->_translator = $parent->getTranslator();
            }
        }
        return $this->_translator;
    }

    public function init()
    {}

    public function setOwner(Core_Plugin_Interface $owner)
    {
        $this->_parent = $owner;
    }
    
    public function getParent()
    {
        return $this->_parent;
    }

    /**
     * @param string $errorMessage
     *
     * @return array
     */
    public function getAngularRepresentation($errorMessage = null)
    {
        return $this->_formatAngularRepresentation($this->_angularType, $errorMessage, $this->_angularConfig);
    }

    /**
     * @param string $name
     *
     * @return \Core_Validate_Abstract
     */
    public function setName($name)
    {
        $this->_name = $name;
        return $this;
    }

    /**
     * @return string
     */
    public function getName()
    {
        return $this->_name;
    }

    /**
     * @param string $errorMessage
     *
     * @return \Core_Validate_Abstract
     */
    public function setErrorMessage($errorMessage)
    {
        $this->_errorMessage = $errorMessage;
        return $this;
    }

    /**
     * @param string $parentErrorMessage
     *
     * @return string
     */
    public function getErrorMessage($parentErrorMessage = null)
    {
        if ($this->_errorMessage) {
            // validator-level error message
            return $this->_translate($this->_errorMessage);
        } else if (null !== $parentErrorMessage) {
            // element-level error message
            return $parentErrorMessage;
        }
        // validator-level default error message
        return $this->_translate($this->_defaultErrorMessage);
    }


    /**
     * @param mixed $context
     *
     * @return Core_Validate_Abstract
     */
    public function setContext($context)
    {
        $this->_context = $context;

        return $this;
    }

    /**
     * @return mixed
     */
    public function getContext()
    {
        return $this->_context;
    }

    /**
     * @param array $options
     *
     * @return \Core_Validate_Abstract
     * @throws InvalidArgumentException
     */
    public function setOptions(array $options)
    {
        foreach ($options as $name => $value) {
            $method = 'set' . ucfirst($name);
            if (method_exists($this, $method)) {
                call_user_func(array($this, $method), $value);
            } else {
                throw new InvalidArgumentException(sprintf('Invalid option "%s" passed', $name));
            }
        }
        return $this;
    }

    /**
     * @param mixed $value
     *
     * @return bool
     */
    public function isValid($value)
    {
        return $this->_isValid($value);
    }

    /**
     * @param string $type
     * @param string $errorMessage
     * @param mixed  $config
     *
     * @return array
     */
    protected function _formatAngularRepresentation($type, $errorMessage = null, $config = null, $attribName = null)
    {
        if (null === $type) {
            return array();
        }

        return array($type => array(
            'attribName'   => (null === $attribName ? $type : $attribName),
            'errorMessage' => $this->getErrorMessage($errorMessage),
            'config'       => (null === $config) ? $type : $config,
        ));
    }
    
    /**
     * @param string $message
     * 
     * @return string
     */
    protected function _translate($message)
    {
        $translator = $this->getTranslator();
        if (!$translator) {
            return $message;
        }
        return $translator->translate($message);
    }
}