<?php

namespace App\Core\Template;

use Mustache_Engine as Mustache_Engine;
use Mustache_Loader_FilesystemLoader as Mustache_Loader_FilesystemLoader;

class Output
{

    private static $_instance;

    private $_template = '';
    private $_extension = '';

    private $_engine;

    private function __construct()
    {
        $this->_template = (defined('TEMPLATE_DEFAULT')) ? TEMPLATE_DEFAULT : 'DefaultTemplate';
        $this->_extension = (defined('TEMPLATE_FILETYPE')) ? TEMPLATE_FILETYPE : '.mustache';

        $this->_engine = new Mustache_Engine(array(
            'entity_flags' => ENT_QUOTES,
            'partials_loader' => new Mustache_Loader_FilesystemLoader(DIR_APP),
            'pragmas' => [Mustache_Engine::PRAGMA_FILTERS],
        ));

        // ========================
        // Helpers
        //

        // Format {{#icons}}xx{{/icons}} as a font awesome icon
        $this->_engine->addHelper('icons', function ($icon) {
            return "<i class='fa fa-" . trim($icon) . "' aria-hidden='true'></i>";
        });

        // Change the {{#strings}}string,module{{/strings}} for the requested localized string
        $this->_engine->addHelper('string', function ($string) {
            return \Lang::getString(...explode(',', trim($string)));
        });

        // ========================
        // Filters
        //

        $this->_engine->addHelper('case', [
            'lower' => function ($value) {
                return strtolower((string) $value);
            },
            'upper' => function ($value) {
                return strtoupper((string) $value);
            }
        ]);
    }

    private static function newObj()
    {
        if (!isset(self::$_instance)) {
            self::$_instance = new Output();
        }
        return self::$_instance;
    }

    public static function getInstance()
    {
        if (!isset(self::$_instance)) {
            return self::newObj();
        }
        return self::$_instance;
    }

    //
    // ----------------------------------------
    // Done with singletone and template boot
    //
    //

    public static function setTemplate($template = 'DefaultTemplate')
    {
        self::getInstance()->_template = $template;
        return self::getInstance();
    }

    public static function render($view = '', $values = array())
    {
        $instance = self::getInstance();

        $template = '';

        if ($view != '') {
            $segments = explode('/', debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)[0]['file']);
            array_pop($segments);
            $location = implode('/', $segments) . '/views/';

            if (is_file($location . $view . $instance->_extension)) {
                $template = file_get_contents($location . $view . $instance->_extension);
            }
        }

        if (is_ajax_request()) {
            echo $instance->_engine->render($template, $values);
            return;
        }

        if (!is_file(__DIR__ . "/classes/" . strtolower($instance->_template) . "/" . $instance->_template . '.php')) {
            $instance->_template = 'DefaultTemplate';
        }

        include_once __DIR__ . "/classes/" . strtolower($instance->_template) . "/" . $instance->_template . '.php';

        $wrapper = new $instance->_template;
        $wrapper = $wrapper->render($template);
        echo $instance->_engine->render($wrapper, $values);
    }


    //
    // ----------------------------------------
    // Menu Stuff Here
    //
    //

    public static function addMenu($route, $name, $icon = '', $attributes = [], $weight = 0){
        global $SIDEBAR;
        $SIDEBAR->add($route, $name, $icon, $attributes, $weight);
    }

    public static function addSubmenu($key, $name, $icon = '', $attributes = [], $weight = 0){
        global $SIDEBAR;
        $SIDEBAR->create_submenu($key, $name, $icon, $attributes , $weight);
    }

    public static function addOnSubmenu($key, $route, $name, $icon = '', $attributes = [], $weight = 0){
        global $SIDEBAR;
        $SIDEBAR->add_on_new($key, $route, $name, $icon, $attributes, $weight);
    }

    public static function headAdd($route, $name){
        global $DROPDOWN;
        $DROPDOWN[] = ['route' => $route, 'name' => $name];
    }

    public static function addSubHeader($key, $name, $icon = '', $attributes = [], $weight = 0){
        global $DROPDOWN;
        $DROPDOWN->create_submenu($key, $name, $icon, $attributes , $weight);
    }

    public static function addOnSubHeader($key, $route, $name, $icon = '', $attributes = [], $weight = 0){
        global $DROPDOWN;
        $DROPDOWN->add_on_new($key, $route, $name, $icon, $attributes, $weight);
    }
}
