<?php

namespace helpers;

/**
 * Helper class for rendering template
 *
 * @copyright  Copyright (c) Tobias Zeising (http://www.aditu.de)
 * @license    GPLv3 (https://www.gnu.org/licenses/gpl-3.0.html)
 * @author     Tobias Zeising <tobias.zeising@aditu.de>
 */
class View {
    /** @var string current base url */
    public $base = '';

    /**
     * set global view vars
     */
    public function __construct() {
        $this->genMinifiedJsAndCss();
        $this->base = $this->getBaseUrl();
    }

    /**
     * Returns the base url of the page. If a base url was configured in the
     * config.ini this will be used. Otherwise base url will be generated by
     * globale server variables ($_SERVER).
     */
    public static function getBaseUrl() {
        $base = '';

        // base url in config.ini file
        if (strlen(trim(\F3::get('base_url'))) > 0) {
            $base = \F3::get('base_url');
            $length = strlen($base);
            if ($length > 0 && substr($base, $length - 1, 1) != '/') {
                $base .= '/';
            }

        // auto generate base url
        } else {
            $protocol = 'http';
            if ((isset($_SERVER['HTTPS']) && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ||
                (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') ||
                (isset($_SERVER['HTTP_HTTPS']) && $_SERVER['HTTP_HTTPS'] == 'https')) {
                $protocol = 'https';
            }

            // check for SSL proxy
            if (isset($_SERVER['HTTP_X_FORWARDED_SERVER']) && isset($_SERVER['HTTP_X_FORWARDED_HOST'])
            && ($_SERVER['HTTP_X_FORWARDED_SERVER'] === $_SERVER['HTTP_X_FORWARDED_HOST'])) {
                $subdir = '/' . preg_replace('/\/[^\/]+$/', '', $_SERVER['PHP_SELF']);
                $host = $_SERVER['HTTP_X_FORWARDED_SERVER'];
            } else {
                $subdir = \F3::get('BASE');
                $host = $_SERVER['SERVER_NAME'];
            }

            $port = '';
            if (($protocol == 'http' && $_SERVER['SERVER_PORT'] != '80') ||
                ($protocol == 'https' && $_SERVER['SERVER_PORT'] != '443')) {
                $port = ':' . $_SERVER['SERVER_PORT'];
            }
            //Override the port if nginx is the front end and the traffic is being forwarded
            if (isset($_SERVER['HTTP_X_FORWARDED_PORT'])) {
                $port = ':' . $_SERVER['HTTP_X_FORWARDED_PORT'];
            }

            $base = $protocol . '://' . $host . $port . $subdir . '/';
        }

        return $base;
    }

    /**
     * render template
     *
     * @param string $template file
     *
     * @return string rendered html
     */
    public function render($template) {
        ob_start();
        include $template;
        $content = ob_get_contents();
        ob_end_clean();

        return $content;
    }

    /**
     * send error message
     *
     * @param string $message
     *
     * @return void
     */
    public function error($message) {
        header('HTTP/1.0 400 Bad Request');
        die($message);
    }

    /**
     * send error message as json string
     *
     * @param mixed $datan
     *
     * @return void
     */
    public function jsonError($data) {
        header('Content-type: application/json');
        $this->error(json_encode($data));
    }

    /**
     * send success message as json string
     *
     * @param mixed $datan
     *
     * @return void
     */
    public function jsonSuccess($data) {
        header('Content-type: application/json');
        die(json_encode($data));
    }

    /**
     * returns global JavaScript file name (all.js)
     *
     * @return string all.js file name
     */
    public static function getGlobalJsFileName() {
        return 'all-v' . \F3::get('version') . '.js';
    }

    /**
     * returns global CSS file name (all.css)
     *
     * @return string all.css file name
     */
    public static function getGlobalCssFileName() {
        return 'all-v' . \F3::get('version') . '.css';
    }

    /**
     * generate minified css and js
     *
     * @return void
     */
    public function genMinifiedJsAndCss() {
        // minify js
        $targetJs = \F3::get('BASEDIR') . '/public/' . self::getGlobalJsFileName();
        if (!file_exists($targetJs) || \F3::get('DEBUG') != 0) {
            $js = '';
            foreach (\F3::get('js') as $file) {
                $js = $js . "\n" . $this->minifyJs(file_get_contents(\F3::get('BASEDIR') . '/' . $file));
            }
            file_put_contents($targetJs, $js);
        }

        // minify css
        $targetCss = \F3::get('BASEDIR') . '/public/' . self::getGlobalCssFileName();
        if (!file_exists($targetCss) || \F3::get('DEBUG') != 0) {
            $css = '';
            foreach (\F3::get('css') as $file) {
                $css = $css . "\n" . $this->minifyCss(file_get_contents(\F3::get('BASEDIR') . '/' . $file));
            }
            file_put_contents($targetCss, $css);
        }
    }

    /**
     * minifies javascript if DEBUG mode is disabled
     *
     * @param javascript to minify
     *
     * @return minified javascript
     */
    private function minifyJs($content) {
        if (\F3::get('DEBUG') != 0) {
            return $content;
        }

        return \JSMin::minify($content);
    }

    /**
     * minifies css if DEBUG mode is disabled
     *
     * @param css to minify
     *
     * @return minified css
     */
    private function minifyCss($content) {
        if (\F3::get('DEBUG') != 0) {
            return $content;
        }

        return \CssMin::minify($content);
    }
}
