<?php

App::uses('Controller', 'Controller');

/**
 * Application controller
 *
 * This file is the base controller of all other controllers
 *
 * PHP version 5
 *
 * @category Controllers
 * @package  Bemmelhor
 * @version  1.0
 * @author   Fabricio S Costa <fabriciojf@gmail.com>
 *
 * @link     http://www.bemmelhor.org
 */
class AppController extends Controller {

    /**
     * Components
     *
     * @var array
     * @access public
     */
    public $components = array(
        'Bemmelhor',
        'Security' => array(
            'csrfUseOnce' => false,
            'csrfExpires' => '+2 hour'
        ),
        'Acl',
        'Auth',
        'Session',
        'RequestHandler',
        'FilterResults.FilterResults' => array(
            'auto' => array(
                'paginate' => false,
                'explode' => true, // recommended
            ),
            'explode' => array(
                'character' => ' ',
                'concatenate' => 'AND',
            )
        )
    );

    /**
     * Helpers
     *
     * @var array
     * @access public
     */
    public $helpers = array(
        'Api',
        'Html',
        'Form',
        'Session',
        'Text',
        'Js',
        'Time',
        'Layout',
        'Custom',
        'Dashboard',
        'Javascript',
        'Ajax',
        'FilterResults.FilterForm' => array(
            'operators' => array(
                'LIKE' => 'containing',
                'NOT LIKE' => 'not containing',
                'LIKE BEGIN' => 'starting with',
                'LIKE END' => 'ending with',
                '=' => 'equal to',
                '!=' => 'different',
                '>' => 'greater than',
                '>=' => 'greater or equal to',
                '<' => 'less than',
                '<=' => 'less or equal to'
            )
        ),
    );

    /**
     * Models
     *
     * @var array
     * @access public
     */
    public $uses = array(
        'Block',
        'Link',
        'Setting',
        'Node',
    );

    /**
     * Pagination
     */
    public $paginate = array(
        'limit' => 10,
    );

    /**
     * Cache pagination results
     *
     * @var boolean
     * @access public
     */
    public $usePaginationCache = true;

    /**
     * View
     *
     * @var string
     * @access public
     */
    public $viewClass = 'Theme';

    /**
     * Theme
     *
     * @var string
     * @access public
     */
    public $theme;

    /**
     * Constructor
     *
     * @access public
     */
    public function __construct($request = null, $response = null) {
        Bemmelhor::applyHookProperties('Hook.controller_properties', $this);
        parent::__construct($request, $response);
    }

    /**
     * beforeFilter
     *
     * @return void
     * @throws MissingComponentException
     */
    public function beforeFilter() {
        parent::beforeFilter();
        $aclFilterComponent = Configure::read('Site.acl_plugin') . 'Filter';
        if (empty($this->{$aclFilterComponent})) {
            throw new MissingComponentException(array('class' => $aclFilterComponent));
        }
        $this->{$aclFilterComponent}->auth();
        $this->RequestHandler->setContent('json', 'text/x-json');
        $this->Security->blackHoleCallback = 'securityError';
        $this->Security->requirePost('admin_delete');

        if (isset($this->request->params['admin'])) {
            $this->layout = 'admin';
        }

        if ($this->RequestHandler->isAjax()) {
            $this->layout = 'ajax';
        }

        if (Configure::read('Site.theme') && !isset($this->request->params['admin'])) {
            $this->theme = Configure::read('Site.theme');
        } elseif (Configure::read('Site.admin_theme') && isset($this->request->params['admin'])) {
            $this->theme = Configure::read('Site.admin_theme');
        }

        if (!isset($this->request->params['admin']) &&
                Configure::read('Site.status') == 0) {
            $this->layout = 'maintenance';
            $this->response->statusCode(503);
            $this->set('title_for_layout', __('Site down for maintenance'));
            $this->render('../Elements/blank');
        }

        $locale = $this->Auth->User('locale');
        if (isset($locale) && ($locale != '')) {
            Configure::write('Config.language', $locale);
        }
        $this->set('submenu', 'default');
    }

    /**
     * blackHoleCallback for SecurityComponent
     *
     * @return void
     */
    public function securityError($type) {
        switch ($type) {
            case 'auth':
                break;
            case 'csrf':
                break;
            case 'get':
                break;
            case 'post':
                break;
            case 'put':
                break;
            case 'delete':
                break;
            default:
                break;
        }
        $this->set(compact('type'));
        $this->response = $this->render('../Errors/security');
        $this->response->statusCode(400);
        $this->response->send();
        $this->_stop();
        return false;
    }

    /**
     * Seta um valor default para o datepicker
     * @param unknown $field
     */
    public function setDatepicker($field, $hour = '') {
        if (!isset($this->request['data'][$field]) || trim($this->request['data'][$field]) == '') {
            $this->request->data($field, date(trim('Y-m-d ' . $hour)));
        }
    }

    /**
     * Formata itens no padrao input(type=date)
     * @param unknown_type $period
     */
    protected function formatDateTime($from = array(), $to = array()) {

        $first = trim($from) != '' ? $from : date('Y-m-d 0:0:0');
        $last = trim($to) != '' ? $to : date('Y-m-d 23:59:59');

        $params = array(
            'start' => $first,
            'end' => $last
        );
        return $params;
    }

    /**
     * Formata itens no padrao input(type=date)
     */
    protected function formatOneDay($date = array()) {

        if (count($date) == 0) {
            $params = array(
                'start' => date('Y-m-d 0:0:0', strtotime("now")),
                'end' => date('Y-m-d 23:59:59', strtotime("now")),
            );
        } else {
            $params = array(
                'start' => $date . ' 00:00',
                'end' => $date . ' 23:59',
            );
        }
        return $params;
    }

    /**
     * Formata dados no padrao dias do ano, mesm, etc
     */
    protected function formatDayOf($period) {

        switch ($period) {
            case 'day' :
                $first = date('Y-m-d', strtotime("now"));
                $last = date('Y-m-d', strtotime('+1 days'));
                $label = "no Dia (" . $first . ')';
                break;

            case 'lastday' :
                $first = date('Y-m-d', strtotime("-1 days"));
                $last = date('Y-m-d', strtotime('now'));
                $label = "no Dia Anterior (" . $first . ')';
                break;

            case 'week' :
                $first = date('Y-m-d', strtotime("-1 weeks sunday"));
                $last = date('Y-m-d', strtotime('-0 weeks saturday'));
                $label = "na Semana (" . $first . '/' . $last . ')';
                break;

            case 'year' :
                $first = date('Y-1-1');
                $last = date('Y-12-31');
                $label = "no Ano (" . $first . '/' . $last . ')';
                break;

            default:
                $first = date('Y-m-1');
                $last = date('Y-m-t');
                $label = "no Mês (" . $first . '/' . $last . ')';
                break;
        }
        $params = array(
            'start' => $first,
            'end' => $last,
            'label' => $label
        );
        return $params;
    }

    protected function log_text($message) {
        CakeLog::write('omni', '');
        CakeLog::write('omni', $message);
        CakeLog::write('omni', '');
    }

    protected function log_array($array) {
        CakeLog::write('omni', '');
        CakeLog::write('omni', json_encode($array));
        CakeLog::write('omni', '');
    }

    /**
     * Gera um debug para a tabela DebugLog
     */
    protected function dump_app($content, $current_function = '') {

        $this->loadModel('DebugLog');

        $this->DebugLog->create();
        $this->DebugLog->set('app_origin', 'OmniSolution');
        $this->DebugLog->set('content', $content);
        $this->DebugLog->set('current_function', $current_function);
        $this->DebugLog->save();
    }

    /**
     * function to clear all cache data
     * by default accessible only for admin
     *
     * @access Public
     * @return void
     */
    public function clear_cache() {
        Cache::clear();
        clearCache();

        $files = array();
        $files = array_merge($files, glob(CACHE . '*')); // remove cached css
        $files = array_merge($files, glob(CACHE . 'css' . DS . '*')); // remove cached css
        $files = array_merge($files, glob(CACHE . 'js' . DS . '*'));  // remove cached js
        $files = array_merge($files, glob(CACHE . 'models' . DS . '*'));  // remove cached models
        $files = array_merge($files, glob(CACHE . 'persistent' . DS . '*'));  // remove cached persistent
        $files = array_merge($files, glob(CACHE . 'queries' . DS . '*'));  // remove cached persistent

        foreach ($files as $f) {
            if (is_file($f)) {
                unlink($f);
            }
        }

        if (function_exists('apc_clear_cache')):
            apc_clear_cache();
            apc_clear_cache('user');
        endif;
    }

    /**
     * Retorna uma lista de faqs relacionados ao termo
     */
    protected function faq($term) {

        if (trim($term) != '') {
            $this->loadModel('Wiki');
            $this->set('faq_term', $term);
            $this->set('wikis', $this->Wiki->find('all', array(
                        'conditions' => array(
                            'Wiki.tags like' => "%{$term}%"
                        ),
                        'fields' => array(
                            'title',
                            'slug'
                        )
            )));
        }
    }

    /**
     * Itens por pagina
     */
    protected function items_per_page($page_reference = '', $orderby = '') {

        if ((isset($page_reference)) && (trim($page_reference) != '')) {
            $this->loadModel('ItemsPerPage');

            $items = $this->ItemsPerPage->find('first', array(
                'conditions' => array(
                    'ItemsPerPage.user_id' => $this->Auth->user('id'),
                    'ItemsPerPage.page_reference like' => $page_reference,
                )
            ));

            if (!$items) {

                $item = array(
                    'ItemsPerPage' => array(
                        'orderby' => $orderby,
                        'page_reference' => $page_reference,
                        'user_id' => $this->Auth->user('id'),
                        'quantity' => 20,
                    )
                );

                $this->ItemsPerPage->create();
                if ($this->ItemsPerPage->save($item)) {
                    return $this->ItemsPerPage->read(false, $this->ItemsPerPage->id);
                }
            }
        }
        return $items;
    }

    /**
     * Retorna um json de itens para popular um combo
     */
    public function admin_set_items_per_page() {

        if ($this->request->is('get')) {

            $data = $this->request->query;
            $this->loadModel('ItemsPerPage');
            $items = $this->ItemsPerPage->find('first', array(
                'conditions' => array(
                    'ItemsPerPage.user_id' => $this->Auth->user('id'),
                    'ItemsPerPage.page_reference like' => "{$data['controller']}/{$data['action']}",
                )
            ));

            $this->request->data['ItemsPerPage']['id'] = $items['ItemsPerPage']['id'];
            $this->request->data['ItemsPerPage']['quantity'] = $data['items_quantity'];
            $this->request->data['ItemsPerPage']['orderby_field'] = $data['orderby_field'];
            $this->request->data['ItemsPerPage']['orderby_type'] = $data['orderby_type'];

            $this->ItemsPerPage->save($this->request->data);

            $this->redirect(array(
                'controller' => $data['controller'],
                'action' => $data['action']
            ));
        }
    }

    /**
     * Retorna um boolean para o box de buscas
     */
    public function admin_set_box_visibility() {

        $this->autoRender = false;
        if ($this->request->is('ajax')) {

            $data = $this->request->query;
            $this->loadModel('FindBoxVisibility');
            $items = $this->FindBoxVisibility->find('first', array(
                'conditions' => array(
                    'FindBoxVisibility.user_id' => $this->Auth->user('id'),
                    'FindBoxVisibility.page_reference like' => "{$data['tpage_controller']}/{$data['tpage_action']}",
                )
            ));

            $this->request->data['FindBoxVisibility']['id'] = $items['FindBoxVisibility']['id'];
            $this->request->data['FindBoxVisibility']['visible'] = $data['tstatus'] == 'show' ? true : false;
            $this->request->data['FindBoxVisibility']['user_id'] = $this->Auth->user('id');
            $this->request->data['FindBoxVisibility']['page_reference'] = "{$data['tpage_controller']}/{$data['tpage_action']}";

            $this->FindBoxVisibility->save($this->request->data);
        }
        die();
    }

    /**
     * Retorna um boolean para o box de buscas
     */
    public function box_visibility($controller, $action) {

        $data = $this->request->query;
        $this->loadModel('FindBoxVisibility');
        $items = $this->FindBoxVisibility->find('first', array(
            'conditions' => array(
                'FindBoxVisibility.user_id' => $this->Auth->user('id'),
                'FindBoxVisibility.page_reference like' => "{$controller}/{$action}",
            )
        ));
        if (count($items) > 0) {
            if ($items['FindBoxVisibility']['visible'] == true) {
                return array(
                    'visibility' => 'inherit',
                    'icon' => 'ion-reply-all',
                    'size' => 'col-md-10',
                );
            }
        }
        return array(
            'visibility' => 'none',
            'icon' => 'ion-navicon-round',
            'size' => 'col-md-12',
        );
    }

    /**
     * Retorna um boolean para o box de buscas
     */
    public function admin_get_box_visibility() {

        $this->autoRender = false;
        if ($this->request->is('ajax')) {

            $data = $this->request->query;
            $this->loadModel('FindBoxVisibility');
            $items = $this->FindBoxVisibility->find('first', array(
                'conditions' => array(
                    'FindBoxVisibility.user_id' => $this->Auth->user('id'),
                    'FindBoxVisibility.page_reference like' => "{$data['tpage_controller']}/{$data['tpage_action']}",
                )
            ));
            return json_encode(array(
                "is_visible" => $items['FindBoxVisibility']['visible']
            ));
        }
    }
}
