<?php
//
// Custom Text Dashlet
// Copyright (c) 2025 Nagios Enterprises, LLC. All rights reserved.
//

include_once(dirname(__FILE__) . '/../dashlethelper.inc.php');

// Run the initialization function
custom_text_dashlet_init();

function custom_text_dashlet_init()
{
    $name = "custom_text";

    $args = array(
        DASHLET_NAME => $name,
        DASHLET_VERSION => "1.0.1",
        DASHLET_AUTHOR => "Nagios Enterprises, LLC",
        DASHLET_DESCRIPTION => _("Display custom text in a dashlet with full styling options."),
        DASHLET_FILTER_GROUPS => array("custom"),
        DASHLET_COPYRIGHT => "Dashlet Copyright &copy; 2025 Nagios Enterprises.",
        DASHLET_LICENSE => "MIT",
        DASHLET_HOMEPAGE => "https://www.nagios.com",
        DASHLET_FUNCTION => "custom_text_dashlet_func",
        DASHLET_TITLE => _("Custom Text"),
        DASHLET_OUTBOARD_CLASS => "custom_text_outboardclass",
        DASHLET_INBOARD_CLASS => "custom_text_inboardclass",
        DASHLET_PREVIEW_CLASS => "custom_text_previewclass",
        DASHLET_JS_FILE => "js/preview.js",
        DASHLET_WIDTH => "300",
        DASHLET_HEIGHT => "200",
        DASHLET_OPACITY => "1.0",
        DASHLET_BACKGROUND => "",
        DASHLET_ISCUSTOM => false
    );

    register_dashlet($name, $args);
}

function custom_text_dashlet_func($mode = DASHLET_MODE_PREVIEW, $id = "", $args = null)
{
    $output = "";
    $imgbase = get_dashlet_url_base("custom_text") . "/images/";

    switch ($mode) {
        case DASHLET_MODE_GETCONFIGHTML:
            if (get_theme() == "xi5") {
                $input_background = "white;";
            } else if (get_theme() == "xi5dark") {
                $input_background = "#333;";
            } else if (get_theme() == "neptunelight" || get_theme() == "neptunelightdark") {
                $input_background = "var(--input);";
            } else {
                $input_background = "white;";
            }

            $output = '
            <script>
                // Fixes dashlet config menu location on Modern themes
                setTimeout(function() {
                    var configbox = document.getElementsByClassName("ui-draggable")[0];
                    configbox.style.removeProperty("top");
                }, 0);

                // Update character count for the textarea
                document.getElementById("displaytext").addEventListener("input", function() {
                    var current = this.value.length;
                    var max = this.getAttribute("maxlength");
                    document.getElementById("charCount").textContent = current + "/" + max + " characters";
                });
            </script>

            <div class="form-group">
                <label for="displaytext">'._('Text to Display').'</label>
                <div>
                    <textarea name="displaytext" class="form-control" id="displaytext" rows="4" maxlength="1000" onchange="updatePreview()"></textarea>
                    <small class="text-muted" id="charCount">0/1000 characters</small>
                </div>
            </div>

            <div class="form-group">
                <label for="fontfamily">'._('Font Family').'</label>
                <select name="fontfamily" class="form-control" id="fontfamily" onchange="updatePreview()">
                    <option value="Arial, sans-serif" style="font-family: Arial">Arial</option>
                    <option value="Courier New, monospace" style="font-family: Courier New">Courier New</option>
                    <option value="Geneva, sans-serif" style="font-family: Geneva">Geneva</option>
                    <option value="Georgia, serif" style="font-family: Georgia">Georgia</option>
                    <option value="Helvetica, sans-serif" style="font-family: Helvetica">Helvetica</option>
                    <option value="Lucida Console, monospace" style="font-family: Lucida Console">Lucida Console</option>
                    <option value="Tahoma, sans-serif" style="font-family: Tahoma">Tahoma</option>
                    <option value="Times New Roman, serif" style="font-family: Times New Roman">Times New Roman</option>
                    <option value="Trebuchet MS, sans-serif" style="font-family: Trebuchet MS">Trebuchet MS</option>
                    <option value="Verdana, sans-serif" style="font-family: Verdana">Verdana</option>
                </select>
            </div>

            <div class="form-group">
                <label for="fontweight">'._('Font Weight').'</label>
                <div>
                    <select name="fontweight" class="form-control" id="fontweight" onchange="updatePreview()">
                        <option value="normal">Normal</option>
                        <option value="bold">Bold</option>
                        <option value="lighter">Light</option>
                    </select>
                </div>
            </div>

            <div class="form-group">
                <label>'._('Italic').'</label>
                <div>
                    <input type="checkbox" name="italic" id="italic" onchange="updatePreview()">
                </div>
            </div>

            <div class="form-group">
                <label>'._('Underline').'</label>
                <div>
                    <input type="checkbox" name="underline" id="underline" onchange="updatePreview()">
                </div>
            </div>

            <div class="form-group">
                <label>'._('Strikethrough').'</label>
                <div>
                    <input type="checkbox" name="strikethrough" id="strikethrough" onchange="updatePreview()">
                </div>
            </div>

            <div class="form-group">
                <label for="textcolor">'._('Text Color').'</label>
                <div>
                    <input type="color" name="textcolor" class="form-control" id="textcolor"
                           value="#000000" style="width: 100px; padding: 0;" onchange="updatePreview()">
                </div>
            </div>

            <div class="form-group">
                <label for="textopacity">'._('Text Opacity').'</label>
                <div>
                    <input type="range" name="textopacity" class="form-control" id="textopacity"
                           min="0" max="100" value="100" step="1" onchange="updatePreview()">
                    <span id="textopacityvalue">100%</span>
                </div>
            </div>

            <div class="form-group">
                <label for="bgcolor">'._('Background Color').'</label>
                <div>
                    <input type="color" name="bgcolor" class="form-control" id="bgcolor"
                           value="#ffffff" style="width: 100px; padding: 0;" onchange="updatePreview()">
                    <div style="margin-top: 5px;">
                        <input type="checkbox" name="bgtransparent" id="bgtransparent" onchange="updatePreview()">
                        <label for="bgtransparent">'._('Transparent Background').'</label>
                    </div>
                </div>
            </div>

            <div class="form-group">
                <label for="bgopacity">'._('Background Opacity').'</label>
                <div>
                    <input type="range" name="bgopacity" class="form-control" id="bgopacity"
                           min="0" max="100" value="100" step="1" onchange="updatePreview()">
                    <span id="bgopacityvalue">100%</span>
                </div>
            </div>

            <div class="form-group">
                <label for="bordercolor">'._('Border Color').'</label>
                <div>
                    <input type="color" name="bordercolor" class="form-control" id="bordercolor"
                           value="#000000" style="width: 100px; padding: 0;" onchange="updatePreview()">
                    <div style="margin-top: 5px;">
                        <input type="checkbox" name="bordertransparent" id="bordertransparent" onchange="updatePreview()">
                        <label for="bordertransparent">'._('Transparent Border').'</label>
                    </div>
                </div>
            </div>

            <div class="form-group">
                <label for="borderwidth">'._('Border Width').'</label>
                <div>
                    <input type="range" name="borderwidth" class="form-control" id="borderwidth"
                           min="0" max="50" value="1" step="1" onchange="updatePreview()">
                    <span id="borderwidthvalue">1px</span>
                </div>
            </div>

            <div class="form-group">
                <label for="borderradius">'._('Border Radius').'</label>
                <div>
                    <input type="range" name="borderradius" class="form-control" id="borderradius"
                           min="0" max="360" value="0" step="1" onchange="updatePreview()">
                    <span id="borderradiusvalue">0px</span>
                </div>
            </div>

            <div class="form-group">
                <label for="borderopacity">'._('Border Opacity').'</label>
                <div>
                    <input type="range" name="borderopacity" class="form-control" id="borderopacity"
                           min="0" max="100" value="100" step="1" onchange="updatePreview()">
                    <span id="borderopacityvalue">100%</span>
                </div>
            </div>

            <div class="form-group">
                <label>'._('Preview').'</label>
                <div id="dashletPreview" class="dashlet-preview" style="
                    background-color: var(--input);
                    padding: 10px;
                    height: 200px;
                    width: 400px;
                    margin-top: 10px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    text-align: center;
                    overflow: hidden;
                    position: relative;
                    box-sizing: border-box;
                ">
                    <div id="previewContent" style="
                        max-width: 100%;
                        max-height: 100%;
                        word-wrap: break-word;
                    ">
                    </div>
                </div>
            </div>

            <script type="text/javascript">
                // Add event listeners for all inputs that affect the preview
                document.getElementById("displaytext").addEventListener("input", updatePreview);
                document.getElementById("fontfamily").addEventListener("change", updatePreview);
                document.getElementById("fontweight").addEventListener("change", updatePreview);
                document.getElementById("italic").addEventListener("change", updatePreview);
                document.getElementById("underline").addEventListener("change", updatePreview);
                document.getElementById("strikethrough").addEventListener("change", updatePreview);
                document.getElementById("textcolor").addEventListener("change", updatePreview);
                document.getElementById("textopacity").addEventListener("input", updatePreview);
                document.getElementById("bgcolor").addEventListener("change", updatePreview);
                document.getElementById("bgtransparent").addEventListener("change", updatePreview);
                document.getElementById("bgopacity").addEventListener("input", updatePreview);
                document.getElementById("bordercolor").addEventListener("change", updatePreview);
                document.getElementById("bordertransparent").addEventListener("change", updatePreview);
                document.getElementById("borderwidth").addEventListener("input", updatePreview);
                document.getElementById("borderradius").addEventListener("input", updatePreview);
                document.getElementById("borderopacity").addEventListener("input", updatePreview);

                // Initial preview
                updatePreview();
            </script>
            ';
            break;

        case DASHLET_MODE_PREVIEW:
            if(!is_neptune()) {
                $output = "<p><img src='" . $imgbase . "preview_other.png'></p>";
            } else if (get_theme() == "neptunelight") {
                $output = "<img src='" . $imgbase . "preview.png' style='max-width: 100%; height: auto;'>";
            } else {
                $output = "<img src='" . $imgbase . "text_preview.png' style='max-width: 100%'>";
            }
            break;

        case DASHLET_MODE_OUTBOARD:
        case DASHLET_MODE_INBOARD:
            $displaytext = isset($args["displaytext"]) ? htmlspecialchars($args["displaytext"]) : "";
            $fontfamily = isset($args["fontfamily"]) ? $args["fontfamily"] : "Arial, sans-serif";
            $fontweight = isset($args["fontweight"]) ? $args["fontweight"] : "normal";

            // Process text color
            $textColor = "black";
            if (isset($args["textcolor"])) {
                $opacity = isset($args["textopacity"]) ? $args["textopacity"] / 100 : 1;
                $textColor = "rgba(" . implode(",", sscanf($args["textcolor"], "#%02x%02x%02x")) . ",$opacity)";
            }

            // Process italic
            $italic = isset($args["italic"]) && $args["italic"] === "on" ? "italic" : "normal";

            // Process underline
            $underline = isset($args["underline"]) && $args["underline"] === "on" ? "underline" : "none";

            // Process strikethrough
            $strikethrough = isset($args["strikethrough"]) && $args["strikethrough"] === "on" ? "line-through" : "none";

            // Combine text decoration styles
            $textDecoration = [];
            if ($underline === "underline") {
                $textDecoration[] = "underline";
            }
            if ($strikethrough === "line-through") {
                $textDecoration[] = "line-through";
            }

            // Set the final text decoration style
            $finalTextDecoration = implode(" ", $textDecoration) ?: "none";

            // Process background color
            $bgColor = "";
            if (isset($args["bgtransparent"]) && $args["bgtransparent"] === "on") {
                $bgColor = "transparent";
            } else if (isset($args["bgcolor"])) {
                $opacity = isset($args["bgopacity"]) ? $args["bgopacity"] / 100 : 1;
                $bgColor = "rgba(" . implode(",", sscanf($args["bgcolor"], "#%02x%02x%02x")) . ",$opacity)";
            }

            // Process border
            $borderWidth = isset($args["borderwidth"]) ? intval($args["borderwidth"]) : 0;
            $borderColor = "";
            if (isset($args["bordertransparent"]) && $args["bordertransparent"] === "on") {
                $borderColor = "transparent";
            } else if (isset($args["bordercolor"])) {
                $opacity = isset($args["borderopacity"]) ? $args["borderopacity"] / 100 : 1;
                $borderColor = "rgba(" . implode(",", sscanf($args["bordercolor"], "#%02x%02x%02x")) . ",$opacity)";
            }

            // Handle border radius
            $borderRadius = isset($args["borderradius"]) ? intval($args["borderradius"]) : 0;

            $output = '
            <script>
                document.addEventListener("DOMContentLoaded", function() {
                    setTimeout(function() {
                        var element = document.getElementById("text-container-'.$id.'");
                        while (element && !element.classList.contains("dashboarddashletcontainer")) {
                            element = element.parentElement;
                        }

                        if (element) {
                            element.style.setProperty("background-color", "transparent", "important");
                        }
                    }, 100);
                });
            </script>
            <div class="text-dashlet-wrapper" style="position: relative; height: 100%; width: 100%;">
                <div class="text-display-container" id="text-container-'.$id.'" style="
                    padding: 10px;
                    font-family: '.$fontfamily.';
                    font-weight: '.$fontweight.';
                    font-style: '.$italic.';
                    text-decoration: '.$finalTextDecoration.';
                    color: '.$textColor.';
                    background-color: '.$bgColor.';
                    border: '.$borderWidth.'px solid '.$borderColor.';
                    border-radius: '.$borderRadius.'px;
                    height: 100%;
                    width: 100%;
                    box-sizing: border-box;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    text-align: center;
                    overflow: hidden;
                    position: relative;
                ">
                    <div id="text-content-'.$id.'" style="
                        text-align: center;
                        word-wrap: break-word;
                        max-width: 100%;
                    ">
                        '.nl2br($displaytext).'
                    </div>
                </div>
            </div>

            <script>
            (function() {
                function initResize() {
                    var container = document.getElementById("text-container-'.$id.'");
                    var content = document.getElementById("text-content-'.$id.'");

                    if (!container || !content) return;

                    function resizeText() {
                        var containerRect = container.getBoundingClientRect();
                        var fontSize = 100;
                        content.style.fontSize = fontSize + "px";

                        // Binary search for the best font size
                        var minSize = 1;
                        var maxSize = 1000;

                        while (minSize <= maxSize) {
                            fontSize = Math.floor((minSize + maxSize) / 2);
                            content.style.fontSize = fontSize + "px";

                            if (content.scrollHeight <= containerRect.height - 20 &&
                                content.scrollWidth <= containerRect.width - 20) {
                                minSize = fontSize + 1;
                            } else {
                                maxSize = fontSize - 1;
                            }
                        }

                        // Set final font size
                        fontSize = Math.max(1, maxSize);
                        content.style.fontSize = fontSize + "px";
                    }

                    resizeText();
                    window.addEventListener("resize", resizeText);
                    if (window.ResizeObserver) {
                        new ResizeObserver(resizeText).observe(container);
                    }
                }

                setTimeout(initResize, 100);
            })();
            </script>
            ';
            break;
    }

    return $output;
}
