<?php

App::uses('AppHelper', 'View/Helper');
App::uses('_Default', 'Lib/Icons');
App::import('Model', 'User');
require(APP . 'Config' . DS . 'bemmelhor_submenus.php');
require(APP . 'Config' . DS . 'bemmelhor_menus_help.php');
require(APP . 'Config' . DS . 'bemmelhor_menus_chart.php');
require(APP . 'Config' . DS . 'bemmelhor_menus_report.php');
require(APP . 'Config' . DS . 'bemmelhor_menus_settings.php');
require(APP . 'Config' . DS . 'bemmelhor_menus_side_default.php');

/**
 * Layout Helper
 *
 * PHP version 5
 *
 * @category Helper
 * @package  Bemmelhor
 * @version  1.0
 * @author   Fabricio S Costa <fabriciojf@gmail.com>
 *
 * @link     http://www.bemmelhor.org
 */
class LayoutHelper extends AppHelper {

    /**
     * Other helpers used by this helper
     *
     * @var array
     * @access public
     */
    public $helpers = array(
        'Html',
        'Form',
        'Session',
        'Js',
    );

    /**
     * Current Node
     *
     * @var array
     * @access public
     */
    public $node = null;

    /**
     * Core helpers
     *
     * Extra supported callbacks, like beforeNodeInfo() and afterNodeInfo(),
     * won't be called for these helpers.
     *
     * @var array
     * @access public
     */
    public $coreHelpers = array(
        // CakePHP
        'Ajax',
        'Cache',
        'Form',
        'Html',
        'Javascript',
        'JqueryEngine',
        'Js',
        'MootoolsEngine',
        'Number',
        'Paginator',
        'PrototypeEngine',
        'Rss',
        'Session',
        'Text',
        'Time',
        'Xml',
        // Bemmelhor
        'Filemanager',
        'Image',
        'Layout',
        'Recaptcha',
    );

    /**
     * Retorna o termo slug do post, para o caso de apresentacao de banners apenas
     * na pagina inicial validar o slug no default.ctp do tema da seguinte forma:
     *
     *  <?php if ($this->Layout->pageSlug() == 'home') : ?>
     * 	    ... conteudo da pagina inicial
     *  <?php else : ?>
     * 		... conteudo das demais paginas
     * 	<?php endif; ?>
     *
     * @return Ambigous <string, boolean>
     */
    public function pageSlug() {
        return $this->node('slug');
    }

    /**
     * Default Constructor
     *
     * @param View $View The View this helper is being attached to.
     * @param array $settings Configuration settings for the helper.
     */
    public function __construct(View $View, $settings = array()) {
        $this->helpers[] = Configure::read('Site.acl_plugin') . '.' . Configure::read('Site.acl_plugin');
        parent::__construct($View, $settings);
    }

    /**
     * Javascript variables
     *
     * Shows bemmelhor.js file along with useful information like the applications's basePath, etc.
     *
     * Also merges Configure::read('Js') with the Bemmelhor js variable.
     * So you can set javascript info anywhere like Configure::write('Js.my_var', 'my value'),
     * and you can access it like 'Bemmelhor.my_var' in your javascript.
     *
     * @return string
     */
    public function js() {
        $bemmelhor = array();
        if (isset($this->params['locale'])) {
            $bemmelhor['basePath'] = Router::url('/' . $this->params['locale'] . '/');
        } else {
            $bemmelhor['basePath'] = Router::url('/');
        }
        $bemmelhor['params'] = array(
            'controller' => $this->params['controller'],
            'action' => $this->params['action'],
            'named' => $this->params['named'],
        );
        if (is_array(Configure::read('Js'))) {
            $bemmelhor = Set::merge($bemmelhor, Configure::read('Js'));
        }
        return $this->Html->scriptBlock('var Bemmelhor = ' . $this->Js->object($bemmelhor) . ';');
    }

    public function favicon() {
        return '<link rel="shortcut icon" href="' . Router::url('/') . 'favicon.ico" />';
    }

    /**
     * Statusf
     *
     * instead of 0/1, show tick/cross
     *
     * @param integer $value 0 or 1
     * @return string formatted img tag
     */
    public function status($value) {
        if ($value == 1) {
            $output = $this->Html->image('/img/icons/tick.png');
        } else {
            $output = $this->Html->image('/img/icons/cross.png');
        }
        return $output;
    }

    /**
     * Display value from $item array
     *
     * @param $item array of values
     * @param $model string model alias
     * @param $field string field name
     * @param $options array
     * @return string
     */
    public function displayField($item, $model, $field, $options = array()) {
        extract(array_intersect_key($options, array(
            'type' => null,
            'url' => array(),
            'options' => array(),
                        )
        ));
        switch ($type) {
            case 'boolean':
                $out = $this->status($item[$model][$field]);
                break;
            default:
                $out = h($item[$model][$field]);
                break;
        }

        if (!empty($url)) {
            if (isset($url['pass'])) {
                $passVars = is_string($url['pass']) ? array($url['pass']) : $url['pass'];
                foreach ($passVars as $passField) {
                    $url[] = $item[$model][$passField];
                }
                unset($url['pass']);
            }

            if (isset($url['named'])) {
                $namedVars = is_string($url['named']) ? array($url['named']) : $url['named'];
                foreach ($namedVars as $namedField) {
                    $url[$namedField] = $item[$model][$namedField];
                }
                unset($url['named']);
            }

            $out = $this->Html->link($out, $url, $options);
        }
        return $out;
    }

    /**
     * Show flash message
     *
     * @return string
     */
    public function sessionFlash() {
        $messages = $this->Session->read('Message');
        $output = '';
        if (is_array($messages)) {
            foreach (array_keys($messages) as $key) {
                $output .= $this->Session->flash($key);
            }
        }
        return $output;
    }

    /**
     * Meta tags
     *
     * @return string
     */
    public function meta($metaForLayout = array()) {
        $_metaForLayout = array();
        if (is_array(Configure::read('Meta'))) {
            $_metaForLayout = Configure::read('Meta');
        }

        if (count($metaForLayout) == 0 &&
                isset($this->_View->viewVars['node']['CustomFields']) &&
                count($this->_View->viewVars['node']['CustomFields']) > 0) {
            $metaForLayout = array();
            foreach ($this->_View->viewVars['node']['CustomFields'] as $key => $value) {
                if (strstr($key, 'meta_')) {
                    $key = str_replace('meta_', '', $key);
                    $metaForLayout[$key] = $value;
                }
            }
        }

        $metaForLayout = array_merge($_metaForLayout, $metaForLayout);

        $output = '';
        foreach ($metaForLayout as $name => $content) {
            $output .= '<meta name="' . $name . '" content="' . $content . '" />';
        }

        return $output;
    }

    /**
     * isLoggedIn
     *
     * if User is logged in
     *
     * @return boolean
     */
    public function isLoggedIn() {
        if ($this->Session->check('Auth.User.id')) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * Feed
     *
     * RSS feeds
     *
     * @param boolean $returnUrl if true, only the URL will be returned
     * @return string
     */
    public function feed($returnUrl = false) {
        if (Configure::read('Site.feed_url')) {
            $url = Configure::read('Site.feed_url');
        } else {
            /* $url = Router::url(array(
              'controller' => 'nodes',
              'action' => 'index',
              'type' => 'blog',
              'ext' => 'rss',
              )); */
            $url = '/nodes/promoted.rss';
        }

        if ($returnUrl) {
            $output = $url;
        } else {
            $url = Router::url($url);
            $output = '<link href="' . $url . '" type="application/rss+xml" rel="alternate" title="RSS 2.0" />';
            return $output;
        }

        return $output;
    }

    /**
     * Get Role ID
     *
     * @return integer
     */
    public function getRoleId() {
        if ($this->isLoggedIn()) {
            $roleId = $this->Session->read('Auth.User.role_id');
        } else {
            // Public
            $roleId = 3;
        }
        return $roleId;
    }

    /**
     * Region is empty
     *
     * returns true if Region has no Blocks.
     *
     * @param string $regionAlias Region alias
     * @return boolean
     */
    public function regionIsEmpty($regionAlias) {
        if (isset($this->_View->viewVars['blocks_for_layout'][$regionAlias]) &&
                count($this->_View->viewVars['blocks_for_layout'][$regionAlias]) > 0) {
            return false;
        } else {
            return true;
        }
    }

    /**
     * Show Blocks for a particular Region
     *
     * @param string $regionAlias Region alias
     * @param array $options
     * @return string
     */
    public function blocks($regionAlias, $options = array()) {
        $_options = array();
        $options = array_merge($_options, $options);
        $output = '';
        if (!$this->regionIsEmpty($regionAlias)) {
            $blocks = $this->_View->viewVars['blocks_for_layout'][$regionAlias];
            foreach ($blocks as $block) {
                $plugin = false;
                if ($block['Block']['element'] != null) {
                    if (strstr($block['Block']['element'], '.')) {
                        $pluginElement = explode('.', $block['Block']['element']);
                        $plugin = $pluginElement[0];
                        $element = $pluginElement[1];
                    } else {
                        $element = $block['Block']['element'];
                    }
                } else {
                    $element = 'block';
                }
                if ($plugin) {
                    $blockOutput = $this->_View->element($element, array('block' => $block), array('plugin' => $plugin));
                } else {
                    $blockOutput = $this->_View->element($element, array('block' => $block));
                }
                $enclosure = isset($block['Params']['enclosure']) ? $block['Params']['enclosure'] === "true" : true;
                if ($element != 'block' && $enclosure) {
                    $block['Block']['body'] = $blockOutput;
                    $block['Block']['element'] = null;
                    $output .= $this->_View->element('block', array('block' => $block));
                } else {
                    $output .= $blockOutput;
                }
            }
        }
        return $output;
    }

    /**
     * Show Menu by Alias
     *
     * @param string $menuAlias Menu alias
     * @param array $options (optional)
     * @return string
     */
    public function menu($menuAlias, $options = array()) {
        $_options = array(
            'tag' => 'ul',
            'tagAttributes' => array(),
            'selected' => 'selected',
            'dropdown' => false,
            'dropdownClass' => 'sf-menu',
            'element' => 'menu',
        );
        $options = array_merge($_options, $options);

        if (!isset($this->_View->viewVars['menus_for_layout'][$menuAlias])) {
            return false;
        }
        $menu = $this->_View->viewVars['menus_for_layout'][$menuAlias];
        $output = $this->_View->element($options['element'], array(
            'menu' => $menu,
            'options' => $options,
        ));
        return $output;
    }

    /**
     * Nested Links
     *
     * @param array $links model output (threaded)
     * @param array $options (optional)
     * @param integer $depth depth level
     * @return string
     */
    public function nestedLinks($links, $options = array(), $depth = 1) {
        $_options = array();
        $options = array_merge($_options, $options);

        $output = '';
        foreach ($links as $link) {
            $linkAttr = array(
                'id' => 'link-' . $link['Link']['id'],
                'rel' => $link['Link']['rel'],
                'target' => $link['Link']['target'],
                'title' => $link['Link']['description'],
                'class' => $link['Link']['class'],
            );

            foreach ($linkAttr as $attrKey => $attrValue) {
                if ($attrValue == null) {
                    unset($linkAttr[$attrKey]);
                }
            }

            // if link is in the format: controller:contacts/action:view
            if (strstr($link['Link']['link'], 'controller:')) {
                $link['Link']['link'] = $this->linkStringToArray($link['Link']['link']);
            }

            // Remove locale part before comparing links
            if (!empty($this->params['locale'])) {
                $currentUrl = substr($this->_View->request->url, strlen($this->params['locale']));
            } else {
                $currentUrl = $this->_View->request->url;
            }

            if (Router::url($link['Link']['link']) == Router::url('/' . $currentUrl)) {
                if (!isset($linkAttr['class'])) {
                    $linkAttr['class'] = '';
                }
                $linkAttr['class'] .= ' ' . $options['selected'];
            }

            $linkOutput = $this->Html->link($link['Link']['title'], $link['Link']['link'], $linkAttr);
            if (isset($link['children']) && count($link['children']) > 0) {
                $linkOutput .= $this->nestedLinks($link['children'], $options, $depth + 1);
            }

            if (Router::url($link['Link']['link']) == Router::url('/' . $currentUrl)) {
                $linkOutput = $this->Html->tag('li', $linkOutput, array('class' => 'active'));
            } else {
                $linkOutput = $this->Html->tag('li', $linkOutput);
            }
            $output .= $linkOutput;
        }
        if ($output != null) {
            $tagAttr = $options['tagAttributes'];
            if ($options['dropdown'] && $depth == 1) {
                $tagAttr['class'] = $options['dropdownClass'];
            }
            $output = $this->Html->tag($options['tag'], $output, $tagAttr);
        }

        return $output;
    }

    /**
     * Converts strings like controller:abc/action:xyz/ to arrays
     *
     * @param string $link link
     * @return array
     */
    public function linkStringToArray($link) {
        $link = explode('/', $link);
        $linkArr = array();
        foreach ($link as $linkElement) {
            if ($linkElement != null) {
                $linkElementE = explode(':', $linkElement);
                if (isset($linkElementE['1'])) {
                    $linkArr[$linkElementE['0']] = $linkElementE['1'];
                } else {
                    $linkArr[] = $linkElement;
                }
            }
        }
        if (!isset($linkArr['plugin'])) {
            $linkArr['plugin'] = false;
        }

        return $linkArr;
    }

    /**
     * Creates a special type of link for use in admin area.
     *
     * Clicking the link will automatically check a corresponding checkbox
     * where element id is equal to $url parameter and immediately submit the form
     * it's on.  This works in tandem with Admin.processLink() in javascript.
     */
    public function processLink($title, $url = null, $options = array(), $confirmMessage = false) {
        if (!empty($confirmMessage)) {
            $options['onclick'] = "if (confirm('$confirmMessage')) { Admin.processLink(this); } return false;";
        } else {
            $options['onclick'] = "Admin.processLink(this); return false;";
        }
        $output = $this->Html->link($title, $url, $options);
        return $output;
    }

    /**
     * Show Vocabulary by Alias
     *
     * @param string $vocabularyAlias Vocabulary alias
     * @param array $options (optional)
     * @return string
     */
    public function vocabulary($vocabularyAlias, $options = array()) {
        $_options = array(
            'tag' => 'ul',
            'tagAttributes' => array(),
            'type' => null,
            'link' => true,
            'plugin' => false,
            'controller' => 'nodes',
            'action' => 'term',
            'element' => 'vocabulary',
        );
        $options = array_merge($_options, $options);

        $output = '';
        if (isset($this->_View->viewVars['vocabularies_for_layout'][$vocabularyAlias]['threaded'])) {
            $vocabulary = $this->_View->viewVars['vocabularies_for_layout'][$vocabularyAlias];
            $output .= $this->_View->element($options['element'], array(
                'vocabulary' => $vocabulary,
                'options' => $options,
            ));
        }
        return $output;
    }

    /**
     * Nested Terms
     *
     * @param array   $terms
     * @param array   $options
     * @param integer $depth
     */
    public function nestedTerms($terms, $options, $depth = 1) {
        $_options = array();
        $options = array_merge($_options, $options);

        $output = '';
        foreach ($terms as $term) {
            if ($options['link']) {
                $termAttr = array(
                    'id' => 'term-' . $term['Term']['id'],
                );
                $termOutput = $this->Html->link($term['Term']['title'], array(
                    'plugin' => $options['plugin'],
                    'controller' => $options['controller'],
                    'action' => $options['action'],
                    'type' => $options['type'],
                    'slug' => $term['Term']['slug'],
                        ), $termAttr);
            } else {
                $termOutput = $term['Term']['title'];
            }
            if (isset($term['children']) && count($term['children']) > 0) {
                $termOutput .= $this->nestedTerms($term['children'], $options, $depth + 1);
            }
            $termOutput = $this->Html->tag('li', $termOutput);
            $output .= $termOutput;
        }
        if ($output != null) {
            $output = $this->Html->tag($options['tag'], $output, $options['tagAttributes']);
        }

        return $output;
    }

    /**
     * Show nodes list
     *
     * @param string $alias Node query alias
     * @param array $options (optional)
     * @return string
     */
    public function nodeList($alias, $options = array()) {
        $_options = array(
            'link' => true,
            'plugin' => false,
            'controller' => 'nodes',
            'action' => 'view',
            'element' => 'node_list',
        );
        $options = array_merge($_options, $options);

        $output = '';
        if (isset($this->_View->viewVars['nodes_for_layout'][$alias])) {
            $nodes = $this->_View->viewVars['nodes_for_layout'][$alias];
            $output = $this->_View->element($options['element'], array(
                'alias' => $alias,
                'nodesList' => $this->_View->viewVars['nodes_for_layout'][$alias],
                'options' => $options,
            ));
        }
        return $output;
    }

    /**
     * Filter content
     *
     * Replaces bbcode-like element tags
     *
     * @param string $content content
     * @return string
     */
    public function filter($content) {
        Bemmelhor::dispatchEvent('Helper.Layout.beforeFilter', $this->_View, array('content' => &$content));
        $content = $this->filterElements($content);
        $content = $this->filterMenus($content);
        $content = $this->filterVocabularies($content);
        $content = $this->filterNodes($content);
        Bemmelhor::dispatchEvent('Helper.Layout.afterFilter', $this->_View, array('content' => &$content));
        return $content;
    }

    /**
     * Filter content for elements
     *
     * Original post by Stefan Zollinger: http://bakery.cakephp.org/articles/view/element-helper
     * [element:element_name] or [e:element_name]
     *
     * @param string $content
     * @return string
     */
    public function filterElements($content) {
        preg_match_all('/\[(element|e):([A-Za-z0-9_\-\/]*)(.*?)\]/i', $content, $tagMatches);
        $validOptions = array('plugin', 'cache', 'callbacks');
        for ($i = 0, $ii = count($tagMatches[1]); $i < $ii; $i++) {
            $regex = '/(\S+)=[\'"]?((?:.(?![\'"]?\s+(?:\S+)=|[>\'"]))*.)[\'"]?/i';
            preg_match_all($regex, $tagMatches[3][$i], $attributes);
            $element = $tagMatches[2][$i];
            $data = $options = array();
            for ($j = 0, $jj = count($attributes[0]); $j < $jj; $j++) {
                if (in_array($attributes[1][$j], $validOptions)) {
                    $options = Set::merge($options, array($attributes[1][$j] => $attributes[2][$j]));
                } else {
                    $data[$attributes[1][$j]] = $attributes[2][$j];
                }
            }
            if (!empty($this->_View->viewVars['block'])) {
                $data['block'] = $this->_View->viewVars['block'];
            }
            $content = str_replace($tagMatches[0][$i], $this->_View->element($element, $data, $options), $content);
        }
        return $content;
    }

    /**
     * Filter content for Menus
     *
     * Replaces [menu:menu_alias] or [m:menu_alias] with Menu list
     *
     * @param string $content
     * @return string
     */
    public function filterMenus($content) {
        preg_match_all('/\[(menu|m):([A-Za-z0-9_\-]*)(.*?)\]/i', $content, $tagMatches);
        for ($i = 0, $ii = count($tagMatches[1]); $i < $ii; $i++) {
            $regex = '/(\S+)=[\'"]?((?:.(?![\'"]?\s+(?:\S+)=|[>\'"]))+.)[\'"]?/i';
            preg_match_all($regex, $tagMatches[3][$i], $attributes);
            $menuAlias = $tagMatches[2][$i];
            $options = array();
            for ($j = 0, $jj = count($attributes[0]); $j < $jj; $j++) {
                $options[$attributes[1][$j]] = $attributes[2][$j];
            }
            $content = str_replace($tagMatches[0][$i], $this->menu($menuAlias, $options), $content);
        }
        return $content;
    }

    /**
     * Filter content for Vocabularies
     *
     * Replaces [vocabulary:vocabulary_alias] or [v:vocabulary_alias] with Terms list
     *
     * @param string $content
     * @return string
     */
    public function filterVocabularies($content) {
        preg_match_all('/\[(vocabulary|v):([A-Za-z0-9_\-]*)(.*?)\]/i', $content, $tagMatches);
        for ($i = 0, $ii = count($tagMatches[1]); $i < $ii; $i++) {
            $regex = '/(\S+)=[\'"]?((?:.(?![\'"]?\s+(?:\S+)=|[>\'"]))+.)[\'"]?/i';
            preg_match_all($regex, $tagMatches[3][$i], $attributes);
            $vocabularyAlias = $tagMatches[2][$i];
            $options = array();
            for ($j = 0, $jj = count($attributes[0]); $j < $jj; $j++) {
                $options[$attributes[1][$j]] = $attributes[2][$j];
            }
            $content = str_replace($tagMatches[0][$i], $this->vocabulary($vocabularyAlias, $options), $content);
        }
        return $content;
    }

    /**
     * Filter content for Nodes
     *
     * Replaces [node:unique_name_for_query] or [n:unique_name_for_query] with Nodes list
     *
     * @param string $content
     * @return string
     */
    public function filterNodes($content) {
        preg_match_all('/\[(node|n):([A-Za-z0-9_\-]*)(.*?)\]/i', $content, $tagMatches);
        for ($i = 0, $ii = count($tagMatches[1]); $i < $ii; $i++) {
            $regex = '/(\S+)=[\'"]?((?:.(?![\'"]?\s+(?:\S+)=|[>\'"]))+.)[\'"]?/i';
            preg_match_all($regex, $tagMatches[3][$i], $attributes);
            $alias = $tagMatches[2][$i];
            $options = array();
            for ($j = 0, $jj = count($attributes[0]); $j < $jj; $j++) {
                $options[$attributes[1][$j]] = $attributes[2][$j];
            }
            $content = str_replace($tagMatches[0][$i], $this->nodeList($alias, $options), $content);
        }
        return $content;
    }

    /**
     * Meta field: with key/value fields
     *
     * @param string $key (optional) key
     * @param string $value (optional) value
     * @param integer $id (optional) ID of Meta
     * @param array $options (optional) options
     * @return string
     */
    public function metaField($key = '', $value = null, $id = null, $options = array()) {
        $_options = array(
            'key' => array(
                'label' => __('Key'),
                'value' => $key,
            ),
            'value' => array(
                'label' => __('Value'),
                'value' => $value,
            ),
        );
        $options = Set::merge($_options, $options);
        $uuid = String::uuid();

        $fields = '';
        if ($id != null) {
            $fields .= $this->Form->input('Meta.' . $uuid . '.id', array('type' => 'hidden', 'value' => $id));
            $this->Form->unlockField('Meta.' . $uuid . '.id');
        }
        $fields .= $this->Form->input('Meta.' . $uuid . '.key', $options['key']);
        $fields .= $this->Form->input('Meta.' . $uuid . '.value', $options['value']);
        $this->Form->unlockField('Meta.' . $uuid . '.key');
        $this->Form->unlockField('Meta.' . $uuid . '.value');
        $fields = $this->Html->tag('div', $fields, array('class' => 'fields'));

        $actions = $this->Html->link(
                __('Remove'), is_null($id) ? '#' : array('plugin' => null, 'controller' => 'nodes', 'action' => 'delete_meta', $id), array('class' => 'remove-meta', 'rel' => $id)
        );
        $actions = $this->Html->tag('div', $actions, array('class' => 'actions'));

        $output = $this->Html->tag('div', $actions . $fields, array('class' => 'meta'));
        return $output;
    }

    /**
     * Show links under Actions column
     *
     * @param integer $id
     * @param array $options
     * @return string
     */
    public function adminRowActions($id, $options = array()) {
        $_options = array();
        $options = array_merge($_options, $options);

        $output = '';
        $rowActions = Configure::read('Admin.rowActions.' . Inflector::camelize($this->params['controller']) . '/' . $this->params['action']);
        if (is_array($rowActions)) {
            foreach ($rowActions as $title => $link) {
                if ($output != '') {
                    $output .= ' ';
                }
                $link = $this->linkStringToArray(str_replace(':id', $id, $link));
                $output .= $this->Html->link($title, $link);
            }
        }
        return $output;
    }

    /**
     * Show tabs
     *
     * @return string
     */
    public function adminTabs($show = null) {
        if (!isset($this->adminTabs)) {
            $this->adminTabs = false;
        }

        $output = '';
        $tabs = Configure::read('Admin.tabs.' . Inflector::camelize($this->params['controller']) . '/' . $this->params['action']);
        if (is_array($tabs)) {
            foreach ($tabs as $title => $tab) {
                if (!isset($tab['options']['type']) || (isset($tab['options']['type']) && (in_array($this->_View->viewVars['typeAlias'], $tab['options']['type'])))) {
                    $domId = strtolower(Inflector::singularize($this->params['controller'])) . '-' . strtolower(Inflector::slug($title, '-'));
                    if ($this->adminTabs) {
                        if (strstr($tab['element'], '.')) {
                            $elementE = explode('.', $tab['element']);
                            $plugin = $elementE['0'];
                            $element = $elementE['1'];
                        } else {
                            $plugin = null;
                        }
                        $output .= '<div id="' . $domId . '">';
                        $output .= $this->_View->element($element, array(), array(
                            'plugin' => $plugin,
                        ));
                        $output .= '</div>';
                    } else {
                        $output .= '<li><a href="#' . $domId . '">' . $title . '</a></li>';
                    }
                }
            }
        }

        $this->adminTabs = true;
        return $output;
    }

    /**
     * Set current Node
     *
     * @param array $node
     * @return void
     */
    public function setNode($node) {
        $this->node = $node;
        $this->hook('afterSetNode');
    }

    /**
     * Set value of a field
     *
     * @param string $field
     * @param string $value
     * @return void
     */
    public function setNodeField($field, $value) {
        $model = 'Node';
        if (strstr($field, '.')) {
            $fieldE = explode('.', $field);
            $model = $fieldE['0'];
            $field = $fieldE['1'];
        }

        $this->node[$model][$field] = $value;
    }

    /**
     * Get value of a Node field
     *
     * @param string $field
     * @return string
     */
    public function node($field = 'id') {
        $model = 'Node';
        if (strstr($field, '.')) {
            $fieldE = explode('.', $field);
            $model = $fieldE['0'];
            $field = $fieldE['1'];
        }

        if (isset($this->node[$model][$field])) {
            return $this->node[$model][$field];
        } else {
            return false;
        }
    }

    /**
     * Node info
     *
     * @param array $options
     * @return string
     */
    public function nodeInfo($options = array()) {
        $_options = array(
            'element' => 'node_info',
        );
        $options = array_merge($_options, $options);

        $output = $this->hook('beforeNodeInfo');
        $output .= $this->_View->element($options['element']);
        $output .= $this->hook('afterNodeInfo');
        return $output;
    }

    /**
     * Node excerpt (summary)
     *
     * @param array $options
     * @return string
     */
    public function nodeExcerpt($options = array()) {
        $_options = array(
            'element' => 'node_excerpt',
        );
        $options = array_merge($_options, $options);

        $output = $this->hook('beforeNodeExcerpt');
        $output .= $this->_View->element($options['element']);
        $output .= $this->hook('afterNodeExcerpt');
        return $output;
    }

    /**
     * Node body
     *
     * @param array $options
     * @return string
     */
    public function nodeBody($options = array()) {
        $_options = array(
            'element' => 'node_body',
        );
        $options = array_merge($_options, $options);

        $output = $this->hook('beforeNodeBody');
        $output .= $this->_View->element($options['element']);
        $output .= $this->hook('afterNodeBody');
        return $output;
    }

    /**
     * Node more info
     *
     * @param array $options
     * @return string
     */
    public function nodeMoreInfo($options = array()) {
        $_options = array(
            'element' => 'node_more_info',
        );
        $options = array_merge($_options, $options);

        $output = $this->hook('beforeNodeMoreInfo');
        $output .= $this->_View->element($options['element']);
        $output .= $this->hook('afterNodeMoreInfo');
        return $output;
    }

    /**
     * Hook
     *
     * Used for calling hook methods from other HookHelpers
     *
     * @param string $methodName
     * @return string
     */
    public function hook($methodName) {
        $output = '';
        foreach ($this->_View->helpers as $helper => $settings) {
            if (!is_string($helper) || in_array($helper, $this->coreHelpers)) {
                continue;
            }
            if (strstr($helper, '.')) {
                $helperE = explode('.', $helper);
                $helper = $helperE['1'];
            }
            if (isset($this->_View->{$helper}) && method_exists($this->_View->{$helper}, $methodName)) {
                $output .= $this->_View->{$helper}->$methodName();
            }
        }
        return $output;
    }

    /**
     * Generate Admin menus added by BemmelhorNav::add()
     *
     * Modelo do menu html gerado
     * <ul class="nav navbar-right top-nav">
     *     <li class="dropdown">
     *         <a href="#" class="dropdown-toggle" data-toggle="dropdown">
     *             <i class="fa fa-user"></i> John Smith <b class="caret"></b>
     *         </a>
     *         <ul class="dropdown-menu">
     * 		       <li>
     *                 <a href="#"><i class="fa fa-fw fa-user"></i> Profile</a>
     *             </li>
     *             <li>
     *                 <a href="#"><i class="fa fa-fw fa-envelope"></i> Inbox</a>
     *             </li>
     *         </ul>
     *     </li>
     * </ul>
     */
    public function adminMenus($menus, $options = array()) {

        $ulOptionsLeft = array(
            'class' => 'nav navbar-nav navbar-left top-nav',
        );

        $liOptions = array(
            'class' => 'dropdown',
        );

        $out = null;
        $sorted = Set::sort($menus, '{[a-z]+}.weight', 'ASC');
        if (empty($this->Role)) {
            $this->Role = ClassRegistry::init('Role');
            $this->Role->Behaviors->attach('Aliasable');
        }

        $currentRole = $this->Role->byId($this->getRoleId());
        $aclPlugin = Configure::read('Site.acl_plugin');
        $tag = '';

        foreach ($sorted as $menu) {
            if ((isset($menu['type']) && ($menu['type'] == 'system')) ||
                    (isset($menu['position']) && $menu['position'] == 'right')) {
                continue;
            }

            $link = '<a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="' .
                    (isset($menu['icon']) ? $menu['icon'] : "") . '"></i> ' .
                    $menu['title'] . ' <b class="caret"></b></a>';
            if (!empty($menu['children'])) {
                $children = $this->adminSubMenus($menu['children'], array(
                    'children' => true,
                    'htmlAttributes' => array('class' => false)
                ));

                if ($children == null) {
                    continue;
                }
                $out .= $this->Html->tag('li', $link . $children, $liOptions);
            }
            $tag = $this->Html->tag('ul', $out, $ulOptionsLeft);
        }
        return $tag;
    }

    /**
     * User Links
     */
    public function addLink($item = array()) {

        if (empty($item)) {
            return;
        }

        $out = null;
        if (empty($this->Role)) {
            $this->Role = ClassRegistry::init('Role');
            $this->Role->Behaviors->attach('Aliasable');
        }
        $currentRole = $this->Role->byId($this->getRoleId());
        $aclPlugin = Configure::read('Site.acl_plugin');

        if ($currentRole != 'admin' && !$this->{$aclPlugin}->linkIsAllowedByRoleId($this->getRoleId(), $item['url'])) {
            return;
        }
        return $this->Html->link($item['title'], $item['url'], array('escape' => false));
    }

    /**
     * User Links
     */
    public function addLinkIcon($item = array()) {

        if (empty($item)) {
            return;
        }

        $out = null;
        if (empty($this->Role)) {
            $this->Role = ClassRegistry::init('Role');
            $this->Role->Behaviors->attach('Aliasable');
        }
        $currentRole = $this->Role->byId($this->getRoleId());
        $aclPlugin = Configure::read('Site.acl_plugin');

        if ($currentRole != 'admin' && !$this->{$aclPlugin}->linkIsAllowedByRoleId($this->getRoleId(), $item['url'])) {
            return;
        }

        $icon = '<div class="text-center"><i class="' . $item['icon'] . ' fa-3x"></i></div>';
        $title = '<div class="text-center">' . $item['title'] . '</div>';

        return '<div class="col-xs-4 col-sm-4 col-md-3 col-lg-3 pb40">' .
                $this->Html->link($icon . $title, $item['url'], array('escape' => false)) .
                '</div>';
    }

    /**
     * Adicionando itens validados nos bradcrumbs
     */
    public function addLinkBreadcrumb($item = array()) {

        if (empty($item)) {
            return;
        }

        $out = null;
        if (empty($this->Role)) {
            $this->Role = ClassRegistry::init('Role');
            $this->Role->Behaviors->attach('Aliasable');
        }
        $currentRole = $this->Role->byId($this->getRoleId());
        $aclPlugin = Configure::read('Site.acl_plugin');

        if ($currentRole != 'admin' && !$this->{$aclPlugin}->linkIsAllowedByRoleId($this->getRoleId(), $item['url'])) {
            return;
        }

        $class = isset($item['class']) ? 'class="' . $item['class'] . '"' : '';
        $icon = isset($item['icon']) ? '<i class="' . $item['icon'] . '"></i> ' : '';

        return '<li ' . $class . '>' . $icon .
                $this->Html->link($item['title'], $item['url'], array('escape' => false)) . '</li>';
    }

    /**
     * Adicionando itens validados nos lists
     */
    public function addLinkListGroup($item = array()) {

        if (empty($item)) {
            return;
        }

        $out = null;
        if (empty($this->Role)) {
            $this->Role = ClassRegistry::init('Role');
            $this->Role->Behaviors->attach('Aliasable');
        }
        $currentRole = $this->Role->byId($this->getRoleId());
        $aclPlugin = Configure::read('Site.acl_plugin');

        if ($currentRole != 'admin' && !$this->{$aclPlugin}->linkIsAllowedByRoleId($this->getRoleId(), $item['url'])) {
            return;
        }

        $class = isset($item['class']) ? 'class="' . $item['class'] . '"' : '';
        $icon = isset($item['icon']) ? '<i class="' . $item['icon'] . '"></i> ' : '';

        return $this->Html->link(
                        $icon . $item['title'], $item['url'], array(
                    'escape' => false,
                    'class' => 'list-group-item'
        ));
    }

    /**
     * Monta o menu de configuracoes do usuario
     * @param unknown_type $menus
     * @param unknown_type $options
     */
    public function adminMenuSettings($menus, $options = array()) {

        $ulOptionsRight = array(
            'class' => 'nav navbar-nav navbar-right top-nav',
        );
        $liOptions = array(
            'class' => 'dropdown',
        );

        $out = null;
        $sorted = Set::sort($menus, '{[a-z]+}.weight', 'ASC');
        if (empty($this->Role)) {
            $this->Role = ClassRegistry::init('Role');
            $this->Role->Behaviors->attach('Aliasable');
        }
        $currentRole = $this->Role->byId($this->getRoleId());
        $aclPlugin = Configure::read('Site.acl_plugin');
        $tag = '';

        foreach ($sorted as $menu) {
            if (!empty($menu['type']) && $menu['type'] == 'system') {

                $user = $this->Html->image('user.png', array(
                    'class' => 'img-responsive img-circle',
                    'style' => 'width: 20px'
                ));

                $link = $this->Html->link($user, array(
                    'controller' => 'bugs',
                    'action' => 'add',
                        ), array(
                    'escape' => false,
                    'class' => 'dropdown-toggle',
                    'data-toggle' => 'dropdown'
                ));

                if (!empty($menu['children'])) {
                    $children = $this->adminSubMenus($menu['children'], array(
                        'children' => true,
                        'htmlAttributes' => array('class' => false)
                    ));
                    $out .= $this->Html->tag('li', $link . $children, $liOptions);
                }
            } else if (!empty($menu['position']) && $menu['position'] == 'right') {

                $caret = $menu['title'] != '' ? ' <b class="caret"></b>' : '';
                $user = '<i class="' . (isset($menu['icon']) ? $menu['icon'] : "")
                        . '"></i> ' . $menu['title'] . $caret;
                $link = $this->Html->link($user, array(
                    'controller' => 'bugs',
                    'action' => 'add',
                        ), array(
                    'escape' => false,
                    'class' => 'dropdown-toggle',
                    'data-toggle' => 'dropdown'
                ));

                if (!empty($menu['children'])) {
                    $children = $this->adminSubMenus($menu['children'], array(
                        'children' => true,
                        'htmlAttributes' => array('class' => false)
                    ));
                    $out .= $this->Html->tag('li', $link . $children, $liOptions);
                }
            }
        }
        return $this->Html->tag('ul', $out, $ulOptionsRight);
    }

    /**
     * Monta o segundo nivel do menu
     * @param unknown_type $menus
     */
    public function adminSubMenus($menus) {

        $ulOptions = array(
            'class' => 'dropdown-menu',
        );

        $out = null;
        $sorted = Set::sort($menus, '{[a-z]+}.weight', 'ASC');
        if (empty($this->Role)) {
            $this->Role = ClassRegistry::init('Role');
            $this->Role->Behaviors->attach('Aliasable');
        }
        $currentRole = $this->Role->byId($this->getRoleId());
        $aclPlugin = Configure::read('Site.acl_plugin');

        foreach ($sorted as $menu) {
            if ($currentRole != 'admin' && !$this->{$aclPlugin}->linkIsAllowedByRoleId($this->getRoleId(), $menu['url'])) {
                continue;
            }

            $icon = !isset($menu['icon']) ? 'fa fa-ellipsis-h' : $menu['icon'];
            $link = $this->Html->link('<i class="' . $icon . '"></i> ' . $menu['title'], $menu['url'], array(
                'escape' => false
            ));
            $out .= $this->Html->tag('li', $link);
        }

        if ($out == null) {
            return null;
        }

        return $this->Html->tag('ul', $out, $ulOptions);
    }

    /** Generate Admin menus added by BemmelhorNav::add()
     *
     * @param array $menus
     * @param array $options
     * @return string menu html tags
     */
    public function adminMenusOld($menus, $options = array()) {
        $options = Set::merge(array(
                    'children' => true,
                    'htmlAttributes' => array(
                        'class' => 'sf-menu',
                    ),
                        ), $options);

        $out = null;
        $sorted = Set::sort($menus, '{[a-z]+}.weight', 'ASC');
        if (empty($this->Role)) {
            $this->Role = ClassRegistry::init('Role');
            $this->Role->Behaviors->attach('Aliasable');
        }
        $currentRole = $this->Role->byId($this->getRoleId());
        $aclPlugin = Configure::read('Site.acl_plugin');
        foreach ($sorted as $menu) {
            if ($currentRole != 'admin' && !$this->{$aclPlugin}->linkIsAllowedByRoleId($this->getRoleId(), $menu['url'])) {
                continue;
            }

            if (empty($menu['htmlAttributes']['class'])) {
                $menuClass = Inflector::slug(strtolower('menu-' . $menu['title']), '-');
                $menu['htmlAttributes'] = Set::merge(array(
                            'class' => $menuClass
                                ), $menu['htmlAttributes']);
            }
            $link = $this->Html->link($menu['title'], $menu['url'], $menu['htmlAttributes']);
            if (!empty($menu['children'])) {
                $children = $this->adminMenus($menu['children'], array(
                    'children' => true,
                    'htmlAttributes' => array('class' => false)
                ));
                $out .= $this->Html->tag('li', $link . $children);
            } else {
                $out .= $this->Html->tag('li', $link);
            }
        }
        return $this->Html->tag('ul', $out, $options['htmlAttributes']);
    }

    /**
     * Adiciona submenus por controller, configure os itens de menu no
     * arquivo Config/bemmelhor_submenus.php
     */
    public function sideMenu($type = 'default') {

        $out = null;
        $tmpmenu = null;
        $tmpdefault = null;

        $aclPlugin = Configure::read('Site.acl_plugin');
        $currentRole = $this->Role->byId($this->getRoleId());

        if ($this->params['controller'] != '') {

            if (BemmelhorNav::items_submenu($this->params['controller']) != null) {
                $menus = BemmelhorNav::items_submenu($this->params['controller']);

                foreach ($menus['children'] as $submenu) {
                    if ($currentRole != 'admin' && !$this->{$aclPlugin}->linkIsAllowedByRoleId($this->getRoleId(), $submenu['url'])) {
                        continue;
                    }
                    $link = $this->Html->link(
                            '<span class="fa-stack fa-lg pull-left"><i class="' . $submenu['icon'] . '"></i></span> ' . __($submenu['title']), $submenu['url'], array('escape' => false)
                    );
                    $tmpmenu .= $this->Html->tag('li', $link);
                }
                $out .= $tmpmenu;
            }
        }

        $menus = BemmelhorNav::items_submenu($type);
        foreach ($menus['children'] as $submenu) {

            if ($submenu['title'] == '---') {
                $tmpdefault .= $this->Html->tag('li', '', array('class' => 'li-hr'));
            } else {
                if ($currentRole != 'admin' && !$this->{$aclPlugin}->linkIsAllowedByRoleId($this->getRoleId(), $submenu['url'])) {
                    continue;
                }
                $link = $this->Html->link(
                        '<span class="fa-stack fa-lg pull-left"><i class="' . $submenu['icon'] . '"></i></span> ' . __($submenu['title']), $submenu['url'], array('escape' => false)
                );
                $tmpdefault .= $this->Html->tag('li', $link);
            }
        }
        $out .= $tmpdefault;
        return $out;
    }

    /**
     * Adiciona submenus por controller, configure os itens de menu no
     * arquivo Config/bemmelhor_submenus.php
     */
    public function genericMenu($type = 'help', $li = false) {

        switch ($type) {
            case 'help' :
                $submenu = MenuHelp::read('default');
                break;

            case 'chart' :
                $submenu = MenuChart::read('default');
                break;

            case 'report' :
                $submenu = MenuReport::read('default');
                break;

            case 'ti' :
                $submenu = MenuTi::read('default');
                break;

            case 'settings' :
                $submenu = MenuSettings::read('default');
                break;

            case 'side_menu' :
                $submenu = MenuSideDefault::read('default');
                break;

            default :
                $submenu = MenuHelp::read('default');
                ;
        }

        $out = '';

        if (empty($this->Role)) {
            $this->Role = ClassRegistry::init('Role');
            $this->Role->Behaviors->attach('Aliasable');
        }
        $aclPlugin = Configure::read('Site.acl_plugin');
        $currentRole = $this->Role->byId($this->getRoleId());
        if (!empty($submenu)) {
            foreach ($submenu['links'] as $item) {

                if ($currentRole != 'admin' && !$this->{$aclPlugin}->linkIsAllowedByRoleId($this->getRoleId(), $item['url'])) {
                    continue;
                }

                if (!$li) {
                    $link = $this->Html->link(
                            '<i class="' . $item['icon'] . '"></i>&nbsp;' .
                            __($item['title']), $item['url'], array(
                        'escape' => false,
                        'class' => 'list-group-item border-top'
                    ));
                } else {
                    $link = $this->Html->tag('li', $this->Html->link(
                                    __($item['title']), $item['url'], array(
                                'escape' => false,
                    )));
                }
                $out .= $link;
            }
        }
        return $out;
    }

    /**
     * Selecao do temaadmin
     */
    public function ThemeAdmin() {
        return trim($this->Session->read('Auth.User.themeadmin')) == '' ? 'Default' :
                trim($this->Session->read('Auth.User.themeadmin'));
    }

    /**
     * Retorna um conjunto de icones, com links favoritos
     * para que sejam apresentados na tela de administracao
     */
    public function getIcons() {

        $icons = $this->Html->link($this->Html->image(_Default::CHART_PIE), array(
            'controller' => 'settings',
            'action' => 'dashboard',
                ), array('escape' => false));

        $icons .= $this->Html->link($this->Html->image(_Default::MAIL), array(
            'controller' => 'mailings',
            'action' => 'index',
                ), array('escape' => false));

        $icons .= $this->Html->link($this->Html->image(_Default::USERS), array(
            'controller' => 'customers',
            'action' => 'index',
                ), array('escape' => false));

        $icons .= $this->Html->link($this->Html->image(_Default::CALENDAR), array(
            'controller' => 'online_calls',
            'action' => 'online',
                ),
                //$icons .= $this->Html->link($this->Html->image(_Default::BLOG), '/',
                array('escape' => false));
        return $icons;
    }

    /**
     * Libera a edicao de posts
     */
    public function editPost($id) {

        $this->Role = ClassRegistry::init('Role');
        $this->Role->Behaviors->attach('Aliasable');
        $currentRole = $this->Role->byId($this->getRoleId());

        if ($currentRole != 'admin') {
            return;
        }

        return '<div class="node-edit pull-right">' . $this->Html->link('Editar Post', array(
                    'plugin' => false,
                    'admin' => true,
                    'controller' => 'nodes',
                    'action' => 'edit/' . $id,
                        ), array(
                    'class' => 'btn btn-sm btn-primary',
                    'escape' => false
                )) . '</div>';
    }

    /**
     * Captura o Saldo atual do usuario Logado
     */
    public function getAtualCash() {
        $User = new User();
        $User->id = $this->Session->read('Auth.User.id');
        $currentUser = $User->read();
        $message = 'Você não possui saldo para envios de SMS, ' .
                ' para adicionar créditos à sua conta ' .
                $this->Html->link(' Clique aqui', array(
                    'plugin' => false,
                    'admin' => true,
                    'controller' => 'saldo',
                    'action' => 'addcreditos',
                        ), array(
                    'escape' => false,
                    'class' => 'btn btn-danger btn-xs'
                        )
        );

        if ($currentUser['User']['sms_credit'] > 0) {
            $message = 'Seu saldo é de: <strong>' . $currentUser['User']['sms_credit'] . '</strong> SMS';
        }
        return $message;
    }

    /**
     * Captura o Saldo atual do usuario Logado
     */
    public function validateCash() {

        $message = "";

        $User = new User();
        $User->id = $this->Session->read('Auth.User.id');
        $currentUser = $User->read();
        if ($currentUser['User']['sms_credit'] <= 0) {
            $message = '<div class="error">Você não possui saldo, adicione créditos para iniciar suas campanhas</div>';
        }
        return $message;
    }

    /**
     * Retorna os ultimos N posts cadastrados em ordem descrescente
     */
    public function last_posts($qtde = 10) {

        $Nodes = new Node();
        $conditions = array(
            'conditions' => array(
                'Node.type' => 'blog'
            ),
            'order' => 'Node.id DESC',
            'fields' => array(
                'id',
                'title',
                'slug',
            ),
            'limit' => $qtde
        );

        $data = $Nodes->find('all', $conditions);
        $content = '';
        foreach ($data as $node) {
            $item = $this->Html->link($node['Node']['title'], array(
                'plugin' => false,
                'admin' => false,
                'controller' => 'blog',
                'action' => $node['Node']['slug']
                    ), array(
                'escape' => false,
                    )
            );
            $content .= $this->Html->tag('li', $item);
        }
        return $this->Html->tag('ul', $content, array('class' => 'last-posts'));
    }

    /**
     * Mascara telefones no padrao brasileiro
     */
    public function phoneMask($phone) {


        if (substr($phone, 0, 4) == '0800') {
            return $this->mask($phone, '####-###-####');
        } else if (substr($phone, 0, 4) == '00800') {
            return $this->mask($phone, '# ####-###-####');
        } else if (strlen($phone) == 8) {
            return $this->mask($phone, '####-####');
        } else if (strlen($phone) == 10) {
            return $this->mask($phone, '(##) ####-####');
        } else if (strlen($phone) == 11) {
            if (substr($phone, 0, 1) == '0') {
                return $this->mask($phone, '# (##) ####-####');
            } else if (substr($phone, 2, 1) == '9') {
                return $this->mask($phone, '(##) #.####-####');
            } else {
                return $this->mask($phone, '# (##) ####-####');
            }
        } else if (strlen($phone) == 12) {
            if (substr($phone, 0, 1) == '0') {
                return $this->mask($phone, '# (##) #.####-####');
            } else {
                return $this->mask($phone, '# (##) #.####-####');
            }
        } else if (strlen($phone) == 13) {
            if (substr($phone, 0, 1) == '0') {
                return $this->mask($phone, '### (##) ####-####');
            } else {
                return $phone;
            }
        } else {
            return $phone;
        }
    }

    /**
     * Aplica qualquer mascara ao numero
     * ex: $this->mask($phone, '# (##) ####-####')
     */
    public function mask($val, $mask) {
        $maskared = '';
        $k = 0;
        for ($i = 0; $i <= strlen($mask) - 1; $i++) {
            if ($mask[$i] == '#') {
                if (isset($val[$k]))
                    $maskared .= $val[$k++];
            }
            else {
                if (isset($mask[$i]))
                    $maskared .= $mask[$i];
            }
        }
        return $maskared;
    }

    /**
     * Retorna a versao do sistema
     */
    public function current_version() {
        return Configure::read('System.version');
    }

    /**
     * Retorna atributos do site
     */
    public function read($param) {
        return Configure::read($param);
    }

    /**
     * Altera a cor do typo de usuario na tela de listagem de usuarios
     */
    public static function userTypeColor($type) {
        if ($type == 'registered') {
            return '<small class="igreen">' . $type . '</small>';
        } else if ($type == 'admin') {
            return '<small class="ired">' . $type . '</small>';
        }
        return '<small class="igray">' . $type . '</small>';
    }

    public function getUserId() {
        return $this->Session->read('Auth.User.id');
    }

    /**
     * Retorna o dia da semana da data passada
     */
    public function dayOfTheWeek($date) {
        $dayweek = array('Domingo', 'Segunda', 'Terça', 'Quarta', 'Quinta', 'Sexta', 'Sábado');
        $dayNumber = date('w', strtotime($date));
        return $dayweek[$dayNumber];
    }

}
