<?php

/**
 * Goweb Sitemanager 5 Framework
 *
 * Sistema de traducoes
 *
 * @version    5.0.0
 * @category   Goweb
 * @package    Goweb_Translator
 * @author     I&D <dev@goweb.pt>, Pedro Pinto <ppinto@goweb.pt>
 * @copyright  2009 (c) Goweb (http://www.goweb.pt)
 */

/**
 * Goweb_Exception
*/
Goweb::loadClass('Goweb_Exception');

/**
 * Sistema de traducoes
 *
 * @version    5.0.0
 * @category   Goweb
 * @package    Goweb_Translator
 * @author     I&D <dev@goweb.pt>, Pedro Pinto <ppinto@goweb.pt>
 * @copyright  2009 (c) Goweb (http://www.goweb.pt)
 */
class Goweb_Translator {

    /**
     * Lingua activa em formato ISO (i.e. pt ou en, etc)
     *
     * @var  string
     */
    protected $_lang;

    /**
     * Caminho onde se encontra os ficheiros das traducoes
     *
     * @var  string
     */
    protected $_path;

    /**
     * Recurso de sistema do ficheiro de traducao
     *
     * @var  resource
     */
    protected $_fileHandle = null;

    /**
     * Array com as traducoes
     *
     * @var  array
     */
    protected $_dict = array();


    /**
     * Objecto Goweb_Db_Adapter
     *
     * @var  Goweb_Model
     */
    protected $_cms_translater;

    /**
     * Constructor
     *
     * @param  string  $lang   Lingua a ser processada
     * @param  array   $langs  Array com as linguas existentes
     * @param  string  $path   Caminho onde se encontram os ficheiros de traducoes
     */
    public function __construct($lang, $langs, $path = '') {
        $this->_lang  = $lang;
        $this->_langs = $langs;
        $this->_path  = $path;
        $this->_cms_translater = Goweb::getModelInstance('Cms_Model_Translater', 'db', false);
        if ($this->_lang != $this->_cms_translater->getLang()){
            $this->_cms_translater->setLang($lang);
            $this->_cms_translater->initLang();
        }
        $this->_initTranslation();
    }

    /**
     * Traduz uma string.
     *
     * O primeiro paremetro e a string para traduzir, os restantes sco as strings de substituicao.
     *
     * @param   mixed
     */
    public function translate() {
        $args = func_get_args();
        if (func_num_args() == 1) {
        	if(is_numeric($args[0])) return $args[0];
            $args[0] = htmlentities($args[0], ENT_NOQUOTES, CHARSET, false);
        	if (!array_key_exists($args[0], $this->_dict)) {
                //$args[0] = str_replace('"', '\"', $args[0]);
                $this->_dict[$args[0]] = $args[0];
                $this->_insertToAllTables($args[0]);
            }
            return html_entity_decode($this->_dict[$args[0]], ENT_NOQUOTES, CHARSET);
        } elseif (func_num_args() > 1) {
        	if(is_numeric($args[0])) return $args[0];
            $args[0] = htmlentities($args[0], ENT_NOQUOTES, CHARSET, false);
        	if (!array_key_exists($args[0], $this->_dict)) {
                $this->_dict[$args[0]] = $args[0];
                $this->_insertToAllTables($args[0]);
            }
            $string = $this->_dict[$args[0]];
            $args = array_slice($args, 1);
            foreach ($args as $param) {
                $string = preg_replace("~{{\s*(.*?)\s*}}~s", $param,  $string, 1);
            }
            return html_entity_decode($string, ENT_NOQUOTES, CHARSET);
        }
        return null;
    }


     /**
     * Inicializa o sistema de traducao No sistema de Base de dados.
     */
    protected function _initTranslation($createJs = false) {
        if(file_exists(WWW_PATH . '/media/js/lang/' . $this->_lang . '.js')) {
        	Goweb::loadJavascript('/media/js/lang/' . $this->_lang . '.js');
        }

        if(file_exists(WWW_PATH . '/media/js/lang/bd_' . $this->_lang . '.js')) {
            if(file_exists(WWW_PATH . '/media/js/prototype/translate.js')) {
                Goweb::loadJavascript('/media/js/prototype.js');
                Goweb::loadJavascript('/media/js/prototype/translate.js');
                Goweb::loadJavascript('/media/js/lang/bd_' . $this->_lang . '.js');
            }
        }

       	$this->_cms_translater->reset();
        $this->_cms_translater->order("texto");

       	$db = $this->_cms_translater->getAdapter();
       	$cache = Zend_Registry::get('cache');
        if (!$tables = $cache->load('listTables')){
            $tables = $db->listTables();
            $cache->save($tables, 'listTables');
        }
        if (!$__dict__ = $cache->load(md5($this->_cms_translater->getTableName()))){
            $traducoes = array();
            if(in_array($this->_cms_translater->getTableName(), $tables)) {
                $traducoes = $this->_cms_translater->fetchAll();
            }
            if($traducoes) {
                $traducoes = $traducoes->toArray();
            } else {
                $traducoes = array();
            }
            $__dict__ = array();
            foreach ($traducoes as $trans) {
                $__dict__[$trans['texto']] = $trans['translater'];
            }
            $cache->save($__dict__, md5($this->_cms_translater->getTableName()));
            if ($createJs){
                    $config = Goweb::registry('config');
                    $langs = explode(',', $config->languages->available);
                    goweb::loadClass('Zend_Json');
                    foreach ($langs as $lang) {
                        $file = WWW_PATH . '/media/js/lang/bd_' . $lang . '.js';
                        if (!is_writable($file)) {
                            continue ;
                        }
                        $tabela = "cms_translater_$lang";
                        $sql = "SELECT texto, translater FROM $tabela ";
                        $rowset = $db->fetchAll($sql);
                        $data = array();
                        foreach ($rowset as $row) {
                            $data[html_entity_decode($row['texto'], null, CHARSET)] = html_entity_decode($row['translater'], null, CHARSET);
                        }
                        $file_contents = 'var Translator = new Translate(' . Zend_Json::encode($data). ');';
                        file_put_contents($file, $file_contents);
                    }
            }
        }

        $this->_dict = $__dict__;
    }

     /**
     * Escreve uma string em todos as tabelas de traducao.
     *
     * @param  string  $content  String a ser escrita nas tabelas
     */
    protected function _insertToAllTables($content) {
		$model_translater = Goweb::getModelInstance('Cms_Model_Translater', 'db', false);
		$db = $model_translater->getAdapter();
       	$cache = Zend_Registry::get('cache');
        if (!$tables = $cache->load('listTables')){
            $tables = $db->listTables();
            $cache->save($tables, 'listTables');
        }
        if(!in_array($model_translater->getTableName(), $tables)){
            return false;
        }
		$model_translater->texto = $content;
		$model_translater->translater = $content;
		$model_translater->save();
        $cache = Zend_Registry::get('cache');
        $cache->clean(Zend_Cache::CLEANING_MODE_ALL);
        clearstatcache();
		$this->_initTranslation(true);
    }
}
