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

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

    /**
     * Parametros extra
     *
     * @var  string
     */
    protected $_extra = null;
    
    /**
     * Javascript do tiny_mce
     *
     * @var String
     */
    protected $_tinyMCE = '';
    
    /**
     * Contructor
     *
     * @param String $name Nome do formulário
     * @param String $action Acção do formulário
     * @param String $method Método de submissão do formulário
     * @param String $enctype Tipo de encriptação do formulário
     * @param String $extra Parametros extra do formulário
     */
    public function __construct($name = 'goweb_form', $action = null, $method = 'post', $enctype = null, $extra = null) {
        if (!is_string($name)) $name = 'goweb_form';
        $this->setName($name);
        $this->setAction($action);
        $this->setMethod($method);
        if (!is_null($enctype)) $this->setEnctype($enctype);
        if (!is_null($extra)) $this->_extra = $extra;
        $this->_setup();
        $this->clearDisplayGroups();
    }
    
    /**
     * Configurar a acção do formulário
     *
     * @param String $action
     */
    public function setAction($action){
        /**
         * por causa das langs e/ou do baseUrl
         */
    	if (!is_null($action) && strlen($action) > 0){
    		if (strpos($action, 'http') === false ) $action = Goweb::link($action);
        	parent::setAction($action);
    	}
    }
    
    /**
     * Render form
     * 
     * @param  Zend_View_Interface $view 
     * @return string
     */
    public function render(Zend_View_Interface $view = null){
        $output = '';
        $rteElements = array();
        foreach (array_keys($this->_elements) as $element) {
            if ($this->{$element}->getType() == 'Goweb_Form_Element_Rte') {
                $rteElements[] = $element;
            }
        }
        if (count($rteElements) > 0) {
            $front = Zend_Controller_Front::getInstance();
            $baseUrl = str_replace(array('/admin', '/index.php'), '', $front->getBaseUrl());
            if (strpos($baseUrl, 'admin') === false) $baseUrl .= '/admin';
            Goweb::loadJavascript('/admin/media/js/tinymce/tiny_mce.js');
            $session = Goweb::registry('session');
            $endTag = ' />';
            if (($this->view instanceof Zend_View_Abstract) && !$this->view->doctype()->isXhtml()) {
                $endTag= '>';
            }
            $output .= '<script type="text/javascript">' . "\n";
            $output .= '<!--' . "\n";
            $output .= 'tinyMCE.init({'."\n";
            $output .= '    convert_urls : false,'. "\n";
            $output .= '    language : "' . ($session->lang ? $session->lang : 'pt') . '",'. "\n";
            $output .= '    forced_root_block : false,'. "\n";
			$output .= '    force_br_newlines : true,'. "\n";
            $output .= '    force_p_newlines : false,'. "\n";
            $output .= '    mode : "exact",' . "\n";
            $output .= '    elements : "' . implode(',',$rteElements) . '",' . "\n";
            if ($this->{$rteElements[0]}->theme == 'imgmap') {
                $output .= '    theme : "advanced",' . "\n";
            } else {
                $output .= '    theme : "' . $this->{$rteElements[0]}->theme . '",' . "\n";
            }
            $output .= '    selfclosetags : "' . $endTag . '",' . "\n";
            if ($this->{$rteElements[0]}->theme == 'imgmap') {
                $output .= '    plugins : "selfclosetags,advhr,advimage,advlink,imgmap,inlinepopups",' . "\n";
            } else {
                $output .= '    plugins : "embedded_video,addthis,googlemaps,selfclosetags,w3cvalidate,component,safari,spellchecker,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,explorer",' . "\n";
            }
            
            /*
             * removed: ,formatselect,fontselect,help,advhr,separator,print,separator,ltr,rtl,emotions,insertlayer,moveforward,movebackward,absolute,separator,styleprops,
             * abbr,acronym,del,ins,nonbreaking,pagebreak
             * 
             * added: formatselect, a pedido do VT :)
             */
            if ($this->{$rteElements[0]}->theme == 'advanced') {
                $output .= '    theme_advanced_buttons1 : "component,embedded_video,addthis,googlemaps,explorer,template,w3cvalidate,selfclosetags,separator,bold,italic,underline,strikethrough,separator,justifyleft,justifycenter,justifyright,justifyfull,separator,styleselect,fontsizeselect,formatselect",' . "\n";
                $output .= '    theme_advanced_buttons2 : "cut,copy,paste,pastetext,pasteword,separator,search,replace,separator,bullist,numlist,separator,outdent,indent,blockquote,separator,undo,redo,separator,link,unlink,anchor,image,cleanup,code,separator,insertdate,inserttime,preview,separator,forecolor,backcolor",' . "\n";
                $output .= '    theme_advanced_buttons3 : "tablecontrols,separator,hr,removeformat,visualaid,separator,sub,sup,separator,charmap,iespell,media,separator,fullscreen,spellchecker,separator,cite,attribs,separator,visualchars,blockquote,separator,insertfile,insertimage",' . "\n";
                //$output .= '    theme_advanced_buttons4 : "spellchecker,separator,cite,attribs,separator,visualchars,template,blockquote,separator,insertfile,insertimage",' . "\n";
                $output .= '    theme_advanced_toolbar_location : "top",' . "\n";
                $output .= '    theme_advanced_toolbar_align : "left",' . "\n";
                $output .= '    theme_advanced_statusbar_location : "bottom",' . "\n";
                $output .= '    theme_advanced_resizing : true,' . "\n";
            } elseif ($this->{$rteElements[0]}->theme == 'imgmap') {
                $output .= '    theme_advanced_buttons1 : "image,imgmap,code",' . "\n";
                $output .= '    theme_advanced_buttons2 : "",' . "\n";
                $output .= '    theme_advanced_buttons3 : "",' . "\n";
                $output .= '    theme_advanced_buttons4 : "",' . "\n";
                //$output .= '    theme_advanced_buttons2 : "cut,copy,paste,pastetext,pasteword,separator,search,replace,separator,bullist,numlist,separator,outdent,indent,blockquote,separator,undo,redo,separator,link,unlink,anchor,image,cleanup,code,separator,insertdate,inserttime,preview,separator,forecolor,backcolor",' . "\n";
                //$output .= '    theme_advanced_buttons3 : "tablecontrols,separator,hr,removeformat,visualaid,separator,sub,sup,separator,charmap,iespell,media,separator,fullscreen,spellchecker,separator,cite,attribs,separator,visualchars,blockquote,separator,insertfile,insertimage",' . "\n";
                //$output .= '    theme_advanced_buttons4 : "spellchecker,separator,cite,attribs,separator,visualchars,template,blockquote,separator,insertfile,insertimage",' . "\n";
                $output .= '    theme_advanced_toolbar_location : "top",' . "\n";
                $output .= '    theme_advanced_toolbar_align : "left",' . "\n";
                $output .= '    theme_advanced_statusbar_location : "bottom",' . "\n";
                $output .= '    theme_advanced_resizing : true,' . "\n";
            }
            $output .= '    apply_source_formatting : true,' . "\n";
            if ($this->{$rteElements[0]}->css != null) {
                $output .= '    content_css : "' . (strpos($baseUrl, '/admin') === false ? $baseUrl: str_replace('/admin', '', $baseUrl)) . $this->{$rteElements[0]}->css . '",' . "\n";
            } else {
                $output .= '    content_css : "' . (strpos($baseUrl, '/admin') === false ? $baseUrl: str_replace('/admin', '', $baseUrl)) . '/media/css/cms.css",' . "\n";
            }
            if ($this->{$rteElements[0]}->plugin_insertdate_dateFormat){
                $output .= '    plugin_insertdate_dateFormat : "' . $this->{$rteElements[0]}->plugin_insertdate_dateFormat.'",' . "\n";
            }else{
                $output .= '    plugin_insertdate_dateFormat : "%Y-%m-%d",' . "\n";
            }
            if ($this->{$rteElements[0]}->plugin_insertdate_timeFormat){
                $output .= '    plugin_insertdate_timeFormat : "' . $this->{$rteElements[0]}->plugin_insertdate_timeFormat.'",' . "\n";
            } else {
                $output .= '    plugin_insertdate_timeFormat : "%H:%M:%S",' . "\n";
            }
            if ($this->{$rteElements[0]}->theme == 'imgmap') {
                $output .= '    extended_valid_elements : "img[usemap|class|src|border=0|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name],map[id|name],area[title|shape|alt|coords|href|target]",' . "\n";
            } else {
                $output .= '    extended_valid_elements : "hr[class|width|size|noshade]",' . "\n";
            }
            $output .= '    template_external_list_url : "' . $baseUrl .'/media/js/tinymce/js/template_list.js",' . "\n";
            if ($this->{$rteElements[0]}->external_link_list_url =! null && $this->{$rteElements[0]}->external_link_list_url != 1) {
                $output .= '    external_link_list_url : "' . $this->{$rteElements[0]}->external_link_list_url . '",' . "\n";
            } else {
                $output .= '    external_link_list_url : "' . $baseUrl .'/media/js/tinymce/js/link_list.js",' . "\n";
            }
            if ($this->{$rteElements[0]}->external_image_list_url =! null && $this->{$rteElements[0]}->external_image_list_url != 1) {
                $output .= '    external_image_list_url : "' . $this->{$rteElements[0]}->external_image_list_url . '",' . "\n";
            }else{
                $output .= '    external_image_list_url : "' . $baseUrl .'/media/js/tinymce/js/image_list.js",' . "\n";
            }
            if ($this->{$rteElements[0]}->flash_external_list_url =! null && $this->{$rteElements[0]}->flash_external_list_url != 1) {
                $output .= '    flash_external_list_url : "' . $this->{$rteElements[0]}->flash_external_list_url . '",' . "\n";
            }else{
                $output .= '    media_external_list_url : "' . $baseUrl .'/media/js/tinymce/js/media_list.js",' . "\n";
            }
            //$output .= '});' . "\n";
            $output .= '    file_browser_callback : "fileBrowserCallBack",' . "\n";
            $output .= '    cms_cms_browser_callback : "linkBrowserCallBack",' . "\n";
            $output .= '    paste_use_dialog : false,' . "\n";
            $output .= '    template_templates : [';
            if (file_exists(WWW_PATH . '/admin/media/templates/layouts.list')){
                $file = WWW_PATH . '/admin/media/templates/layouts.list';
                if (file_exists(WWW_PATH . '/admin/media/templates/' . $session->lang . '_layouts.list')){
                    $file = WWW_PATH . '/admin/media/templates/' . $session->lang . '_layouts.list';
                }
                $handle = fopen($file, 'r');
                $count = 1;
                while (($data = fgetcsv($handle, 0, ";")) !== FALSE) {
                    if (count($data) != 3) continue;
                    if ($count>1) $output .= ','; 
                    $output .= "\n";
                    $output .= '    		{' . "\n";
                    $output .= '    			title : "' . $data[1] . '",' . "\n";
                    $output .= '    			src : "' . $baseUrl .'/media/templates/' . $data[0] . '",' . "\n";
                    $output .= '    			description : "' . $data[2] . '"' . "\n";
                    $output .= '    		}';
                    $count++;
                }
                $output .= "\n";
            }
            $output .= '    	]' . "\n";
            
            $output .= '});' . "\n";
            $output .= 'function linkBrowserCallBack(field_name, url, type, win) {' . "\n";
            $output .= '    var fileBrowserWindow = new Array();' . "\n";
            $output .= '    fileBrowserWindow[\'title\'] = \'Cms Page Browser\';' . "\n";
            $output .= '    fileBrowserWindow[\'file\'] = "' . Goweb::link('/cms/advlink/') . '";' . "\n";
            $output .= '    fileBrowserWindow[\'width\'] = \'720\'' . "\n";
            $output .= '    fileBrowserWindow[\'height\'] = \'550\'' . "\n";
            $output .= '    fileBrowserWindow[\'close_previous\'] = \'no\'' . "\n";
            $output .= '    fileBrowserWindow[\'close_previous\'] = \'no\'' . "\n";
            $output .= '    fileBrowserWindow[\'inline\'] = \'yes\'' . "\n";
            $output .= '    tinyMCE.activeEditor.windowManager.open(fileBrowserWindow, {' . "\n";
            $output .= '                       window : win,' . "\n";
            $output .= '                       input : field_name' . "\n";
            $output .= '    });' . "\n";
            $output .= '    return false;' . "\n";
            $output .= '}' . "\n";
            $output .= 'function fileBrowserCallBack(field_name, url, type, win) {' . "\n";
            $output .= '    var fileBrowserWindow = new Array();' . "\n";
            $output .= '    fileBrowserWindow[\'title\'] = \'File Browser\';' . "\n";
            $output .= '    fileBrowserWindow[\'file\'] = "' . Goweb::link('/filemanager/browse/section/') . '" + type;' . "\n";
            $output .= '    fileBrowserWindow[\'width\'] = \'720\'' . "\n";
            $output .= '    fileBrowserWindow[\'height\'] = \'655\'' . "\n";
            $output .= '    fileBrowserWindow[\'resizable\'] = \'yes\'' . "\n";
            $output .= '    fileBrowserWindow[\'close_previous\'] = \'no\'' . "\n";
            $output .= '    fileBrowserWindow[\'inline\'] = \'yes\'' . "\n";
            $output .= '    tinyMCE.activeEditor.windowManager.open(fileBrowserWindow, {' . "\n";
            $output .= '                       window : win,' . "\n";
            $output .= '                       input : field_name' . "\n";
            $output .= '    });' . "\n";
            $output .= '    return false;' . "\n";
            $output .= '}' . "\n";
            $output .= '-->' . "\n";
            $output .= '</script>' . "\n";
            $this->_tinyMCE = $output;
        }
        $output .= parent::render($view);
        return $output;
    }
    
    /**
     * Limpar os Decorators, nunca foi usado por default cá,
     * e pode criar confusão com os pintores
     *
     */
    public function clearDecorators(){
        $this->addDecorator('FormElements');
        $this->addDecorator('HtmlTag', array('tag' => null));
        $this->addDecorator('Form');
        $this->setElementDecorators(array('ViewHelper'));
        foreach (array_keys($this->_elements) as $element) {
            if ($this->_elements[$element]->type == 'file'){
                $this->_elements[$element]->setDecorators(array('File'));
            }
        }
    }
    
    /**
     * Obter a criação do elemento <form>
     *
     * @return string
     */
    public function start(){
        $this->clearDecorators();
        $view = $this->getView();
        return ($this->_tinyMCE . "\n" . $view->form($this->getName(), $this->getAttribs(), false));
    }
    
    /**
     * Obter a finalização do elemento <form>
     *
     * @return string
     */
    public function end(){
        return "\n</form>\n";
    }
    
 	/**
     * Este m&eacute;todo devolve um array os nomes dos elementos associados ao formul&aacute;rio.
     *
     * @return  array
     */
    public function getElementsNames() {
        return array_keys($this->_elements);
    }
    
    /**
     * Este pode ser implementado quando for extendido o Goweb_Form.
     * Os elementos deverao ser instanciados neste m&eacute;todo.
     */
    protected function _setup() {}
    
    
   /**
     * M&eacute;todo chamada de m&eacute;todo caso n&atilde;o exista.
     * E utilizado para instanciar din&atilde;micamente o tipo de elemento.
     *
     * @param   $elementType  string  Tipo de coluna
     * @param   $params       array   Array com os parametros
     * @throws  Goweb_Exception  No caso do tipo de elemento n&atilde;o existir
     * @return  Goweb_Form_Element
     */
    public function __call($elementType, $params = array()) {
        $type = 'Goweb_Form_Element_';
        if (!Goweb::isReadable($type . $elementType)) {
            $type = 'Zend_Form_Element_';
            if (!Goweb::isReadable($type . $elementType)) {
                throw new Goweb_Exception('O tipo de elemento "Goweb_Form_Element_' . $elementType . ' n&atilde;o existe.');
            }
        }
        
        if ($elementType == 'File') {
            $this->setEnctype('multipart/form-data');
        }

        if (count($params) > 0) {
            $params = $params[0];
        }
        if (is_string($params)){
            $params = array($params);
        }
        if (!isset($params['name'])) $params['name'] = 'tmp';

        Goweb::loadClass($type . $elementType);
        $elementClassName = $type . $elementType;
        return new $elementClassName($params);
    }    
    
    /**
     * Este m&eacute;todo adiciona um elemento ao formul&aacute;rio.
     *
     * Exemplo:
     *
     * <code>
     * Goweb::loadClass('Goweb_Form');
     *
     * $form = new Goweb_Form();
     *
     * $form->nome = Text();
     * $form->label = 'Nome:';
     * ou
     * $form->nome = Text(array('label', 'Nome:'));
     * </code>
     *
     * @param  string              $name           Nome do elemento
     * @param  Goweb_Form_Element  $element
     */
    public function __set($name,  $element) {
        if (array_key_exists($name, $this->_elements)) {
            throw new Goweb_Exception('O elemento "' . $name . '" je existe no formul&aacute;rio.');
        }

        if (!$element instanceof Zend_Form_Element && !$element instanceof Goweb_Form_Element) {
            throw new Goweb_Exception('O elemento "' . $name . '" n&atilde;o existe no formul&aacute;rio.');
        }
        $element->setName($name);
        $this->_elements[$name] = $element;
    }
    
    /**
     * Validate the form
     *
     * @return boolean
     */
    public function validate(){
        $request = Zend_Controller_Front::getInstance()->getRequest();
        $return = $this->isValid($request->getPost());
        return $return;
    }

    /**
     * Retorna TRUE se o elemento existir no formul&aacute;rio
     *
     * @param   string   $element  Nome do elemento
     * @return  boolean  TRUE se o elemento existir no formul&aacute;rio
     */
    public function elementExists($element) {
        return array_key_exists($element, $this->_elements);
    }
    
    /**
     * Bug-fix de interligaçao goweb-zend
     *
     * @return array
     */
    /*protected function _getErrorMessages(){
        //return array();
    }*/

    /**
     * Bug-fix de interligaçao goweb-zend
     *
     * @return array
     */
    /*public function getErrorMessages(){
        return $this->getMessages();
    }*/
    
    /**
     * Bug-fix de interligaçao goweb-zend
     *
     * @param String $name nome do campo
     * @param mixed $value valor do campo
     */
    public function addHidden($name, $value){
        if (array_key_exists($name, $this->_elements)) {
            throw new Goweb_Exception('O elemento "' . $name . '" je existe no formul&aacute;rio.');
        }
        $this->addElement('hidden', $name);
        $this->_elements[$name]->setValue($value);
    }

    /**
     * Obter as validações de javascript para os elementos
     *
     * @return String
     */
    public function getJsValidateMini() {
        Goweb::loadJavascript('/admin/media/js/prototype.js');
        Goweb::loadJavascript('/admin/media/js/scriptaculous/scriptaculous.js');
        Goweb::loadJavascript('/media/js/livevalidation_prototype.js');
        Goweb::loadJavascript('/media/js/livevalidation_prototype_goweb.js');
        $front = Zend_Controller_Front::getInstance();
        $baseUrl = str_replace(array('/admin', '/index.php'), '',$front->getBaseUrl());
        $imgOk = "<img src=\"" .$baseUrl . "/media/images/button_accept.png\" alt=\"button_accept.png\" class=\"valid_img\" />";
        $imgKO = "<img src=\"" .$baseUrl . "/media/images/button_cancel.png\" alt=\"button_cancel.png\" class=\"invalid_img\" /><span class=\"invalid_txt\">";
        $output = '';
        foreach (array_keys($this->_elements) as $element) {
            if (($this->_elements[$element]->type != 'submit') && ($this->_elements[$element]->type != 'checkbox') &&
            ($this->_elements[$element]->type != 'button') && ($this->_elements[$element]->type != 'file') &&
            ($this->_elements[$element]->type != 'radio') && ($this->_elements[$element]->type != 'multicheckbox') &&
            ($this->_elements[$element]->type != 'file')) {
                $validators = $this->_elements[$element]->getValidators();
                if (count($validators) > 0){
                    if (array_key_exists('Zend_Captcha_Image', $validators)) continue;
                    $output .= "    var $element = new LiveValidation( '" . $this->_elements[$element]->getId() . "', { validMessage: '$imgOk', onlyOnBlur: true";
                    if (array_key_exists('Goweb_Validate_Date', $validators)){
                        $output .= ", insertAfterWhatNode: 'fd-but-" . $this->_elements[$element]->getId() . "'";
                    }
                    $output .= "});\n";
                    $messages = $this->{$element}->getErrorMessages();
                    foreach ($validators as $class => $validator){
                        switch ($class){
                            case 'Goweb_Validate_Required':
                                $message = html_entity_decode((isset($messages['Goweb_Validate_Required']) ? $messages['Goweb_Validate_Required'] : current($messages)) , ENT_NOQUOTES, CHARSET);
                                $message = str_replace(array("'", '/'), array("\'", '\/'), $message);
                                $output .= "        $element.add( Validate.Presence, { failureMessage: '$imgKO" . $message . "<\/span>' } );\n";
                                break;
                            case 'Goweb_Validate_Email':
                                $message = html_entity_decode((isset($messages['Goweb_Validate_Email']) ? $messages['Goweb_Validate_Email'] : current($messages)), ENT_NOQUOTES, CHARSET);
                                $message = str_replace(array("'", '/'), array("\'", '\/'), $message);
                                $output .= "        $element.add( Validate.Email, { failureMessage: '$imgKO" . $message . "<\/span>' } );\n";
                                break;
                            case 'Goweb_Validate_Url':
                                $message = html_entity_decode((isset($messages['Goweb_Validate_Url']) ? $messages['Goweb_Validate_Url'] : current($messages)), ENT_NOQUOTES, CHARSET);
                                $message = str_replace(array("'", '/'), array("\'", '\/'), $message);
                                $output .= "        $element.add( Validate.Url, { failureMessage: '$imgKO" . $message . "<\/span>' } );\n";
                                break;
                            case 'Goweb_Validate_Integer':
                                $message = html_entity_decode((isset($messages['Goweb_Validate_Integer']) ? $messages['Goweb_Validate_Integer'] : current($messages)), ENT_NOQUOTES, CHARSET);
                                $message = str_replace(array("'", '/'), array("\'", '\/'), $message);
                                $output .= "        $element.add( Validate.Numericality, { onlyInteger: true, notANumberMessage: '$imgKO" . $message . "<\/span>' } );\n";
                                break;
                            case 'Goweb_Validate_Length':
                                $params = $validator->getParams();
                                $valor = "";
                                if (array_key_exists('absolut', $params) && $params['absolut']) {
                                    $valor = " is: " . $params['absolut'];
                                } else {
                                    if (array_key_exists('minlength', $params) && $params['minlength']) {
                                        $valor .= " minimum: " . $params['minlength'];
                                    }
                                    if (array_key_exists('maxlength', $params) && $params['maxlength']) {
                                        $valor .= " maximum: " . $params['maxlength'];
                                    }
                                }
                                if (strlen($valor)>0){
                                    $message = html_entity_decode((isset($messages['Goweb_Validate_Length']) ? $messages['Goweb_Validate_Length'] : current($messages)), ENT_NOQUOTES, CHARSET);
                                    $message = str_replace(array("'", '/'), array("\'", '\/'), $message);
                                    $output .= "        $element.add( Validate.Length, {" . $valor . ", tooShortMessage: '$imgKO" . $message . "', tooLongMessage: '$imgKO" . $message . "', wrongLengthMessage: '$imgKO" . $message . "<\/span>' } );\n";
                                }
                                break;
                            case 'Goweb_Validate_Lesser':
                                $params = $validator->getParams();
                                $valor = "";
                                if (array_key_exists('number', $params) && $params['number']) {
                                    $valor = " maximum: " . $params['number'];
                                }
                                if (strlen($valor)>0){
                                    $message = html_entity_decode((isset($messages['Goweb_Validate_Lesser']) ? $messages['Goweb_Validate_Lesser'] : current($messages)), ENT_NOQUOTES, CHARSET);
                                    $message = str_replace(array("'", '/'), array("\'", '\/'), $message);
                                    $output .= "        $element.add( Validate.Numericality, {" . $valor . ", failureMessage: '$imgKO" . $message . "<\/span>' } );\n";
                                }
                                break;
                            case 'Goweb_Validate_SameAs':
                                $elementSame = $validator->getElement();
                                $message = html_entity_decode(isset($messages['Goweb_Validate_SameAs']) ? $messages['Goweb_Validate_SameAs'] : current($messages), ENT_NOQUOTES, CHARSET);
                                $message = str_replace(array("'", '/'), array("\'", '\/'), $message);
                                $output .= "        $element.add( Validate.Confirmation, { match: '" . $elementSame . "', failureMessage: '$imgKO" . $message . "<\/span>' } );\n";
                                break;
                            case 'Goweb_Validate_Date':
                                $message = html_entity_decode((isset($messages['Goweb_Validate_Date']) ? $messages['Goweb_Validate_Date'] : current($messages)), ENT_NOQUOTES, CHARSET);
                                $message = str_replace(array("'", '/'), array("\'", '\/'), $message);
                                $output .= "        $element.add( Validate.Date, { failureMessage: '$imgKO" . $message . "<\/span>' } );\n";
                                break;
                        }

                    }


                }
            } else if ($this->_elements[$element]->type == 'multicheckbox'){
                /**
                 * @todo fix para forçar a que pelo menos um elemento esteja seleccionado
                 */
                if(!$this->_elements[$element]->isArray()){
                    $output .= '$("'.$this->getName().'").getInputs("checkbox","'.$element.'[]").each(function(element){' . "\n";
                    $output .= 'Event.observe(element, "click", function(event) {' . "\n";
                    $output .= '     var aGroup = this.parentNode.parentNode;' . "\n";
                    $output .= ' var allInputs = aGroup.getElementsByTagName("input");' . "\n";
                    $output .= ' for (var i = 0; i < allInputs.length; i++) {' . "\n";
                    $output .= '  if (allInputs[i] == this) {' . "\n";
                    $output .= '   continue;' . "\n";
                    $output .= '  } else {' . "\n";
                    $output .= '   allInputs[i].checked = false;' . "\n";
                    $output .= '  }' . "\n";
                    $output .= ' }' . "\n";
                    $output .= '});' . "\n";
                    $output .= '});' . "\n";
                }
            } else if ($this->_elements[$element]->type == 'checkbox'){
                $validators = $this->_elements[$element]->getValidators();
                if (count($validators) > 0){
                    if (array_key_exists('Zend_Captcha_Image', $validators)) continue;
                    $output .= "    var $element = new LiveValidation( '" . $this->_elements[$element]->getId() . "', { validMessage: '$imgOk', onlyOnBlur: true";
                    if (array_key_exists('Goweb_Validate_Date', $validators)){
                        $output .= ", insertAfterWhatNode: 'fd-but-" . $this->_elements[$element]->getId() . "'";
                    }
                    $output .= "});\n";
                    $messages = $this->{$element}->getErrorMessages();
                    foreach ($validators as $class => $validator){
                        switch ($class){
                            case 'Goweb_Validate_Required':
                                $message = html_entity_decode((isset($messages['Goweb_Validate_Required']) ? $messages['Goweb_Validate_Required'] : current($messages)) , ENT_NOQUOTES, CHARSET);
                                $message = str_replace(array("'", '/'), array("\'", '\/'), $message);
                                $output .= "        $element.add( Validate.Acceptance, { failureMessage: '$imgKO" . $message . "<\/span>' } );\n";
                                break;
                        }
                    }
                }
            }
        }
        return $output;
    }
        
    
    /**
     * Obter as validações de javascript completas
     *
     * @return String
     */
    public function getJsValidate() {
        goweb::loadJavascript('/admin/media/js/prototype.js');
        goweb::loadJavascript('/admin/media/js/scriptaculous/scriptaculous.js');
        goweb::loadJavascript('/media/js/livevalidation_prototype.js');
        goweb::loadJavascript('/media/js/livevalidation_prototype_goweb.js');
        $output = "\n" .'<script  type="text/javascript" defer="defer">' . "\n";
        $output .= '/* <![CDATA[ */' . "\n";
        /**
         * eh necessario que seja uma funcao por causa do calendario, que eh criado
         * dinamicamente e o elemento do insertAfterWhatNode ainda nao existe
         * quando o formulario eh desenhado
         */
        $output .= "function init_" . $this->getName() . "_validate(){\n";
        $output .= $this->getJsValidateMini();
        $output .= '}' . "\n";
        
        
        $output .= "$('" . $this->getName() . "').addClassName('LV_form_to_validate');\n";
        $output .= "Event.observe(window, 'load', init_" . $this->getName() . "_validate, false);". "\n";
        $output .= ' /* ]]> */
 </script>';
        return $output;
    }
    
    /**
     * Este m&eacute;todo limpa todos os valores dos elementos.
     */
    public function cleanValues() {
        foreach (array_keys($this->_elements) as $element) {
            if (($this->_elements[$element]->type != 'submit') &&
                ($this->_elements[$element]->type != 'button') && ($this->_elements[$element]->type != 'image')) {
                $this->_elements[$element]->value = null;
            }
        }
    }
    
}