<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.

/**
 * This is built using the bootstrapbase template to allow for new theme's using Moodle's new Bootstrap theme engine
 *
 * @package   theme_remui
 * @copyright (c) 2023 WisdmLabs (https://wisdmlabs.com/) <support@wisdmlabs.com>
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
namespace theme_remui;

define("THEMEREMUI", "theme_remui");
/**
 * This is built using the bootstrapbase template to allow for new theme's using.
 * @copyright (c) 2022 WisdmLabs (https://wisdmlabs.com/) <support@wisdmlabs.com>
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
class toolbox {

    /**
     * Core renderer object
     * @var null
     */
    protected $corerenderer = null;

    /**
     * Toolbox instance
     * @var toolbox
     */
    protected static $instance;

    /**
     * Private constructor for singletone class.
     */
    private function __construct() {
    }

    /**
     * Get singletone instance of toolbox
     * @return toolbox Class instance
     */
    public static function get_instance() {
        if (!is_object(self::$instance)) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Sets the core_renderer class instance so that when purging all caches and 'theme_xxx_process_css' etc.
     * the settings are correct.
     * @param core_renderer $core Child object of core_renderer class.
     */
    public static function set_core_renderer($core) {
        $us = self::get_instance();
        // Set only once from the initial calling lib.php process_css function so that subsequent parent calls do not override it.
        // Must happen before parents.
        if (null === $us->corerenderer) {
            $us->corerenderer = $core;
        }
    }

    /**
     * Get theme settings
     * @param  string $setting Theme settings
     * @return string          Settings value
     */
    public static function get_theme_setting($setting) {
        $us = self::check_corerenderer();
        $themeconfig = $us->get_theme_config();
        $tcr = array_reverse($themeconfig, true);

        $settingvalue = false;
        foreach ($tcr as $tconfig) {
            if (property_exists($tconfig->settings, $setting)) {
                $settingvalue = $tconfig->settings->$setting;
                break;
            }
        }
        return $settingvalue;
    }

    /**
     * Finds the given setting in the theme from the themes' configuration object.
     * @param  string $setting Setting name.
     * @param  string $format  false|'format_text'|'format_html'.
     * @return any             false|value of setting.
     */
    public static function get_setting($setting, $format = false) {
        global $CFG;
        $us = self::check_corerenderer();
        $themeconfig = $us->get_theme_config();
        $tcr = array_reverse($themeconfig, true);
        $settingvalue = false;
        foreach ($tcr as $tconfig) {
            if (property_exists($tconfig->settings, $setting)) {
                $settingvalue = $tconfig->settings->$setting;
                break;
            }
        }
        if (!$settingvalue) {
            return false;
        }

        require_once($CFG->dirroot . '/lib/weblib.php');
        if (empty($settingvalue)) {
            return false;
        } else if (!$format) {
            return $settingvalue;
        } else if ($format === 'format_text') {
            return format_text($settingvalue, FORMAT_PLAIN);
        } else if ($format === 'format_html') {
            return format_text($settingvalue, FORMAT_HTML, array('trusted' => true, 'noclean' => true));
        } else if ($format === 'format_file_url') {
            return self::setting_file_url($setting, $setting);
        } else {
            return format_string($settingvalue);
        }
    }

    /**
     * Get file url from settings
     * @param  String $setting  Settings name
     * @param  String $filearea Filearea
     * @return String           String
     */
    public static function setting_file_url($setting, $filearea) {
        $us = self::check_corerenderer();
        $themeconfig = $us->get_theme_config();
        $tcr = array_reverse($themeconfig, true);
        $settingconfig = null;
        foreach ($tcr as $tconfig) {
            if (property_exists($tconfig->settings, $setting)) {
                $settingconfig = $tconfig;
                break;
            }
        }
        if ($settingconfig) {
            return $settingconfig->setting_file_url($setting, $filearea);
        }
        return null;
    }

    /**
     * Fetch image url
     *
     * @param  String $imagename Image name
     * @param  String $component Image component
     *
     * @return String            Image url
     */
    public static function image_url($imagename, $component) {
        $us = self::check_corerenderer();
        return $us->image_url($imagename, $component);
    }

    /**
     * Get renderer
     * @return object Renderer object
     */
    private static function check_corerenderer() {
        $us = self::get_instance();
        if (empty($us->corerenderer)) {
            // Use $OUTPUT unless is not a Remui or child core_renderer which can happen on theme switch.
            global $OUTPUT;
            if (property_exists($OUTPUT, 'remui')) {
                $us->corerenderer = $OUTPUT;
            } else {
                // Use $PAGE->theme->name as will be accurate than $CFG->theme when using URL theme changes.
                // Core 'allowthemechangeonurl' setting.
                global $PAGE;
                $corerenderer = null;
                try {
                    $corerenderer = $PAGE->get_renderer('theme_'.$PAGE->theme->name, 'core');
                } catch (\coding_exception $ce) {
                    // Specialised renderer may not exist in theme.  This is not a coding fault.  We just need to cope.
                    $corerenderer = null;
                }
                // Fallback check.
                if (($corerenderer != null) && (property_exists($corerenderer, 'remui'))) {
                    $us->corerenderer = $corerenderer;
                } else {
                    // Probably during theme switch, '$CFG->theme' will be accurrate.
                    global $CFG;
                    try {
                        $corerenderer = $PAGE->get_renderer('theme_'.$CFG->theme, 'core');
                    } catch (\coding_exception $ce) {
                        // Specialised renderer may not exist in theme.  This is not a coding fault.  We just need to cope.
                        $corerenderer = null;
                    }
                    if (($corerenderer != null) && (property_exists($corerenderer, 'remui'))) {
                        $us->corerenderer = $corerenderer;
                    } else {
                        // Last resort.  Hopefully will be fine on next page load for Child themes.
                        // However '***_process_css' in lib.php will be fine as it sets the correct renderer.
                        $us->corerenderer = $PAGE->get_renderer('theme_remui', 'core');
                    }
                }
            }
        }
        return $us->corerenderer;
    }

    /**
     * Set font in css
     *
     * @param String  $css      Css content
     * @param String  $fontname Font name
     *
     * @return String           Css content
     */
    public static function set_font($css, $fontname) {
        $fontfamilytag = '[[setting:fontfamily]]';
        $familyreplacement = $fontname;

        $css = str_replace($fontfamilytag, $familyreplacement, $css);

        return $css;
    }

    /**
     * Set color in the css
     *
     * @param String  $css           Css content
     * @param String  $themecolor    Color
     * @param String  $tag           Css content
     * @param String  $defaultcolour Color
     *
     * @return String                Css content
     */
    public static function set_color($css, $themecolor, $tag, $defaultcolour) {
        if (!($themecolor)) {
            $replacement = $defaultcolour;
        } else {
            $replacement = $themecolor;
        }

        $css = str_replace($tag, $replacement, $css);
        return $css;
    }

    /**
     * Set custom css
     * @param String  $css       Css content
     * @param String  $customcss Css content
     *
     * @return String            Css content
     */
    public static function set_customcss($css, $customcss) {
        $tag = '[[setting:customcss]]';
        $replacement = $customcss;
        $css = str_replace($tag, $replacement, $css);
        return $css;
    }

    /**
     * Set logo in the css
     *
     * @param String  $css  Css content
     * @param String  $logo Logo url
     *
     * @return String       Css content
     */
    public static function set_logo($css, $logo) {
        $tag = '[[setting:logo]]';
        if (!($logo)) {
            $replacement = 'none';
        } else {
            $replacement = 'url(\''.$logo.'\')';
        }
        $css = str_replace($tag, $replacement, $css);
        return $css;
    }

    /**
     * Set logo height in the css
     *
     * @param String  $css        Css content
     * @param String  $logoheight Logo height
     *
     * @return String             Css content
     */
    public static function set_logoheight($css, $logoheight) {
        $tag = '[[setting:logoheight]]';
        if (!($logoheight)) {
            $replacement = '65px';
        } else {
            $replacement = $logoheight;
        }
        $css = str_replace($tag, $replacement, $css);
        return $css;
    }

    /**
     * Set single plugin config
     * @param string $configname Config name
     * @param string $configdata Config data
     */
    public static function set_plugin_config($configname, $configdata) {
        set_config($configname, $configdata, THEMEREMUI);
    }

    /**
     * Set plugin config data of multiple config names
     * @param array $configdata Plugin config data array
     */
    public static function set_plugin_configs($configdata = array()) {
        foreach ($configdata as $configname => $value) {
            self::set_plugin_config($configname, $value);
        }
    }

    /**
     * Get plugin config from config name
     * @param  string $configname Plugin config name
     * @return string             Config data from db
     */
    public static function get_plugin_config($configname) {
        return get_config(THEMEREMUI, $configname);
    }

    /**
     * This function Requires array of confignames
     * Unset the Plugin Configs
     * @param string|array $confignames Plugin config names
     */
    public static function remove_plugin_config($confignames) {
        if (!is_array($confignames)) {
            $confignames = array($confignames);
        }

        foreach ($confignames as $value) {
            unset_config($value, THEMEREMUI);
        }
    }

}
