<?php

Goweb::loadClass('Goweb_Controller_Action');
Goweb::loadClass('Goweb_View');
Goweb::loadClass('Goweb_Paginator');
Goweb::loadClass('Goweb_Js_JSCookMenu');

/**
 * Goweb Sitemanager 5 Framework
 * @version    5.1.5
 * @category   Frontoffice
 * @package    Catalogo
 * @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 Catalogo_GenericController extends Goweb_Controller_Action {

    /**
     * Cache para queries manuais
     *
     * @var Zend_Cache_Core
     */
    protected $_customCache = null;

    /**
     * string dummy para o url amigável
     *
     * @var String
     */
    protected $_goString = 'go';

    /**
     * string com o separador para o título da página
     *
     * @var String
     */
    protected $_goSeparator = ' / ';

    /**
     * canal a ser usado neste controller
     *
     * @var String
     */
    protected $_canal = 'base';

    /**
     * Objecto Catalogo_Model_Categoria
     *
     * @var Catalogo_Model_Categoria
     */
    protected $_categoriaModel = null;

    /**
     * Objecto Catalogo_Model_Produto
     *
     * @var Catalogo_Model_Produto
     */
    protected $_produtoModel = null;

    /**
     * Objecto Goweb_Config_Ini
     *
     * @var Goweb_Config_Ini
     */
    protected $_moduleConfig = null;

    /**
     * Array com o caminho do produto
     */
    protected $_path = array();

    /**
     * Construtor da classe
     */
    public function init() {
        $this->_moduleConfig = new Goweb_Config(Goweb_Config_Ini::load(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'config.ini', 'base'));
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Catalogo');
        $this->view->moduleConfig = $this->_moduleConfig;
        $this->_categoriaModel = Goweb::getModelInstance('Catalogo_Model_Categoria', 'db', false);
        $this->_produtoModel = Goweb::getModelInstance('Catalogo_Model_Produto', 'db');
        $this->view->imagens_upload_path = $this->_moduleConfig->images->target . '/';
        $this->view->ficheiros_upload_path = $this->_moduleConfig->files->target . '/';
        $this->view->loadCss('/media/css/catalogo.css');
        $this->_customCache = Zend_Registry::get('cache');
        if($this->_moduleConfig->cambios->activo) {
            $this->setCambiosSessionAction();
        }
    }

    /**
     * Acao executada se nenhuma outra acao for especificada
     */
    public function indexAction() {
        if ($this->_produtoModel->colExists('url')){
            $sub = $this->_getLinkStart();
            $pathInfo = str_replace($sub, '', $this->_request->getPathInfo());
            if ($pathInfo == '/') $pathInfo = '';
            if ($pathInfo && 
                    ($this->_produtoModel->findBy('url', $pathInfo) || 
                    $this->_produtoModel->findBy('url', substr($pathInfo, 1)))){
                        $this->_setParam('id', $this->_produtoModel->id);
                        return $this->detailAction();
            }
            if ($this->_categoriaModel->colExists('url') && $pathInfo && 
                    ($this->_categoriaModel->findBy('url', $pathInfo) || 
                    $this->_categoriaModel->findBy('url', substr($pathInfo, 1)))){
                        $this->_setParam('categoria_id', $this->_categoriaModel->id);
                        return $this->listAction();
            }
        }
        return $this->listAction();
    }

    /**
     * Desenha opção escolha se moeda
     */
    public function formCambiosAction(){
        if ($this->_directRequest) { // significa que foi chamado directamente.
            Goweb::loadClass('Cms_Controller', APPLICATION_PATH);
            Cms_Controller::renderOutput($this->view,
                                        'form_cambio.tpl',
                                        'Seleccionar Moeda',
                                        'catalogo-form-Cambio',
            translate('Seleccionar Moeda'));
            $this->_helper->viewRenderer->setRender($this->_canal);
        } else {
            $this->_helper->viewRenderer->setRender('form_cambio');
        }
    }

    /**
     * Listar produtos ou categorias
     *
     * Se houver sub-categorias entao listar as categorias
     * Senao, listar os produtos daquela categoria
     */
    public function listAction() {
        $categoriaId = $this->_getParam('categoria_id');

        if (!$categoriaId) {
            $categoriaId = 0;
        }

        if ($this->_categoriaModel->colExists('url')){
            $sub = $this->_getLinkStart();
            $pathInfo = str_replace($sub, '', $this->_request->getPathInfo());
            if ($pathInfo == '/') $pathInfo = '';
            $translate = Zend_Controller_Router_Route::getDefaultTranslator();
            if (is_numeric(strpos($pathInfo, ($translate ? $translate->_('list') : 'list') . '/categoria_id')) && $this->_categoriaModel->find($categoriaId) && $this->_categoriaModel->url){
                return $this->_redirect($sub . '/' . $this->_categoriaModel->url . ($this->_request->page ? '?page=' . $this->_request->page : ''), array('code' => 301));
            }
        }

        if ($categoriaId == 0 || ($this->_validateId($categoriaId) && $this->_categoriaModel->find($categoriaId) && $this->_categoriaModel->activo)) {
            $this->_categoriaModel->order('ordem');
            $this->_categoriaModel->where($this->_categoriaModel->getTableName() . '.pai_id = ?', $categoriaId);
            $this->_categoriaModel->where($this->_categoriaModel->getTableName() . '.activo = 1');
            $this->_resultCategorias = $this->_categoriaModel->count();
            if ($this->_resultCategorias > 0) {
                return $this->listCategoriasAction($categoriaId);
            } else {
                return $this->listProdutosAction();
            }
        } else {
            return $this->listProdutosAction();
        }
    }

    /**
     * Listagem dos Produtos
     */
    public function listProdutosAction() {
        $page = $this->_request->page > 0 ? $this->_request->page : '1';

        // menu
        $menu = new Goweb_Js_JSCookMenu('categorias');

        // categoria_id
        $categoriaId = $this->_getParam('categoria_id');
        $rows = $this->_getParam('rows');
        $this->view->rows='';
        if ($this->_validateId($rows)) {
            $this->view->rows = '/rows/' . $rows;
        }
        if ($this->_validateId($categoriaId) && $this->_categoriaModel->find($categoriaId) && $this->_categoriaModel->activo) {
            $categoria = $this->_categoriaModel->getRow();
        } else {
            $categoria = null;
            $categoriaId = 0;
        }

        $this->view->categoria_id = $categoriaId;

        // paginator
        $this->_produtoModel->where($this->_produtoModel->getTableName() . '.categoria_id=?', $categoriaId);
        $this->_produtoModel->where($this->_produtoModel->getTableName() . '.activo=?', '1');
        $paginator = new Goweb_Paginator(Goweb::link('/catalogo/list/categoria_id/' . $categoriaId . $this->view->rows . '/', 'page='),
        $this->_produtoModel->count(),
        $page,
        $rows ? $rows : $this->_moduleConfig->paginator->rows_per_page,
        $this->_moduleConfig->paginator->links_per_page);

        $this->view->paginator = $paginator;
        $this->view->setViewsPath(GENERIC_VIEWS_PATH);
        $this->view->paginator_output = $this->view->render('paginator.tpl');

        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Catalogo');

        // parametro para associar loja
        $this->view->loja = $this->_moduleConfig->loja->activa;

        // categorias
        $this->_categoriaModel->where($this->_categoriaModel->getTableName() . '.activo=?', '1');
        $this->_categoriaModel->loadForeigns(false);
        $this->_categoriaModel->order('ordem');
        $categoriasRowset = $this->_categoriaModel->fetchAll();
        $categorias = null;
        $categoriasList = array();
        if ($categoriasRowset) {
            foreach ($categoriasRowset as $row) {
                $menu->addNode($row->id,
                $row->pai_id,
                $row->titulo,
                               '',
                Goweb::link('/catalogo/list/categoria_id/' . $row->id . $this->view->rows .'/'));
            }
            $categoriasList = $menu->build(0);
        }
        $this->view->categorias_list = $categoriasList;

        // produtos
        $this->_produtoModel->where($this->_produtoModel->getTableName() . '.categoria_id=?', $categoriaId);
        $this->_produtoModel->where($this->_produtoModel->getTableName() . '.activo=?', '1');
        $this->_produtoModel->order('ordem');
        $this->_produtoModel->limitPage($paginator->getPage(), $paginator->getRowsPerPage());
        $this->view->produtos = $this->_produtoModel->fetchAll();
        $this->view->detail_url = '/catalogo/detail/id/';

        $titulo = $this->_caminho('0', $categoriaId);

        // cms
        if ($this->_directRequest) { // significa que foi chamado directamente.
            Goweb::loadClass('Cms_Controller', APPLICATION_PATH);
            Cms_Controller::renderOutput($this->view,
                                        'list.tpl',
                                        'Catalogo',
                                        'catalogo-list',
            translate('PRODUTOS') . ' > ' . $titulo,
            $this->_getParam('print'));
            $this->_helper->viewRenderer->setRender($this->_canal);
        } else {
            $this->_helper->viewRenderer->setRender('list');
        }
    }

    /**
     * Listagem das categorias
     */
    public function listCategoriasAction($categoriaId = 0) {
        $rows = $this->_getParam('rows');
        $this->view->rows='';
        if ($this->_validateId($rows)) {
            $this->view->rows = '/rows/' . $rows;
        }
        // lista a arvore das categorias
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Catalogo');

        $categoriaModel = Goweb::getModelInstance('Catalogo_Model_Categoria', 'db', false);
        $db = $categoriaModel->getAdapter();

        $table = $categoriaModel->getTableName();

        $query = 'SELECT * FROM ' . $table . ' WHERE activo = 1 ';
        $query .= ' AND pai_id = ' . $categoriaId;
        $query .= ' ORDER BY ordem';

        /**
         * cache nesta sucatisse, implementar menu como deve ser
         * @todo refazer e manter compatibilidades
         */
        if(($result = $this->_customCache->load(md5($query))) === false) {
            $result = $db->fetchAll($query);
            $this->_customCache->save($result, md5($query));
        }

        if ($result) {
            $this->view->total      = count($result);
            $this->view->categorias = $result;
        } else {
            $this->view->total      = 0;
            $this->view->categorias = false;
        }

        $this->view->categoria_id = $categoriaId;

        $titulo = $this->_caminho('0', $categoriaId);

        if ($this->_directRequest) { // significa que foi chamado directamente.
            Goweb::loadClass('Cms_Controller', APPLICATION_PATH);
            Cms_Controller::renderOutput($this->view,
                                         'categorias.tpl',
                                         'Categorias',
                                         'catalogo-listCategorias',
            translate('PRODUTOS') . ' > ' . $titulo,
            $this->_getParam('print'));
            $this->_helper->viewRenderer->setRender($this->_canal);
        } else {
            $this->_helper->viewRenderer->setRender('categorias');
        }

    }

    /**
     * Visualizar o detalhe do Produto
     */
    public function detailAction() {
        if ($this->_produtoModel->colExists('url')){
            $sub = $this->_getLinkStart();
            $pathInfo = str_replace($sub, '', $this->_request->getPathInfo());
            if ($pathInfo == '/') $pathInfo = '';
            $translate = Zend_Controller_Router_Route::getDefaultTranslator();
            if (is_numeric(strpos($pathInfo, ($translate ? $translate->_('detail') : 'detail') . '/id')) && $this->_produtoModel->find($this->_getParam('id')) && $this->_produtoModel->url){
                return $this->_redirect($sub . '/' . $this->_produtoModel->url, array('code' => 301));
            }
        }
        if ($this->_validateId($this->_getParam('id')) && $this->_produtoModel->find($this->_getParam('id')) && $this->_produtoModel->activo &&
                $this->_produtoModel->categoria->activo) {
            $this->view->produto = $this->_produtoModel->getRow();
            $produtoId = $this->_produtoModel->id;
            $fichaId = $this->_produtoModel->ficha_id;

            // menu
            $menu = new Goweb_Js_JSCookMenu('categorias');

            // categorias
            $this->_categoriaModel->where($this->_categoriaModel->getTableName() . '.activo=?', '1');
            $this->_categoriaModel->loadForeigns(false);
            $this->_categoriaModel->order('ordem');
            $categoriasRowset = $this->_categoriaModel->fetchAll();
            $categorias = null;
            if ($categoriasRowset) {
                foreach ($categoriasRowset as $row) {
                    $menu->addNode($row->id,
                    $row->pai_id,
                    $row->titulo,
                                   '',
                    Goweb::link('/catalogo/list/categoria_id/' . $row->id . '/'));
                }
                $categoriasList = $menu->build(0);
            }
            $this->view->categorias_list = $categoriasList;

            // parametro para associar loja
            $this->view->loja = $this->_moduleConfig->loja->activa;

            // imagens
            $imagemModel = Goweb::getModelInstance('Catalogo_Model_Imagem', 'db', false);
            $imagemModel->where('produto_id=?', $produtoId);
            $this->view->imagens = $imagemModel->fetchAll();

            // ficheiros
            $ficheiroModel = Goweb::getModelInstance('Catalogo_Model_Ficheiro', 'db', false);
            $ficheiroModel->where('produto_id=?', $produtoId);
            $this->view->ficheiros = $ficheiroModel->fetchAll();

            // ficha
            $ficha = null;
            if ($fichaId > 0) {
                $ficha = $this->_getFicha($produtoId, $fichaId);
            }
            $this->view->ficha = $ficha;

            if ($this->_directRequest) { // significa que foi chamado directamente.
                Goweb::loadClass('Cms_Controller', APPLICATION_PATH);
                Cms_Controller::renderOutput($this->view,
                                             'detail.tpl',
                                             'Catalogo',
                                             'catalogo-detail',
                $this->view->produto->titulo . $this->_goSeparator . ($this->_produtoModel->categoria ? $this->_produtoModel->categoria->titulo . $this->_goSeparator : '') .  translate('Detalhe de Produto'),
                $this->_getParam('print'));
                if (!$this->_getParam('print'))
                $this->_helper->viewRenderer->setRender($this->_canal);
            }
        } else {
            $this->view->setViewsPath(VIEWS_PATH);
            $this->getResponse()->setRawHeader('HTTP/1.1 404 Not Found');
            $this->_helper->viewRenderer->setRender('404');
        }
    }

    /**
     * Listagem dos produtos em Destaque
     */
    public function destaquesAction() {
        $nro_produtos = $this->_getParam('nro_produtos');
        if (!$nro_produtos && !$this->_validateId($nro_produtos)) {
            $nro_produtos = 1;
        }

        $this->_produtoModel->where($this->_produtoModel->getTableName() . '.destaque = 1');
        $this->_produtoModel->where($this->_produtoModel->getTableName() . '.activo = 1');
        $categoriaId = $this->_getParam('categoria_id');
        if($this->_validateId($categoriaId)) {
            $this->_produtoModel->where('categoria_id = ' . $categoriaId);
        }
        $this->_produtoModel->limit($nro_produtos, 0);

        $produtos = $this->_produtoModel->fetchAll();
        // parametro para associar loja
        $this->view->loja = $this->_moduleConfig->loja->activa;

        $this->view->produtos = $produtos;
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Catalogo');
        if ($this->_directRequest) { // significa que foi chamado directamente.
            Goweb::loadClass('Cms_Controller', APPLICATION_PATH);
            Cms_Controller::renderOutput($this->view,
                                         'destaque.tpl',
                                         'Catalogo',
                                         'catalogo-destaque',
            translate('Produtos em Destaque'),
            $this->_getParam('print'));
            $this->_helper->viewRenderer->setRender($this->_canal);
        } else {
            $this->_helper->viewRenderer->setRender('destaque');
        }
    }


    /**
     * Este menu suporta niveis infinitos.
     */
    public function unlimitedSlideMenuAction() {
        // paginas
        $session = Goweb::registry('session');
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Catalogo');

        $useLink = '/catalogo/list/categoria_id/';

        //Goweb::dump($session->mypaiId);
        //Goweb::dump($this->_getParam('id_selected'));
        if(!$session->mypaiId){
            //Goweb::dump($session->mypaiId)
            if ($this->_getParam('subpagina')) {
                $this->view->pai_id = $this->_getParam('subpagina');
            } else {
                $this->view->pai_id = '0';
            }
        }

        if($this->_getParam('id_selected')) {
            $id_selected = $this->_getParam('id_selected');
        } else {
            $id_selected = 0;
        }

        $categoriaModel = Goweb::getModelInstance('Catalogo_Model_Categoria', 'db', false);
        $db = $categoriaModel->getAdapter();

        $table = $categoriaModel->getTableName();

        $query = 'SELECT * FROM ' . $table . ' WHERE activo = 1 ';
        if($session->mypaiId){
            $query .= ' AND pai_id = '.$session->mypaiId;
        } else {
            $query .= ' AND pai_id = '.$this->view->pai_id;
        }
        $query .= ' ORDER BY pai_id,ordem';
        /**
         * cache nesta sucatisse, implementar menu como deve ser, com cerca de 100 categorias são feitas mais de 400 queries, o que é incomportável
         * @todo refazer e manter compatibilidades
         */
        if(($result = $this->_customCache->load(md5($query))) === false) {
            $result = $db->fetchAll($query);
            $this->_customCache->save($result, md5($query));
        }

        $struct = '';

        if ($result) {
            $struct .= '<ul>';
            foreach ($result as $item) {
                if($id_selected > 0 && $id_selected == $item['id']){
                    $struct .= "<li id='usm_".$item['id']."'><a name='usm_selected' ";
                } else {
                    $struct .= "<li id='usm_".$item['id']."'><a ";
                }
                if($this->_ifIsParent($item['id'])){
                    $struct .= "href='#'>".$item['titulo'].'</a>';
                } else {
                    $struct .= "href='".$useLink.$item['id']."'>".$item['titulo'].'</a>';
                }
                $this->_getAllSubUSMIds($struct, $item['id'], $useLink, $id_selected);
            }
            $struct .= '</li></ul>';
        }

        $this->view->result = $struct;
        $this->view->rootId = $this->_getParam('subpagina');
        $this->_helper->viewRenderer->setRender('unlimited_slide_menu');
    }

    /**
     *
     * Funcao recursiva auxiliar que cria toda a estrutura em àrvore do menu
     * mediante o id do pai.
     *
     */
    private function _getAllSubUSMIds(&$struct, $id, $useLink, $id_selected=0) {

        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Catalogo');

        $categoriaModel = Goweb::getModelInstance('Catalogo_Model_Categoria', 'db', false);
        $db = $categoriaModel->getAdapter();

        $table = $categoriaModel->getTableName();

        $query = 'SELECT * FROM ' . $table . ' WHERE activo = 1 ';
        $query .= ' AND pai_id = '.$id;
        $query .= ' ORDER BY pai_id,ordem';

        /**
         * cache nesta sucatisse, implementar menu como deve ser, com cerca de 100 categorias são feitas mais de 400 queries, o que é incomportável
         * @todo refazer e manter compatibilidades
         */
        if(($result = $this->_customCache->load(md5($query))) === false) {
            $result = $db->fetchAll($query);
            $this->_customCache->save($result, md5($query));
        }

        if ($result) {
            $struct .= '<ul>';
            foreach ($result as $item) {
                if($id_selected > 0 && $id_selected == $item['id']){
                    $struct .= "<li id='usm_".$item['id']."'><a name='usm_selected' ";
                } else {
                    $struct .= "<li id='usm_".$item['id']."'><a ";
                }
                if($this->_ifIsParent($item['id'])){
                    $struct .= "href='#'>".$item['titulo'].'</a>';
                } else {
                    $struct .= "href='".$useLink.$item['id']."'>".$item['titulo'].'</a>';
                }
                $this->_getAllSubUSMIds($struct, $item['id'], $useLink, $id_selected);
            }
            $struct .= '</li></ul>';
        }
        return $struct;

    }

    /**
     *
     * Funcao auxiliar que retorna verdadeiro quanto um certo
     * id tem filhos.
     * Serve para validar se é o ultimo nível ou não para atribuição
     * de um link.
     *
     */
    private function _ifIsParent($id) {

        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Catalogo');

        $categoriaModel = Goweb::getModelInstance('Catalogo_Model_Categoria', 'db', false);
        $db = $categoriaModel->getAdapter();
        $table = $categoriaModel->getTableName();

        $query = 'SELECT * FROM ' . $table . ' WHERE activo = 1 ';
        $query .= ' AND pai_id = '.$id;
        $query .= ' ORDER BY pai_id,ordem';

        /**
         * cache nesta sucatisse, implementar menu como deve ser, com cerca de 100 categorias são feitas mais de 400 queries, o que é incomportável
         * @todo refazer e manter compatibilidades
         */
        if(($result = $this->_customCache->load(md5($query))) === false) {
            $result = $db->fetchAll($query);
            $this->_customCache->save($result, md5($query));
        }

        if ($result) {
            return true;
        } else {
            return false;
        }
    }



    /**
     * Acao para exibir o menu do site
     */
    public function menuAction() {
        $menu_id = $this->_getParam('menu_id');
        if (!$menu_id) {
            $menu_id = 1;
        }

        $menu_nome = 'menu_catalogo_' . $menu_id;

        // menu
        Goweb::loadClass('Goweb_Js_JSCookMenu');
        $menu = new Goweb_Js_JSCookMenu($menu_nome);

        // paginas
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Catalogo');

        $db = $this->_categoriaModel->getAdapter();
        $query = 'SELECT * FROM `' . $this->_categoriaModel->getTableName() . '` WHERE activo = 1 ';
        $query .= ' ORDER BY ordem ';

        /**
         * cache nesta sucatisse, implementar menu como deve ser, com cerca de 100 categorias são feitas mais de 400 queries, o que é incomportável
         * @todo refazer e manter compatibilidades
         */
        if(($result = $this->_customCache->load(md5($query))) === false) {
            $result = $db->fetchAll($query);
            $this->_customCache->save($result, md5($query));
        }

        $pai_id = 0;
        if ($this->_validateId($this->_getParam('pai_id'))) {
            $pai_id = $this->_getParam('pai_id');
        }

        $categorias = null;
        if (count($result) > 0) {
            foreach ($result as $categoria) {
                $menu->addNode($categoria['id'],
                $categoria['pai_id'],
                $categoria['titulo'],
                               '',
                Goweb::link('/catalogo/list/categoria_id/' . $categoria['id'] . '/'));
            }
            $categorias = $menu->build($pai_id);
        }

        $this->view->menu_nome = $menu_nome;

        $this->view->categorias = $categorias;
        $this->_helper->viewRenderer->setRender('menu');
    }

    /**
     * Esta acao disponibiliza os produtos em formato RSS
     */
    public function rssAction() {
        $this->_helper->viewRenderer->setNoRender();
        if (!$this->_moduleConfig->rss || !$this->_moduleConfig->rss->activo) return false;
        $config = Goweb::registry('config');
        $format = $this->_request->getParam('format');
        $format = in_array($format, array('rss', 'atom')) ? $format : 'rss';

        $this->_produtoModel->where($this->_produtoModel->getTableName() . '.activo = 1');
        $this->_produtoModel->order('ordem');
        $rowset = $this->_produtoModel->fetchAll();
        $channel = array('title'      => translate('Produtos'),
                        'link'        => $this->_getServerName(),
                        'description' => translate('Goweb - Produtos'),
                        'charset'     => 'UTF-8',
        				'published'   => time(),
        				'generator'   => translate('Goweb_Rss'),
        				'author'      => $config->mail->from_email,
        				'webmaster'   => $config->mail->from_email,
                        'entries'     => array());
        if ($rowset){
            foreach ($rowset as $item) {
                if ($item->descricao) {
                    $description = htmlentities($item->descricao);
                } else {
                    $description = htmlentities($item->titulo);
                }
                
                $entry = array(
                         'title'       => $item->titulo,
                         'link'        => $this->_getServerName() . $this->view->link('/catalogo/detail/id/' . $item->id . '/'),
                		 'guid'        => $this->_getServerName() . $this->view->link('/catalogo/detail/id/' . $item->id . '/'),
                         'description' => $description,
                         'lastUpdate'  => mktime(8, 0, 0, date('m'), date('d'), date('Y'))
                         );
                if ($item->imagem) {
                    if (file_exists(WWW_PATH . $this->_moduleConfig->images->target . '/' . 'big_' . $item->imagem)) {
                        $entry['enclosure'] = array();
                        $entry['enclosure'][] = array('url' => $this->_getServerName() . $this->view->baseUrl .
                                                    $this->_moduleConfig->images->target . '/' . 'big_' . $item->imagem,
                                               	  'length' => filesize(WWW_PATH . $this->_moduleConfig->images->target . '/' . 'big_' . $item->imagem),
                        					   	  'type' => mime_content_type(WWW_PATH . $this->_moduleConfig->images->target . '/' . 'big_' . $item->imagem));
                    }
                }
                         
                $channel['entries'][] = $entry;
            }
        }
        goweb::loadClass('Zend_Feed');
        $feed = Zend_Feed::importArray($channel, $format);
        $feed->send();

    }

    /**
     * Metodo responsavel pelo resultado da pesquisa
     */
    public function resultadoPesquisaAction() {
        $invalidChars = array('<', '>', '"', '\'');
        $palavra = str_replace($invalidChars, '', $this->_request->palavra);

        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Catalogo');

        if (strlen($palavra) > 2) {
            $this->_produtoModel->loadForeigns(false);
            $table = $this->_produtoModel->getTableName();
            $this->_produtoModel->where($table . '.activo > 0 AND (' . $table . '.titulo LIKE "%{$palavra}%" OR ' . $table . '.descricao LIKE "%{$palavra}%")');
            $this->view->resultado = $this->_produtoModel->fetchAll();
            $this->view->message = null;
        } else {
            $this->view->resultado = false;
            $this->view->message = translate('Para que a pesquisa apresente resultados eficazes, introduza no m&iacute;nimo 3 caracteres.');
        }

        $moduloModel = Goweb::getModelInstance('Sistema_Model_Modulo', 'db');
        $moduloModel->where('pesquisa > ?', '0');
        $this->view->modulos = $moduloModel->fetchAll();
        $this->view->modulo_pesquisa = 'Catalogo';
        $this->view->palavra = $palavra;

        if ($this->_directRequest) { // significa que foi chamado directamente.
            Goweb::loadClass('Cms_Controller', APPLICATION_PATH);
            Cms_Controller::renderOutput($this->view,
                                        'search.tpl',
                                        'Catalogo',
                                        'catalogo-resultado-pesquisa',
            translate('Pesquisa'),
            $this->_getParam('print'));
            $this->_helper->viewRenderer->setRender($this->_canal);
        } else {
            $this->_helper->viewRenderer->setRender('search');
        }
    }

    /**
     * Funcao para fazer o download do ficheiro associado ao produto
     */
    public function getFileAction() {
        if (($this->_validateId($this->_getParam('id'))) &&
        ($this->_produtoModel->find($this->_getParam('id')))) {

            if ($this->_produtoModel->{$this->_getParam('file')}) {

                $filename = $this->_produtoModel->{$this->_getParam('file')};
                $file_extension = strtolower(substr(strrchr($filename, '.'),1));
                $fileWithLocation = WWW_PATH . DIRECTORY_SEPARATOR . $this->_produtoModel->getCol($this->_getParam('file'))->getParam('target') . DIRECTORY_SEPARATOR . $this->_produtoModel->{$this->_getParam('file')};
                
                goweb::loadClass('Goweb_Mime');
                $ctype = Goweb_Mime::getMime($file_extension);

                if (strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE')){
                        header('Content-Type: "'.$ctype.'"');
                        header('Content-Disposition: attachment; filename="'.$this->_produtoModel->{$this->_getParam('file')}.'"');
                        header('Expires: 0');
                        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
                        header('Content-Transfer-Encoding: binary');
                        header('Pragma: public');
                        header('Content-Length: '.filesize($fileWithLocation));
                } else {
                        header('Content-Type: "'.$ctype.'"');
                        header('Content-Disposition: attachment; filename="'.$this->_produtoModel->{$this->_getParam('file')}.'"');
                        header('Content-Transfer-Encoding: binary');
                        header('Expires: 0');
                        header('Pragma: no-cache');
                        header('Content-Length: '.filesize($fileWithLocation));
                }

                set_time_limit(0);

                readfile($fileWithLocation);
                exit(0);

            }

        }
    }

    /**
     * Devolve o Model referente a uma determinada ficha do produto
     *
     * @param integer
     *
     * @return Catalogo_Model_Barebone
     */
    protected function _getFichaModel($fichaId) {
        Goweb::loadModel('Catalogo_Model_Barebone');
        $bareboneModel = new Catalogo_Model_Barebone($this->_elementModel->getAdapter(), false);  
        if (!$bareboneModel instanceof Goweb_Form_Generic_Model_Barebone){
                return $this->_getFichaModelOld($fichaId);  
        }
        $bareboneModel->setup($fichaId);
        return $bareboneModel;
    }
    
    /**
     * Funcao auxiliar que devolve o model da ficha em questao
     *
     * @param integer
     *
     * @return Catalogo_Model_Barebone
     */
    protected function _getFichaModelOld($fichaId) {
        $elementModel = Goweb::getModelInstance('Catalogo_Model_Element', 'db');
        $bareboneModel = Goweb::getModelInstance('Catalogo_Model_Barebone', 'db');
        $bareboneModel->setTableName('catalogo_ficha_id_' . $fichaId . '_' . $bareboneModel->getLang());
        $bareboneModel->setTablePrefix('catalogo_ficha_id_' . $fichaId);
        $elementModel->where($elementModel->getTableName() . '.ficha_id=?', $fichaId);
        $rowset = $elementModel->fetchAll();
        if (!$rowset) {
            return $bareboneModel;
        }
        foreach ($rowset as $row) {
            $params = array();
            $nome = 'element_' . $row->id;
            $params['label'] = $row->label;
            $params['notnull'] = false;
            if ($row->element == 'text') {
                if ($row->size > 0) {
                    $params['maxlength'] = $row->size;
                }
                $bareboneModel->{$nome} = $bareboneModel->Char($params);
            } elseif ($row->element == 'textarea') {
                $bareboneModel->{$nome} = $bareboneModel->Text($params);
            } else {
                // no caso de ser checkbox, radio ou select é guardado apenas o valor
                $params['maxlength'] = '200';
                $bareboneModel->{$nome} = $bareboneModel->Char($params);
            }
        }
        return $bareboneModel;
    }

    /**
     * Funcao auxiliar que devolve a ficha relacionado ao produto em questao
     *
     * @param integer
     * @param integer
     *
     * @return array
     */
    protected function _getFicha($produtoId, $fichaId) {
        $this->_elementModel = Goweb::getModelInstance('Catalogo_Model_Element', 'db', false);
        $bareboneModel = $this->_getFichaModel($fichaId);

        $db = Goweb::registry('db');
        $tables = $db->listTables();
        /**
         * Fix para quando a tabela não existe, é comum, acreditem... :)
         */
        if (!in_array($bareboneModel->getTableName(), $tables)) {
            return false;
        }
        $this->_elementModel->where($this->_elementModel->getTableName() . '.ficha_id=?', $fichaId);
        if ($this->_elementModel->colExists('ordem')){
            $this->_elementModel->order('ordem');
        }
        $rowset = $this->_elementModel->fetchAll();
        $bareboneModel->findBy('produto_id', $produtoId);
        $ficha = array();
        foreach ($rowset as $row) {
            $elementName = 'element_' . $row->id;
            $ficha[$elementName] = array('label' => $row->label,
                             'type'  => $row->element,
                             'value' => ($bareboneModel->{$elementName} && strpos($bareboneModel->{$elementName}, 'a:') === 0 ? unserialize($bareboneModel->{$elementName}) : $bareboneModel->{$elementName}));
        }
        return $ficha;
    }

    /**
     * Acao para mostrar o caminho do produto
     */
    public function caminhoAction() {
        if ($this->_validateId($this->_getParam('id'))) {
            $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Catalogo');
            $table = $this->_categoriaModel->getTableName();
            $this->_categoriaModel->loadForeigns(false);
            $result = $this->_categoriaModel->fetchAll(array('id', 'pai_id', 'titulo'));

            if ($result) {
                $this->_buildPath($result, $this->_getParam('id'), $this->_getParam('stop_id'));
            }

            $this->view->path = array_reverse($this->_path);
            $this->_helper->viewRenderer->setRender('caminho');
        }
    }

    /**
     * Funcao auxiliar interna a classe para mostrar o caminho do produto
     */
    protected function _caminho($stop_id, $categoria_id) {
        if ($this->_validateId($categoria_id)) {

            $table = $this->_categoriaModel->getTableName();
            $this->_categoriaModel->loadForeigns(false);
            $result = $this->_categoriaModel->fetchAll(array('id', 'pai_id', 'titulo'));

            if ($result) {
                $this->_buildPath($result, $categoria_id, $stop_id);
            }

            $path = array_reverse($this->_path);

            if ($path) {
                $total = count($path);
                $titulo = '';
                for ($i = 0; $i < $total; $i++) {
                    $titulo .= "<a href='" . Goweb::link('/catalogo/list/categoria_id/' . $path[$i]['id']) . "' class='link'>" . $path[$i]['titulo'] . "</a>";
                    if ($i < ($total -1)) {
                        $titulo .= ' > ';
                    }
                }
            }

            return $titulo;
        }
    }

    /**
     * Monta o caminho do produto
     *
     * @param Goweb_Db_Model_Rowset
     * @param integer
     * @param integer
     */
    protected function _buildPath($categorias, $id, $stop = 0) {
        if ($id != $stop) {
            $nid = null;
            foreach ($categorias as $key => $categoria) {
                if ($categoria->id == $id) {
                    $nid = $categoria->pai_id;
                    $this->_path[] = array('id'     => $categoria->id,
                                           'pai_id' => $categoria->pai_id,
                                           'titulo' => $categoria->titulo);
                }
            }
            $this->_buildPath($categorias, $nid, $stop);
        }
    }
    /**
     * Coloca cambios na sessao
     */
    public function setCambiosSessionAction(){
        $cambio_select = '';
        $session = Goweb::registry('session');
        if(isset($_POST['moeda']))	$cambio_select = $_POST['moeda'];
        $array_moedas = array();
        if($this->_moduleConfig->cambios->activo){
            $moedas = explode('::', $this->_moduleConfig->cambios->moedas);
            foreach ($moedas as $moeda) {
                $moeda_temp = explode(':', $moeda);
                if(count($moeda_temp) == 3){
                    $cambio = '1';
                    $cambioModel =  Goweb::getModelInstance('Catalogo_Model_Cambio', 'db', false);
                    $cambioModel->order('-id');
                    $cambioModel->where("nome = '{$moeda_temp[0]}' AND activo = 1");
                    $cambios = $cambioModel->fetchAll();
                    if($cambios){
                        foreach ($cambios as $cambio_temp) {
                            $cambio = $cambio_temp->cambio;
                        }
                    }
                    $array_moedas[] = array('nome' => $moeda_temp[0], 'simbolo' => '&' .$moeda_temp[1] . ';', 'position' => $moeda_temp[2], 'cambio' => $cambio);
                }
            }
            $session->cambios = $array_moedas;
            $cambio_select_temp = $session->cambio;
            if($cambio_select_temp == ''){
                $cambio_select_temp = 'Euro';
            }
            if($cambio_select != ''){
                $cambio_select_temp =$cambio_select;
            }
            $session->cambio = $cambio_select_temp;
        }
        elseif(isset($session->cambios)){
            unset($session->cambios);
        }

    }

    /**
     * Acao executada se a acao chamada nao existir neste modulo
     *
     * @param string
     * @param array
     */
    public function __call($action, $arguments) {
        if('Action' == substr($action, -6)) {
            $this->_forward('index');
        } else {
            throw new Goweb_Exception('A fun&ccedil;&atilde;o n&atilde;o existe em '. get_class($this));
        }
    }
    /**
     * Menu em lista
     *
     */
    public function menuList2Action(){
        $pai_id = $this->_getParam('pai_id');
        if (!$pai_id) $pai_id = 0;
        $id = $this->_getParam('id_selected');
        if (!$id) $id = 0;
        if ($this->_validateId($id) && $id > 0 && !$this->_categoriaModel->find($id)){
            $this->_helper->viewRenderer->setNoRender();
            return false;
        }
        if ($this->_validateId($pai_id) && $pai_id > 0 && !$this->_categoriaModel->find($pai_id)) {
            $this->_helper->viewRenderer->setNoRender();
            return false;
        }
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Cms');
        $tree = $this->_getTree();
        $tree->build($pai_id);
        $parents = $this->_getAllParents($id);
        
        $this->view->menu = $this->_getList2($tree->getTree(), null, $pai_id, $id, 0, $parents);
        $this->view->menu .= '<script type="text/javascript">
var catalogo_menu_id_' . $pai_id . '=new menu.dd("catalogo_menu_id_' . $pai_id . '");
catalogo_menu_id_' . $pai_id . '.init("catalogo_menu_id_' . $pai_id . '","menuhover");
</script>';
        
        $this->_helper->viewRenderer->setRender('menu-list');
    }

    /**
     * Menu em lista
     *
     */
    public function menuListDropMultiAction(){
        $pai_id = $this->_getParam('pai_id');
        if (!$pai_id) $pai_id = 0;
        $id = $this->_getParam('id_selected');
        if (!$id) $id = 0;
        if ($this->_validateId($id) && $id > 0 && !$this->_categoriaModel->find($id)) return false;
        if ($this->_validateId($pai_id) && $pai_id > 0 && !$this->_categoriaModel->find($pai_id)) return false;
        $this->view->setViewsPath(VIEWS_PATH . DIRECTORY_SEPARATOR . 'Cms');
        $tree = $this->_getTree();
        $tree->build($pai_id);
        $parents = $this->_getAllParents($id);
        
        $this->view->menu = $this->_getListDropMulti($tree->getTree(), null, $pai_id, $id, 0, $parents);
        
        $this->_helper->viewRenderer->setRender('menu-list');
    }
    
    /**
     * Criar a tree
     *
     * @param String $idCol
     * @param String $pidCol
     * @param String $nameCol
     * @return Goweb_Tree
     */
    public function _getTree($idCol = 'id', $pidCol = 'pai_id', $nameCol = 'titulo'){
        goweb::loadClass('Goweb_Tree');
        $tree = new Goweb_Tree($idCol, $pidCol);

        // n&atilde;o carregar as chaves estrangeiras
        $this->_categoriaModel->loadForeigns(false);

        $rowset = $this->_categoriaModel->fetchAll(array($idCol, $pidCol, $nameCol, 'activo'));

        if ($rowset) {
            foreach ($rowset as $row) {
                if (!$row->activo) continue;
                $node = array($idCol => $row->{$idCol},
                    $pidCol => $row->{$pidCol},
                    $nameCol => $row->{$nameCol},
                    'redireccionar' => 0,
                    'url' => '/catalogo/list/categoria_id/' . $row->{$idCol},
                    );

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

    /**
     * Obter todos os pais para o id seleccionado
     *
     * @param int $pai_id
     * @return array
     */
    protected function _getAllParents($pai_id = 0){
        $parents = array();

        $parents[] = $pai_id;

        if ($this->_categoriaModel->find($pai_id)){
            while ($this->_categoriaModel->find($this->_categoriaModel->pai_id)){
                $parents[] = $this->_categoriaModel->id;
            }
        }
        return $parents;
    }

/**
     * obter lista ordenada
     *
     * @param Goweb_Tree $tree
     * @param String $html
     * @param int $parentId
     * @param int $idSelected
     * @param int $level
     * @return String
     */
    protected function _getListDropMulti($tree = null, $html = null, $parentId = 0, $idSelected = 0, $level = 0, $parents = array()){
        if ($tree) {
            if (is_null($html)){
                $html = str_pad(' ', $level) . "<ul id='catalogo_menu_id_$parentId' class='droplineMulti'>\n";
            } else {
                $html .= str_pad(' ', $level) . "<ul>\n";
            }
            $count = 0;
            $limit = $this->_getParam('limit');
            foreach ($tree as $node) {
                if ($limit && $node->pai_id == $parentId && $count >= $limit) continue;
                if ($node->pai_id == $parentId) $count++;
                $html .= str_pad(' ', $level+1) . '<li';
                $cssClass = '';
                if (count($node->childs) > 0) {
                    if (strlen($cssClass)) $cssClass .= ' ';
                    $cssClass .= 'child';
                }
                if ($level == 0){
                    if (strlen($cssClass)) $cssClass .= ' ';
                    $cssClass .= 'top';
                }
                if (strlen($cssClass)) $html .= ' class="' . $cssClass . '"';
                $html .= "><a href='";
                if (is_null($node->url) || count($node->childs) > 0){
                    $html .= $this->view->baseUrl ."' onclick='return false;'";
                } else {
                    $html .= ($node->url ? $this->view->link($node->url) : $this->view->link('/catalogo/list/categoria_id/' . $node->id)) . "'";
                }
                $cssClass = '';
                if (in_array($node->id, $parents)){
                    $cssClass .= 'selected';
                }
                if ($level == 0){
                    if (strlen($cssClass)) $cssClass .= ' ';
                    $cssClass .= 'top_link';
                }
                if (count($node->childs) > 0) {
                    if (strlen($cssClass)) $cssClass .= ' ';
                    $cssClass .= 'down';
                }
                if (strlen($cssClass) > 0) $html .= ' class="' . $cssClass . '"';
                $html .= '>';
                $html .=  '<span>' . htmlentities($node->titulo, ENT_NOQUOTES, CHARSET) . '</span>';
                $html .= '<!--[if IE 7]><!--></a><!--<![endif]-->
<!--[if lte IE 6]><table><tr><td><![endif]-->';
                if (count($node->childs) > 0) {
                    $level++;
                    $level++;
                    $html = $this->_getListDropMulti($node->childs, $html, $parentId, $idSelected, $level, $parents);
                    $level--;
                    $level--;
                }
                $html .= str_pad(' ', $level+1);
                if (count($node->childs) > 0) {
                    $html .= "<!--[if lte IE 6]></td></tr></table></a><![endif]--></li>\n";
                } else {
                    $html .= "</li>\n";
                }
            }
            $html .= str_pad(' ', $level) . "</ul>\n";
        }
        return $html;
    }
    /**
     * obter lista ordenada
     *
     * @param Goweb_Tree $tree
     * @param String $html
     * @param int $parentId
     * @param int $idSelected
     * @param int $level
     * @return String
     */
    protected function _getList2($tree = null, $html = null, $parentId = 0, $idSelected = 0, $level = 0, $parents = array()){
        if ($tree) {
            if (is_null($html)){
                $html = str_pad(' ', $level) . "<ul class='dropdown-menu' id='catalogo_menu_id_$parentId'>\n";
            } else {
                $html .= str_pad(' ', $level) . "<ul>\n";
            }
            $count = 0;
            $limit = $this->_getParam('limit');
            foreach ($tree as $node) {
                if ($limit && $node->pai_id == $parentId && $count >= $limit) continue;
                if ($node->pai_id == $parentId) $count++;
                $html .= str_pad(' ', $level+1) . '<li>';
                $cssClass = '';
                if (in_array($node->id, $parents)){
                    $cssClass .= 'selected';
                }
                if ($level == 0) {
                    if (strlen($cssClass)) $cssClass .= ' ';
                    $cssClass .= 'dropdown-menulink';
                }
                if (count($node->childs) > 0 && $level > 0) {
                    if (strlen($cssClass)) $cssClass .= ' ';
                    $cssClass .= 'sub';
                }
                if (strlen($cssClass)) $cssClass = ' class="' . $cssClass . '"';
                $html .= "<a href='";
                if (is_null($node->url) || count($node->childs) > 0){
                    $html .= $this->view->baseUrl ."' onclick='return false;'";
                } else {
                    $html .= ($node->url ? $this->view->link($node->url) : $this->view->link('/catalogo/list/categoria_id/' . $node->id)) . "'";
                }
                $html .= "$cssClass>" . '<span>' . htmlentities($node->titulo, ENT_NOQUOTES, CHARSET) . '</span>' . "</a>\n";
                
                if (count($node->childs) > 0) {
                    $level++;
                    $level++;
                    $html = $this->_getList2($node->childs, $html, $parentId, $idSelected, $level, $parents);
                    $level--;
                    $level--;
                }
                $html .= str_pad(' ', $level+1) . "</li>\n";
            }
            $html .= str_pad(' ', $level) . "</ul>\n";
        }
        return $html;
    }

    /**
     * Obter o ínicio dos links, útil para costumizações
     *
     * @return string
     */
    protected function _getLinkStart(){
        $translate = Zend_Controller_Router_Route::getDefaultTranslator();
        $sub = '/'. ($translate ? $translate->_($this->_getParam('controller')) : $this->_getParam('controller'));
        if($this->_getParam('lang')){
            $sub = '/' . $this->_getParam('lang') . $sub;
        }
        $sub .= '/' . $this->_goString;
        return $sub;
    }
}
