<?php
/**
 * mageia.org global nav bar utilities.
 *
 * PHP version 5.4
 *
 * @category Mageia
 * @package  Mageia\Web\nav
 * @author   rda <rda@mageia.org>
 * @link     http://nav.mageia.org/
 *
 * @license http://www.gnu.org/licenses/gpl-2.0.html GNU GPL v2+
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License aspublished by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
*/
// definition

require_once('php-mo.php');

// languages for home
$langs = array(
    'af' => 'Afrikaans',
    'ar' => 'العربية/عربي',
    'ast' => 'Asturianu',
    'bg' => 'Български',
    'bn' => 'বাংলা',
    'ca' => 'Català',
    'cy' => 'Cymraeg',
    'cs' => 'Čeština',
    'da' => 'Dansk',
    'de' => 'Deutsch',
    'el' => 'Ελληνικά',
    'en' => 'English',
    'en-gb' => 'English GB',
    'eo' => 'Esperanto',
    'es' => 'Español',
    'et' => 'Eesti',
    'eu' => 'Euskara',
    'fi' => 'Suomeksi',
    'fr' => 'Français',
    'he' => 'עברית',
    'hi' => 'हिन्दी',
    'hr' => 'Hrvatski',
    'hu' => 'Magyar',
    'ia' => 'Interlingua',
    'id' => 'Bahasa Indonesia',
    'it' => 'Italiano',
    'ja' => '日本語',
    'lo' => 'ພາສາລາວ',
    'lv' => 'Latviešu',
    'lt' => 'Lietuvių',
    'nb' => 'Bokmål',
    'nl' => 'Nederlands',
    'pl' => 'Polski',
    'pms' => 'Piemontèis',
    'pt' => 'Português',
    'pt-br' => 'Português do Brasil',
    'ro' => 'Română',
    'ru' => 'Русский',
    'sco' => 'Scots',
    'sk' => 'Slovenčina',
    'sl' => 'Slovenščina',
    'sq' => 'Gjuha shqipe',
    'sr' => 'Српски',
    'sv' => 'Svenska',
    'tg' => 'Тоҷикӣ',
    'th' => 'ภาษาไทย',
    'tr' => 'Türkçe',
    'uk' => 'Українська',
    'ur' => 'اردو',
    'zh-cn' => '简体中文',
    'zh-tw' => '正體中文'
);

/**
 * Enables RTL language changes
 *
 * Returns TRUE if $locale is RTL
 */
function is_locale_rtl($locale)
{
    return in_array($locale, array('ar', 'he', 'tg', 'ur'));
}

class NCache
{
    function __construct() { }

    /**
     * Factory.
     *
     * @param string $path where cache file store is located, relative to app path.
     * @param integer $timeout in seconds
     *
     * @return NCache
    */
    public static function build($path, $timeout = 3600)
    {
        $path = __DIR__ . '/' . $path;

        if (!is_dir($path))
            return null;

        if ($timeout < 60)
            $timeout = 60;

        $i           = new self;
        $i->_path    = $path;
        $i->_timeout = $timeout;

        return $i;
    }

    /**
     * Get value for $key.
     *
     * @param mixed $key
     *
     * @return mixed
    */
    function get($key = null)
    {
        if (is_null($key))
            return false;

        $filename = $this->_get_filename($key);

        if ($this->_is_valid_file($filename, $this->_timeout)) {
            return unserialize(file_get_contents($filename));
        }

        return null;
    }

    /**
     * Save $value under $key.
     *
     * @param mixed $key
     * @param mixed $value
    */
    function set($key, $value)
    {
        if (is_null($key))
            return false;

        $filename = $this->_get_filename($key);
        file_put_contents($filename, serialize($value));

        return true;
    }

    /**
     * Get cache file from key.
     *
     * @param mixed $key
     *
     * @return string
    */
    private function _get_filename($key)
    {
        $key  = hash('sha1', serialize($key));

        return $this->_path . '/' . $key . '.cache';
    }

    /**
     * Check that the cache file exists and has not expired.
     *
     * @param string $filename
     *
     * @return boolean
    */
    private function _is_valid_file($filename, $timeout)
    {
        if (!file_exists($filename)) {
            //error_log(sprintf('Could not find %s', $filename), 0);
            return false;
        }

        if (filemtime($filename) + $timeout < time()) {
            //error_log(sprintf('%s timestamp expired (timeout was %ds.).', $filename, $timeout));
            unlink($filename);
            return false;
        }

        //error_log(sprintf('Found %s', $filename));
        return true;
    }
}

class l10n
{
//    public static $t;

    /**
     * Load langs/$lang.lang into global $_t array.
     *
     * @param string $lang
     *
     * @return void
    */
    public static function load($lang)
    {
        global $_t;
        $_t = array();

        if ($lang == 'en')
            return;

        $po_file    = __DIR__ . '/langs/' . $lang . '.po';
        $cache_file = __DIR__ . '/var/tmp/cache/nav_lang_' . $lang . '.php';
        $_ts        = 0;
        $po_ts      = 0;
        if (file_exists($po_file)) {
            $po_ts  = filemtime($po_file);
        }

        if (file_exists($cache_file)) {
            // quick and dirty safety mechanism for file integrity test bug #15252
            if ('$eof = TRUE;' == substr(php_strip_whitespace($cache_file), -12)) {
                include $cache_file;
                if ($_ts > $po_ts) {
                    return;
                }
            }
        }

        if (file_exists($po_file)) {
            $dictionary = phpmo_parse_po_file($po_file);

            foreach ($dictionary as $key => $value) {
                if ($key != '') {
                    if ($value[0][0] != '') {
                        $_t[trim($key)] = trim($value[0][0]);
                    } else {
                        $_t[trim($key)] = trim($key);
                    }
                }
            }

            $_t_data = var_export($_t, true);
            $cache   = <<<P
<?php
/**! Generated. Do not edit. */

// filemtime($po_file)
\$_ts = $po_ts;

// $lang strings
global \$_t;
\$_t = $_t_data;

\$eof = TRUE;
P;
            file_put_contents($cache_file, $cache);
        }
    }

    /**
     * Get value for key $s in global array $_t.
     *
     * @param string $s
     *
     * @return string
    */
    public static function _t($s) {
        if (trim($s) == '')
            return '';

        global $_t;

        $s = array_key_exists($s, $_t) ? $_t[$s] : $s;
        $s = trim(str_replace(array('{ok}', '{OK}', '{Ok}', '{oK}'), '', $s));

        return $s;
    }
}

/**
 * Produce navigation HTML code.
 *
 * @param boolean $wrap = false should it be wrapped in a <header id="nav" /> element?
 * @param string  $lang = 'en'
 * @param string  $inject = null
 * @param string  $vhost = 'www.mageia.org'
 * @param object  $cache
 *
 * @return string HTML code
*/
function _mgnav_html($wrap = false, $lang = 'en', $inject = null, $vhost = 'www.mageia.org', $cache = null)
{
    $key = array($wrap, $lang, $inject, $vhost);

    if (!is_null($cache) && ($h = $cache->get($key))) {
        apache_note('navCacheHit', 1);
        return $h;
    }

    apache_note('navCacheHit', 0);

    $lang = _lang_check($lang);

    l10n::load($lang, $cache);

    $tn = array(
        //array('mageia',     '//$S/$L/map/',           'Mageia',                  l10n::_t('Go to mageia.org site map.')),
        array('about',      '//$S/$L/about/',         l10n::_t('About&nbsp;us'), l10n::_t('Learn more about Mageia.')),
        array('downloads',  '//$S/$L/downloads/',     l10n::_t('Downloads'),     l10n::_t('Download Mageia ISO and updates.')),
        array('support',    '//$S/$L/support/',       l10n::_t('Support'),       l10n::_t('Get support from Mageia community.')),
        array('wiki',       l10n::_t('//wiki.mageia.org/'),     l10n::_t('Wiki'),          l10n::_t('Wiki of the Mageia Community')),
        array('doc',        '//$S/$L/doc/',           l10n::_t('Docs'),          l10n::_t('Documentations of Mageia')),
        array('community',  '//$S/$L/community/',     l10n::_t('Community'),     l10n::_t('')),
        array('contribute', '//$S/$L/contribute/',    l10n::_t('Contribute'),    l10n::_t('You too can build Mageia with us!')),
        array('donate',     '//$S/$L/donate/',        l10n::_t('Donate'),        l10n::_t('')),
        array('you',        '//identity.mageia.org/', l10n::_t('You'),           l10n::_t('Your Mageia online account.')),
        array('contact',    '//$S/$L/contact/',       l10n::_t('Contact'),       l10n::_t('Contact Us'))
    //    <search>
    );

    $s = array();
    foreach ($tn as $i) {
        $s[] = sprintf('<li class="nav-item"><a href="%s" class="%s nav-link" title="%s">%s</a></li>',
            str_replace(
                array('$L', '$S'),
                array($lang, $vhost),
                $i[1]
            ),
            $i[0],
            $i[3],
            $i[2]
        );
    }

    if (!is_null($inject))
        $s[] = sprintf('%s', $inject);

    $s = implode($s);
    $links_direction = is_locale_rtl($lang) ? ' dir="rtl"' : '';
    $links_position = is_locale_rtl($lang) ? 'ml-auto' : 'mr-auto';
    $navbar_collapse_position = is_locale_rtl($lang) ? 'style="text-align: right;"' : 'style="text-align: left;"';
    $h = sprintf('<!--googleoff: all-->
    <div' . $links_direction . ' class="mganav">
        <nav id="mgnav" class="container navbar navbar-expand-lg navbar-light">
            <a class="navbar-brand text-hide" href="//'. $vhost .'/'. $lang. '">Mageia</a>
            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
                <div class="collapse navbar-collapse" ' . $navbar_collapse_position . ' id="navbarNav">
                    <ul class="navbar-nav ' . $links_position . '">%s</ul>
                </div>
            </nav>
    </div><!--googleon: all-->', $s);

    if ($wrap)
        $h = sprintf('<header id="hmgn" class="sticky-top">%s
</header>', $h);

    if (!is_null($cache))
        $cache->set($key, $h);

    return $h;
}

/**
 * Returns CSS definition ready to be inserted into a HTML document.
 *
 * @return string
*/
function _mgnav_style()
{
	if ( defined('ALIGNMENT') && constant('ALIGNMENT') == 'Center' ){
		return '<style>' . file_get_contents(__DIR__ . '/css/source.css') . '</style><style>' . file_get_contents(__DIR__ . '/css/center.css') . '</style>';
	} else {
		return '<style>' . file_get_contents(__DIR__ . '/css/source.css') . '</style>';
	}
}

/**
 * Get the primary language subtag only.<p></p>
*/
function _lang_check($s = null)
{
    if (is_null($s)) {
        return 'en';
    }

    global $langs;
    $supported = array_keys($langs);

    if (in_array($s, $supported))
        return $s;

    $sub = explode('-', $s);
    $sub = strtolower($sub[0]);

    if (in_array($sub, $supported))
        return $sub;

    return 'en';
}