<?php
namespace Tripetto;

class Theme
{
    static function isTransparent($value)
    {
        $value = trim($value);

        // Treat empty, the "transparent" keyword and fully transparent rgba()/hsla()
        // values (e.g. rgba(0,0,0,0)) as transparent. WordPress 7 emits such a value
        // as the initial background of .button-primary.
        return $value === "" || stripos($value, "transparent") !== false || preg_match('/^(rgba|hsla)\(.*,\s*0(\.0+)?\s*\)$/i', $value);
    }

    static function isColor($value)
    {
        $value = trim($value);

        if (Theme::isTransparent($value)) {
            return false;
        }

        // Accept hex colors (#rgb, #rgba, #rrggbb, #rrggbbaa) and color functions.
        return preg_match('/^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i', $value) || preg_match("/^(rgb|rgba|hsl|hsla)\(/i", $value);
    }

    static function color($css, $rule, $fallback)
    {
        $start = strpos($css, $rule);

        if ($start !== false) {
            $start += strlen($rule);
            $end = strpos($css, "}", $start);
            $block = $end !== false ? substr($css, $start, $end - $start) : substr($css, $start);

            // Scan the declarations for the first usable, non-transparent color. WordPress 7
            // can prefix the rule with a transparent "background" reset before the actual
            // "background-color", so we keep looking instead of trusting the first match.
            foreach (explode(";", $block) as $declaration) {
                $i = strpos($declaration, ":");

                if ($i === false) {
                    continue;
                }

                $name = substr($declaration, 0, $i);
                $value = substr($declaration, $i + 1);

                if (($name === "background" || $name === "background-color") && Theme::isColor($value)) {
                    return $value;
                }
            }
        }

        // No usable color found (missing rule, transparent reset, or a CSS variable we
        // cannot resolve server-side): fall back to the supplied default color.
        return $fallback;
    }

    static function colors()
    {
        global $_wp_admin_css_colors;

        $colors = Helpers::createJSON();

        $colors->background = "#f1f1f1";
        $colors->primary = "#2271b1";
        $colors->secondary = "#1d2327";

        $theme = get_user_option("admin_color", get_current_user_id());

        if (!empty($theme)) {
            $theme_colors = $_wp_admin_css_colors[$theme];

            if (!empty($theme_colors) && isset($theme_colors->url) && !empty($theme_colors->url)) {
                $response = wp_safe_remote_get($theme_colors->url);

                if (is_array($response) && !is_wp_error($response) && isset($response["body"])) {
                    $css = strval($response["body"]);

                    if (!empty($css)) {
                        $css = str_replace(" ", "", $css);

                        $colors->background = Theme::color($css, "body{", $colors->background);
                        $colors->primary = Theme::color($css, ".button-primary{", $colors->primary);
                    }
                }
            }
        }

        return $colors;
    }
}
?>
