<?php
require_once 'Zend/Form/ZendElement.php';
/**
 * Goweb Sitemanager 5 Framework
 *
 * @version    5.1.2
 * @category   Zend
 * @package    Zend
 * @author     I&D <dev@goweb.pt>, Pedro Pinto <ppinto@goweb.pt>
 * @copyright  2010 (c) Goweb (http://www.goweb.pt)
 */

/**
 *
 * @version    5.1.2
 * @category   Zend
 * @package    Zend_Form
 * @author     I&D <dev@goweb.pt>, Pedro Pinto <ppinto@goweb.pt>
 * @copyright  2010 (c) Goweb (http://www.goweb.pt)
 */
class Zend_Form_Element extends Zend_Form_ZendElement{

    /**
     * Configurações do elemento
     *
     * @var  array
     */
    protected $_config = array('class' => null,
                               'focus_class' => null,
                               'error_class' => null,
                               'help' => null,
                               'extra' => null);


    /**
     * Retrieve validator first error
     *
     * @return string
     */
    public function getErrorMessage(){
        $error = $this->getMessages();
        $errors = array();
        foreach ($this->getValidators() as $validator){
            foreach ($this->getValidators() as $validator){
                $tmpError = $validator->getMessages();
                $errors = array_merge($errors, $tmpError);
            }
        }
        if (is_array($errors) && count($errors)>0) {
            /**
             * span a pedido do JRosado :)
             */
            return '<span>' . current($errors) . '</span>';
        }
        return $errors;
    }

    /**
     * Constructor
     *
     * $spec may be:
     * - string: name of element
     * - array: options with which to configure element
     * - Zend_Config: Zend_Config with options for configuring element
     *
     * @param  string|array|Zend_Config $spec
     * @return void
     * @throws Zend_Form_Exception if no element name after initialization
     */
    public function __construct($spec, $options = null){
        if (is_array($spec)) {
            foreach ($spec as $key => $value) {
                if (array_key_exists($key, $this->_config)) {
                    $this->_config[$key] = $value;
                }
            }
        }
        if (isset($this->_config['focus_class']) && $this->_config['focus_class']) {
            $this->setAttrib('onfocus', 'this.className="'.$this->_config['focus_class'].'"');
            $this->setAttrib('onblur', 'this.className="'.$this->_config['focus_class'].'"');
        }

        if (isset($this->_config['class']) && $this->_config['class'] != null) {
            $this->setAttrib('class', $this->_config['class']);
        }
        parent::__construct($spec, $options);
    }

    /**
     * Validate element value
     *
     * @return bool
     */
    public function validate(){
        $request = Zend_Controller_Front::getInstance()->getRequest();
        $valid = $this->isValid($request->getPost());
        if (isset($this->_config['error_class']) && $valid && $this->_config['error_class']) {
            $this->setAttrib('class', $this->_config['error_class']);
        }
        return $valid;
    }

    /**
     * Overloading: set object property
     *
     * @param  string $key
     * @param  mixed $value
     * @return void
     */
    public function __set($key, $value) {
        if (array_key_exists($key, $this->_config)) {
            if (in_array($key, array('class'))){
                $this->setAttrib($key, $value);
            }
            return $this->_config[$key] = $value;
        }else if (strcmp($key, 'value') === 0){
            if ($this instanceof Zend_Form_Element_Submit){
                return $this->setLabel($value);
            }
            return $this->setValue($value);
        }else if (strcmp($key, 'label') === 0){
            return $this->setLabel($value);
        }
        parent::__set($key, $value);
    }

    /**
     * Overloading: retrieve object property
     *
     * @param String $key
     * @return mixed
     */
    public function __get($key){
        if (array_key_exists($key, $this->_config)) {
            return $this->_config[$key];
        }else if (strcmp($key, 'label') === 0){
            $label = $this->getLabel();
            if ($this->isRequired()) {
                return '<label class="required">' . $label . '</label>';
            }
            return '<label>' . $label . '</label>';
        }else if (strcmp($key, 'input') === 0){
            return $this->render();
        }else if (strcmp($key, 'value') === 0){
            return $this->getValue();
        }else if (strcmp($key, 'validators') === 0) {
            return $this;
        }elseif (strcmp($key, 'type') == 0){
            $type=$this->getType();
            return strtolower(substr($type, strrpos($type, '_')+1));
        }
        return parent::__get($key);
    }

    /**
     * Este metodo retorn TRUE se o validador je existe no elemento.
     *
     * @param   string  $validatorClassName
     * @return  bool    Retorna TRUE se o validador je existe no elemento
     */
    public function validatorExists($validatorClassName) {
        if (array_key_exists($validatorClassName, $this->_validators)) {
            return true;
        }
        return false;
    }

    /**
     * Metodo chamada de metodo caso n&atilde;o exista.
     * e utilizado para instanciar dinemicamente os validadores.
     *
     * Exemplo:
     * $form->nome_do_campo->validators->Request();
     *
     * @param   $elementType  string  Tipo de coluna
     * @param   $params       array   Array com os paremetros
     * @throws  Goweb_Exception  No caso do tipo de elemento n&atilde;o existir
     * @return  Goweb_Form_Element
     */
    public function __call($validatorType, $params = array()) {
        $validator = 'Goweb_Validate_';
        if (!Goweb::isReadable($validator . $validatorType)) {
            $validator = 'Zend_Validate_';
            if (!Goweb::isReadable($validator . $validatorType)) {
                throw new Goweb_Exception('O tipo de validador "Goweb_Validate_' . $validatorType . '" n&atilde;o existe.');
            }
        }

        Goweb::loadClass($validator . $validatorType);
        $validatorClassName = $validator . $validatorType;
        if (count($params) > 1) {
            $this->addValidator(new $validatorClassName($params[0], $params[1]));
        } else {
            if (!isset($params[0])) $params[0] = array();

            $this->addValidator(new $validatorClassName($params[0]));
        }
        if (strcmp($validatorType, 'Required') == 0){
            $this->setRequired();
        }
        if (is_string($params[0])){
            //$this->addErrorMessage($params[0]);
            $this->_errorMessages[$validator . $validatorType] = (string) $params[0];
        }
    }
}