<?php

Goweb::loadClass('Goweb_Controller_Action');

/**
 * Goweb Sitemanager 5 Framework
 * @version    5.0.19
 * @category   Frontoffice
 * @package    Index
 * @subpackage Controller
 * @author     I&D <dev@goweb.pt>, Pedro Pinto <ppinto@goweb.pt>
 * @copyright  2010 (c) Goweb (http://www.goweb.pt)
 *
 * A classe _Controller para o Front-Office disponibiliza
 * as accoes referentes a cada Modulo.
 *
*/
class Index_GenericController extends Goweb_Controller_Action {
    
    /**
     * Obter valores de um model por json
     *
     * @return string JSON encoded object
     */
    public function jsonModelAction(){
        $this->_helper->viewRenderer->setNoRender();
        if (!$this->_request->isAjax()){
            return false;
        }
        $model = goweb::getModelInstance($this->_request->model, 'db', false);
        list ($field, $value) = explode('-', $this->_request->id);
        $foreignModelName = $model->getCol($field)->getParam('model');
        $foreignModel = Goweb::getModelInstance($foreignModelName, $model->getAdapter(), false, true);
        
       	$key = $foreignModel->getPrimary();
       	$label = $foreignModel->getToString();
       	$model_value = $this->_request->getParam('model_value');
       	$treeValue = array();
       	if ($model_value && $this->_validateId($model_value)){
       	    if ($model->find($model_value)){
       	        $treeValue = $model->{$field} ? unserialize($model->{$field}) : array();
       	    }
       	}

       	if (!$foreignModel->colExists($key)) {
       	    throw new Goweb_Exception("O campo '$key' nao existe no model '" . get_class($foreignModel) . "'");
       	} else if (!$foreignModel->colExists($label)) {
       	    throw new Goweb_Exception("O campo '$label' nao existe no model '" . get_class($foreignModel) . "'");
       	}
       	$foreignModel->where('pai_id=?', $value);
       	$rowset = $foreignModel->fetchAll();
       	$nodes = array('nodes');
       	if ($rowset){
       	    foreach ($rowset as $row){
       	        $attribs = array();
       	        if (in_array($row->{$key}, $treeValue)) $attribs['checked'] = true;
       	        $node= array(
       	        'id' => $field.'-'.$row->{$key},
       	        'type' => 'node',
       	        'data' => $this->view->formCheckbox($field.'['.$row->{$key}.']', $row->{$key}, $attribs).$row->{$label}
       	        );
       	        if (!$foreignModel->findBy('pai_id', $row->{$key})){
       	            $node['type'] = 'leafnode';
       	        }
       	        $nodes['nodes'][] = $node;
       	    }
       	}
       	$this->_helper->json($nodes);
    }
    
    /**
     * Obter os valores necessários para um autocomplete baseado no scriptaculous
     *
     * @return String contendo xhtml
     */
    public function ajaxAutocompleteAction(){
        $this->_helper->viewRenderer->setNoRender();
        if (!$this->_request->isAjax()){
            $this->_helper->viewRenderer->setNoRender();
            return false;
        }

        /**
         * @see Goweb_Db_Model
         */
        $model = goweb::getModelInstance($this->_request->model, 'db', false);

        $colName = $this->_request->col;
        $value = $this->_request->{$colName};
        if (!$model->colExists($colName)){
            throw new Goweb_Exception("O campo '$colName' nao existe no model '" . get_class($model) . "'");
        }
        if (!strlen($value)){
            throw new Goweb_Exception("O campo '$colName' foi passado com o valor '" . $value . "' que n&atilde;o &eacute; v&aacute;lido");
        }
        
        $key = $model->getPrimary();
        $label = $model->getToString();
        $autoComplete = $model->getCol($colName)->getParam('auto_complete');
        if (is_null($autoComplete) || $autoComplete['fullSearch']){
            $model->where($colName . ' LIKE "%' . $value . '%"');
        } else if ($autoComplete['partialSearch']){
            $model->where($colName . ' LIKE "' . $value . '%"');
        } else {
            $model->where($colName . '= ?',  $value);
        }

        $limit = $autoComplete['choices'] && is_numeric($autoComplete['choices']) && $autoComplete['choices'] > 0 ?  $autoComplete['choices'] : 10;
        $model->limit($limit);
        $model->order($label);
        $model->distinct();
        $rowset = $model->fetchAll(array($label));
        $data = array();
        if ($rowset){
            foreach ($rowset as $row) {
                $data[] = html_entity_decode($row->{$label}, ENT_NOQUOTES, CHARSET);
            }
        }        
        $this->_helper->AutoCompleteScriptaculous($data);
    }
    
    /**
     * Usado para actualizar as select boxes entre si
     *
     * @deprecated mantido para compatibilidade
     * @return String contendo xhtml
     */
    public function updateSelectAction(){
        $this->_helper->viewRenderer->setNoRender();
        if (!$this->_request->isAjax()){
            return false;
        }
        $model = goweb::getModelInstance($this->_request->model, 'db', false);

        $field = $this->_request->field;
        $column = $this->_request->column;
        $value = $this->_getParam($column);
        if(!$value) $value = $this->_request->{$column};
        if(!$value) $value = 0;
        if (!$model->colExists($field)){
            throw new Goweb_Exception("O campo '$field' nao existe no model '" . get_class($model) . "'");
        }
        $foreignModelName = $model->getCol($field)->getParam('model');
        $foreignModel = Goweb::getModelInstance($foreignModelName, $model->getAdapter(), false, true);
       	$key = $foreignModel->getPrimary();
       	$label = $foreignModel->getToString();

       	if (!$foreignModel->colExists($key)) {
       	    throw new Goweb_Exception("O campo '$key' nao existe no model '" . get_class($foreignModel) . "'");
       	} else if (!$foreignModel->colExists($label)) {
       	    throw new Goweb_Exception("O campo '$label' nao existe no model '" . get_class($foreignModel) . "'");
       	} else if (!$foreignModel->colExists($column)) {
       	    throw new Goweb_Exception("O campo '$column' nao existe no model '" . get_class($foreignModel) . "'");
       	}
       	$foreignModel->where($column . ' = ?', $value);
       	$foreignModel->order($label);
       	$rowset = $foreignModel->fetchAll();

       	
       	goweb::loadClass('Goweb_Form_Element_Select');
       	$field_select = new Goweb_Form_Element_Select($field);
       	if ($model->getCol($field)->getParam('update')){
       	    $campos = $model->getCol($field)->getParam('update');
       	    if (is_array($campos)){
       	        $onChange = "";
       	        foreach ($campos as $campo){
       	            if (!$model->colExists($campo)){
   	                    throw new Goweb_Exception("O campo '$campo' nao existe no model '" . get_class($model) . "'");
       	            }
       	            $onChange .= 'updateSelect("' . str_replace('/admin', '', Goweb::link('/index/updateSelect/')) . '","' . get_class($model) . '", "' . $field . '", "' . $campo . '", this.options[this.selectedIndex].value);';
       	        }
       	    } else {
       	        if (!$model->colExists($campos)){
   	                throw new Goweb_Exception("O campo '$campos' nao existe no model '" . get_class($model) . "'");
       	        }
       	        $onChange = 'updateSelect("' . str_replace('/admin', '', Goweb::link('/index/updateSelect/')) . '","' . get_class($model) . '", "' . $field . '", "' . $campos . '", this.options[this.selectedIndex].value);';
       	    }

       	    $field_select->setAttrib('onchange', $onChange);
       	}

       	$options = array();
       	$options[] = html_entity_decode(translate('Escolha uma op&ccedil;&atilde;o'), ENT_NOQUOTES, CHARSET);
       	if ($rowset){
       	    foreach ($rowset as $row) {
       	        $options[$row->{$key}] = html_entity_decode($row->{$label}, ENT_NOQUOTES, CHARSET);
       	    }
       	}
       	$field_select->options = $options;

        $field_select->setDecorators(array('ViewHelper', array()));
       	echo $field_select->render();

    }

    /**
     * Usado para actualizar as select boxes entre si
     *
     * @return String contendo xhtml
     */
    public function gowebUpdateSelectAction(){
        $this->_helper->viewRenderer->setNoRender();
        if (!$this->_request->isAjax()){
            return false;
        }
        $model = goweb::getModelInstance($this->_request->model, 'db', false);

        $field = $this->_request->field;
        $column = $this->_request->column;
        $value = $this->_getParam($column);
        if(!$value) $value = $this->_request->{$column};
        if(!$value) $value = 0;
        if (!$model->colExists($field)){
            throw new Goweb_Exception("O campo '$field' nao existe no model '" . get_class($model) . "'");
        }
        $foreignModelName = $model->getCol($field)->getParam('model');
        $foreignModel = Goweb::getModelInstance($foreignModelName, $model->getAdapter(), false, true);
        $key = $foreignModel->getPrimary();
        $label = $foreignModel->getToString();

        if (!$foreignModel->colExists($key)) {
            throw new Goweb_Exception("O campo '$key' nao existe no model '" . get_class($foreignModel) . "'");
        } else if (!$foreignModel->colExists($label)) {
            throw new Goweb_Exception("O campo '$label' nao existe no model '" . get_class($foreignModel) . "'");
        } else if (!$foreignModel->colExists($column)) {
            throw new Goweb_Exception("O campo '$column' nao existe no model '" . get_class($foreignModel) . "'");
        }
        $foreignModel->where($column . ' IN (' . $value . ')');
        $foreignModel->order($label);
        $rowset = $foreignModel->fetchAll();
        if ($model->getCol($field)->getType() != 'ForeignKeyMultiple') {
            echo '<option value="" label="' . html_entity_decode(translate('Escolha uma op&ccedil;&atilde;o'), ENT_NOQUOTES, CHARSET) . '">' . html_entity_decode(translate('Escolha uma op&ccedil;&atilde;o'), ENT_NOQUOTES, CHARSET) . '</option>' . "\n";
        }

        if ($rowset){
            foreach ($rowset as $row) {
                echo '<option value="' . $row->{$key} . '" label="' . html_entity_decode($row->{$label}, ENT_NOQUOTES, CHARSET) . '">' . html_entity_decode($row->{$label}, ENT_NOQUOTES, CHARSET) . '</option>' . "\n";
            }
        }
    }

    /**
     * Usado para obter o url, a ser usado em javascript, com ajax
     *
     * @return string
     */
    public function addTranslateAction(){
        $this->_helper->viewRenderer->setNoRender();
        if (!$this->_request->isPost() || !$this->_request->isAjax() || !$this->_request->text){
            return false;
        }
        echo translate(str_replace("%26", "&", $this->_request->text));
    }
    
    /**
     * Usado para obter o url, a ser usado em javascript, com ajax
     *
     * @return string
     */
    public function getUrlAction(){
        $this->_helper->viewRenderer->setNoRender();
        if (!$this->_request->isPost() || !$this->_request->isAjax() || !$this->_request->url){
            return false;
        }
        echo goweb::link($this->_request->url);
    }
    
    /**
     * Acção para obter o formulário para a criação de password aleatória
     *
     */
    public function randomPasswordAction(){
        if (!$this->_request->isAjax()){
            $this->_helper->viewRenderer->setNoRender();
            return false;
        }
        $this->view->name = $this->_request->campo;
        $this->view->setViewsPath(GENERIC_VIEWS_PATH);
    }
    
    /**
     * Acção para obter o formulário para mudar de categoria em Modal Box
     *
     */
    public function treeSelectAction(){

        if (!$this->_request->isAjax()){
             $this->_helper->viewRenderer->setNoRender();
            return false;
        }
        
        $model = goweb::getModelInstance($this->_request->model, 'db', false);

        $field = $this->_request->field;
        $colName = $this->_request->col;
        $link = $this->_request->link;
        if (!$link) $link = null; 
        if (!$colName) $colName='pai_id';
        $baseUrl = str_replace(array('/admin', '/index.php'), '', Zend_Controller_Front::getInstance()->getRequest()->getBaseUrl());
        $tree = $this->_getModelTree($model, array('id'=> 'id', 'pid' => 'pai_id', 'name' => $model->getToString()), $colName, $link);
        Goweb::loadClass('Goweb_Js_TafelTree');
        Goweb::loadCss('/admin/media/js/tafelTree/css/tree.css');
        Goweb::loadJavascript('/admin/media/js/prototype.js');
        Goweb::loadJavascript('/admin/media/js/scriptaculous/scriptaculous.js');
        Goweb::loadJavascript('/admin/media/js/tafelTree/Tree-optimized.js');
        $tafelTree = new Goweb_Js_TafelTree($colName . '_tafelTree',
        $baseUrl . '/admin/media/js/tafelTree/imgs/',
        null, null, array(
                        	'generate' => true,
                        	'defaultImg'=>'page.gif',
                        	'defaultImgOpen' => 'folderopen.gif',
    						'defaultImgClose' => 'folder.gif',
                        	'cookies' => false,
                            'openAtLoad' => false,
                        	'lineStyle'=>'full'));
        $tree->build(0);
        $tafelTree->setTreeElements($tree->getTree());
        goweb::loadClass('Goweb_Form_Element_TafelTree');
        ${$colName . '_tafel'} = new Goweb_Form_Element_TafelTree(array('name' => $colName));
        ${$colName . '_tafel'}->setTree($tafelTree);
        $this->view->output = ${$colName . '_tafel'}->render();
        $this->view->setViewsPath(GENERIC_VIEWS_PATH);
        $this->_helper->viewRenderer->setRender('tafel-tree');
    }
    
    /**
     * Acao executada se nenhuma outra acao for especificada
     */
    public function indexAction() {
        $this->_forward('index', 'cms');
    }

    /**
     * Acao executada se a acao chamada nao existir neste modulo
     *
     * @param string
     * @param array
    */
    public function __call($action, $arguments) {
        $this->_forward('index', 'cms');
    }
    
    /**
     * Criar arvore
     *
     * @param Goweb_Db_Model $model
     * @param array $nodesParams
     * @return Goweb_Js_Tree
     */
    protected function _getModelTree($model = 'Cms_Model_Pagina', $nodesParams = array('id'=> 'id', 'pid' => 'pai_id', 'name' => 'titulo'), $colName = null, $link = null) {
        
        if (is_string($model)) $model = goweb::getModelInstance($model, 'db', false);

        // valida se foram passados os campos necesserio para o node
        if (!array_key_exists('id', $nodesParams)) {
            throw new Goweb_Exception("O campo  'id' &eacute; necess&aacute;rio nos par&aacute;metros dos nodes.");
        }
        if (!array_key_exists('pid', $nodesParams)) {
            throw new Goweb_Exception("O campo  'pid' &eacute; necess&aacute;rio nos par&aacute;metros dos nodes.");
        }
        if (!array_key_exists('name', $nodesParams)) {
            throw new Goweb_Exception("O campo  'name' &eacute; necess&aacute;rio nos par&aacute;metros dos nodes.");
        }

        $idCol = $nodesParams['id'];
        $pidCol = $nodesParams['pid'];
        $nameCol = $nodesParams['name'];
        $model->loadForeigns(false);
        Goweb::loadClass('Goweb_Tree');
        $tree = new Goweb_Tree($idCol, $pidCol);
        if ($model->colExists('ordem')) $model->order('ordem'); // ordena as paginas pelo campo ordem da bd
        
        $cols = array($idCol, $pidCol, $nameCol, 'redireccionar');
        foreach ($cols as $key => $col){
            if (!$model->colExists($col)) unset($cols[$key]);
        }
        $rowset = $model->fetchAll($cols);
        if (!is_null($colName)){
            if (is_null($link)){
                $link = "$(\"{{colName}}\").value=\"{{id}}\";";
            } else {
                $link = "$(\"{{colName}}\").value=\"" . $link . "\";";
            }
        }
        $link = str_replace('{{colName}}', $colName, $link);
        $link .= "Modalbox.hide(); return false;";

        if ($rowset) {
            foreach ($rowset as $row) {
                $titulo = $row->{$nameCol};
                if (!is_null($colName)){
                    $titulo = "<a href='' onclick='" . $link . "'>" . $titulo . "</a>";
                    $titulo = str_replace('{{id}}', $row->{$idCol}, $titulo);
                    
                }
                $node = array($idCol => $row->{$idCol},
                $pidCol => $row->{$pidCol},
                $nameCol => $titulo);

                // adiciona o node
                $tree->addElement($node);
            }
        }

        // retorna o Goweb_Js_Tree
        return $tree;
    }
    
}
