"""
// ==UserScript==
// @name         Enhanced Rectangle Drawer Tool with Trusted Types
// @namespace    http://your.namespace.here/
// @version      1.2
// @description  Draw, manage, and interact with rectangles on any webpage with Trusted Types compliance. Features enhanced usability and interactivity.
// @author       Your Name
// @match        *://*/*
// @grant        none
// @run-at       document-end
// ==/UserScript==

(function () {
    'use strict';

    let TTP;

    // **Trusted Types Policy Creation**
    if (window.trustedTypes && window.trustedTypes.createPolicy) {
        TTP = window.trustedTypes.createPolicy('default', {
            createHTML: (input) => input, // Allow all HTML strings (use with caution)
            createScriptURL: (input) => input,
            createScript: (input) => input,
            emptyScript: () => '',
        });
    }

    // **Logging to Verify Script Execution**
    console.log("Enhanced Rectangle Drawer Tool with Trusted Types is running!");

    /**
     * RectangleDrawer Class
     * Handles creation, management, and interaction of rectangles on the webpage.
     */
    class RectangleDrawer {
        static cssInjected = false;

        constructor(options = {}) {
            this.options = {
                persistent: true, // Whether rectangles remain after drawing
                ...options,
            };
            this.rects = new Map();
            this.currentRect = null;
            this.isDrawing = false;
            this.isResizing = false;
            this.resizingInfo = null;
            this.isDragging = false;
            this.draggingInfo = null;
            this.drawingMode = false;
            this.startX = 0;
            this.startY = 0;
            this.rectIdCounter = 0;

            this.injectCSS();
            this.initEvents();
        }

        /**
         * Inject necessary CSS styles into the webpage.
         * Uses Trusted Types to safely inject CSS if policies are enforced.
         */
        injectCSS() {
            if (RectangleDrawer.cssInjected) return;

            const style = document.createElement('style');
            const cssContent = `
                .rectangle-drawer-rect {
                    position: absolute;
                    border: 2px solid #3498db;
                    background-color: rgba(52, 152, 219, 0.2);
                    box-sizing: border-box;
                    z-index: 9999;
                    cursor: move;
                    transition: box-shadow 0.2s;
                }
                .rectangle-drawer-rect:hover {
                    box-shadow: 0 0 10px rgba(52, 152, 219, 0.7);
                }
                .rectangle-drawer-rect .delete-btn {
                    position: absolute;
                    top: -10px;
                    right: -10px;
                    background: #e74c3c;
                    color: white;
                    border: none;
                    border-radius: 50%;
                    width: 24px;
                    height: 24px;
                    display: none;
                    cursor: pointer;
                    align-items: center;
                    justify-content: center;
                    font-size: 16px;
                    line-height: 24px;
                    padding: 0;
                    box-shadow: 0 0 5px rgba(0,0,0,0.3);
                }
                .rectangle-drawer-rect:hover .delete-btn {
                    display: flex;
                }
                .rectangle-drawer-rect .delete-btn:hover {
                    background: #c0392b;
                }
                .rectangle-drawer-rect .resize-handle {
                    position: absolute;
                    width: 12px;
                    height: 12px;
                    background: #3498db;
                    cursor: nwse-resize;
                    border: 1px solid white;
                    box-sizing: border-box;
                }
                .rectangle-drawer-rect .resize-handle.nw {
                    top: -6px;
                    left: -6px;
                    cursor: nwse-resize;
                }
                .rectangle-drawer-rect .resize-handle.ne {
                    top: -6px;
                    right: -6px;
                    cursor: nesw-resize;
                }
                .rectangle-drawer-rect .resize-handle.sw {
                    bottom: -6px;
                    left: -6px;
                    cursor: nesw-resize;
                }
                .rectangle-drawer-rect .resize-handle.se {
                    bottom: -6px;
                    right: -6px;
                    cursor: nwse-resize;
                }
                /* UI Container Styles */
                .rectangle-drawer-ui {
                    position: fixed;
                    top: 20px;
                    right: 20px;
                    background: rgba(0, 0, 0, 0.7);
                    padding: 10px;
                    border-radius: 8px;
                    z-index: 10000;
                    display: flex;
                    flex-direction: column;
                    gap: 10px;
                }
                .rectangle-drawer-ui button {
                    padding: 8px 12px;
                    background: #3498db;
                    color: white;
                    border: none;
                    border-radius: 4px;
                    cursor: pointer;
                    font-size: 14px;
                    transition: background 0.2s;
                }
                .rectangle-drawer-ui button:hover {
                    background: #2980b9;
                }
            `;
            if (TTP) {
                // Use Trusted Types to safely inject CSS
                style.textContent = TTP.createHTML(cssContent);
            } else {
                // Fallback if Trusted Types are not enforced
                style.textContent = cssContent;
            }
            document.head.appendChild(style);
            RectangleDrawer.cssInjected = true;
        }

        /**
         * Initialize event listeners for drawing, resizing, and dragging rectangles.
         */
        initEvents() {
            this.mouseDownHandler = this.onMouseDown.bind(this);
            this.mouseMoveHandler = this.onMouseMove.bind(this);
            this.mouseUpHandler = this.onMouseUp.bind(this);
            document.addEventListener('mousedown', this.mouseDownHandler);
            document.addEventListener('mousemove', this.mouseMoveHandler);
            document.addEventListener('mouseup', this.mouseUpHandler);

            // Handle window resize to keep rectangles in view
            window.addEventListener('resize', () => {
                this.rects.forEach((data, id) => {
                    const rectElem = document.querySelector(`.rectangle-drawer-rect[data-id="${id}"]`);
                    if (rectElem) {
                        rectElem.style.left = `${data.left}px`;
                        rectElem.style.top = `${data.top}px`;
                        rectElem.style.width = `${data.width}px`;
                        rectElem.style.height = `${data.height}px`;
                    }
                });
            });
        }

        /**
         * Activate drawing mode. The user can draw rectangles until they exit the mode.
         */
        activateDrawingMode() {
            this.drawingMode = true;
            // Optionally, you can indicate drawing mode via UI (e.g., change cursor)
            document.body.style.cursor = 'crosshair';
        }

        /**
         * Handle mouse down event to start drawing, resizing, or dragging.
         */
        onMouseDown(e) {
            // Only respond to left mouse button
            if (e.button !== 0) return;

            // If not in drawing mode, check if clicking on a rectangle for dragging
            if (!this.drawingMode) {
                const rectElem = e.target.closest('.rectangle-drawer-rect');
                if (rectElem) {
                    // Prevent initiating drag if clicking on resize handle or delete button
                    if (e.target.classList.contains('resize-handle') || e.target.classList.contains('delete-btn')) {
                        return;
                    }
                    this.isDragging = true;
                    this.draggingInfo = {
                        rect: rectElem,
                        startX: e.pageX,
                        startY: e.pageY,
                        startLeft: parseInt(rectElem.style.left, 10),
                        startTop: parseInt(rectElem.style.top, 10),
                    };
                    return;
                }
            }

            // If in drawing mode, start drawing a new rectangle
            if (this.drawingMode) {
                // Prevent drawing if clicked on existing rectangle or UI
                if (e.target.closest('.rectangle-drawer-rect') || e.target.closest('.rectangle-drawer-ui')) return;

                this.isDrawing = true;
                this.startX = e.pageX;
                this.startY = e.pageY;

                const rect = document.createElement('div');
                rect.classList.add('rectangle-drawer-rect');
                rect.style.left = `${this.startX}px`;
                rect.style.top = `${this.startY}px`;
                rect.style.width = `0px`;
                rect.style.height = `0px`;
                rect.style.cursor = 'crosshair';

                // Create delete button using DOM methods
                const deleteBtn = document.createElement('button');
                deleteBtn.classList.add('delete-btn');
                deleteBtn.innerHTML = '&times;';
                deleteBtn.title = 'Delete Rectangle';
                deleteBtn.addEventListener('click', (event) => {
                    event.stopPropagation();
                    const rectId = rect.getAttribute('data-id');
                    this.removeRect(rectId);
                });
                rect.appendChild(deleteBtn);

                // Create resize handles
                ['nw', 'ne', 'sw', 'se'].forEach((corner) => {
                    const handle = document.createElement('div');
                    handle.classList.add('resize-handle', corner);
                    rect.appendChild(handle);
                    // Handle resizing
                    handle.addEventListener('mousedown', (event) => this.initResize(event, rect, corner));
                });

                document.body.appendChild(rect);
                this.currentRect = rect;
            }
        }

        /**
         * Handle mouse move event to draw, resize, or drag a rectangle.
         */
        onMouseMove(e) {
            const { pageX, pageY } = e;

            // Drawing a new rectangle
            if (this.isDrawing && this.currentRect) {
                const width = pageX - this.startX;
                const height = pageY - this.startY;
                this.currentRect.style.width = `${Math.abs(width)}px`;
                this.currentRect.style.height = `${Math.abs(height)}px`;
                this.currentRect.style.left = `${width < 0 ? pageX : this.startX}px`;
                this.currentRect.style.top = `${height < 0 ? pageY : this.startY}px`;
                return;
            }

            // Resizing an existing rectangle
            if (this.isResizing && this.resizingInfo) {
                const { rect, corner, startX, startY, startWidth, startHeight, startLeft, startTop } = this.resizingInfo;
                const deltaX = pageX - startX;
                const deltaY = pageY - startY;

                let newWidth = startWidth;
                let newHeight = startHeight;
                let newLeft = startLeft;
                let newTop = startTop;

                if (corner.includes('e')) {
                    newWidth = startWidth + deltaX;
                }
                if (corner.includes('s')) {
                    newHeight = startHeight + deltaY;
                }
                if (corner.includes('w')) {
                    newWidth = startWidth - deltaX;
                    newLeft = startLeft + deltaX;
                }
                if (corner.includes('n')) {
                    newHeight = startHeight - deltaY;
                    newTop = startTop + deltaY;
                }

                if (newWidth > 20) {
                    rect.style.width = `${newWidth}px`;
                    rect.style.left = `${newLeft}px`;
                }
                if (newHeight > 20) {
                    rect.style.height = `${newHeight}px`;
                    rect.style.top = `${newTop}px`;
                }
                return;
            }

            // Dragging an existing rectangle
            if (this.isDragging && this.draggingInfo) {
                const deltaX = pageX - this.draggingInfo.startX;
                const deltaY = pageY - this.draggingInfo.startY;
                let newLeft = this.draggingInfo.startLeft + deltaX;
                let newTop = this.draggingInfo.startTop + deltaY;

                // Optional: Constrain within the viewport
                const rectElem = this.draggingInfo.rect;
                const rectWidth = parseInt(rectElem.style.width, 10);
                const rectHeight = parseInt(rectElem.style.height, 10);
                const maxLeft = window.innerWidth - rectWidth;
                const maxTop = window.innerHeight - rectHeight;
                newLeft = Math.max(0, Math.min(newLeft, maxLeft));
                newTop = Math.max(0, Math.min(newTop, maxTop));

                rectElem.style.left = `${newLeft}px`;
                rectElem.style.top = `${newTop}px`;
                return;
            }
        }

        /**
         * Handle mouse up event to finalize drawing, resizing, or dragging.
         */
        onMouseUp(e) {
            if (this.isDrawing && this.currentRect) {
                this.isDrawing = false;
                this.drawingMode = false; // Exit drawing mode after drawing one rectangle
                document.body.style.cursor = 'default';
                const rect = this.currentRect;
                const id = `rect-${++this.rectIdCounter}`;
                rect.setAttribute('data-id', id);
                rect.style.cursor = 'move';

                if (this.options.persistent) {
                    this.rects.set(id, this.getRectData(rect));
                } else {
                    rect.remove();
                }

                this.currentRect = null;
                return;
            }

            if (this.isResizing) {
                this.isResizing = false;
                this.resizingInfo = null;
                const rect = this.currentlyResizing;
                const id = rect.getAttribute('data-id');
                if (id && this.rects.has(id)) {
                    this.rects.set(id, this.getRectData(rect));
                }
                this.currentlyResizing = null;
                return;
            }

            if (this.isDragging) {
                this.isDragging = false;
                const rect = this.draggingInfo.rect;
                const id = rect.getAttribute('data-id');
                if (id && this.rects.has(id)) {
                    this.rects.set(id, this.getRectData(rect));
                }
                this.draggingInfo = null;
                return;
            }
        }

        /**
         * Initialize resizing of a rectangle.
         */
        initResize(event, rect, corner) {
            event.stopPropagation(); // Prevent triggering other events
            this.isResizing = true;
            this.currentlyResizing = rect;
            this.resizingInfo = {
                rect,
                corner,
                startX: event.pageX,
                startY: event.pageY,
                startWidth: parseInt(window.getComputedStyle(rect).width, 10),
                startHeight: parseInt(window.getComputedStyle(rect).height, 10),
                startLeft: parseInt(window.getComputedStyle(rect).left, 10),
                startTop: parseInt(window.getComputedStyle(rect).top, 10),
            };
        }

        /**
         * Remove a rectangle by its ID.
         */
        removeRect(id) {
            const rect = this.rects.get(id);
            if (rect) {
                const elem = document.querySelector(`.rectangle-drawer-rect[data-id="${id}"]`);
                if (elem) elem.remove();
                this.rects.delete(id);
            }
        }

        /**
         * Remove all rectangles from the page.
         */
        clearAllRects() {
            this.rects.forEach((_, id) => this.removeRect(id));
        }

        /**
         * Retrieve all rectangles with their IDs and coordinates.
         */
        getAllRects() {
            const rectData = [];
            this.rects.forEach((data, id) => {
                rectData.push({ id, ...data });
            });
            return rectData;
        }

        /**
         * Get rectangle data (position and size).
         */
        getRectData(rect) {
            const id = rect.getAttribute('data-id');
            const left = parseInt(rect.style.left, 10);
            const top = parseInt(rect.style.top, 10);
            const width = parseInt(rect.style.width, 10);
            const height = parseInt(rect.style.height, 10);
            return { left, top, width, height };
        }

        /**
         * Clean up event listeners and remove all rectangles.
         */
        destroy() {
            document.removeEventListener('mousedown', this.mouseDownHandler);
            document.removeEventListener('mousemove', this.mouseMoveHandler);
            document.removeEventListener('mouseup', this.mouseUpHandler);
            window.removeEventListener('resize', this.onWindowResize);
            this.clearAllRects();
        }
    }

    /**
     * UIManager Class
     * Handles the creation and management of the user interface.
     */
    class UIManager {
        constructor(drawerInstance) {
            this.drawer = drawerInstance;
            this.createUI();
        }

        /**
         * Create the fixed UI container with buttons.
         * Uses Trusted Types to safely inject HTML if policies are enforced.
         */
        createUI() {
                const uiContainer = document.createElement('div');
                uiContainer.classList.add('rectangle-drawer-ui');

                // Create New Rect Button using DOM methods
                const newRectBtn = document.createElement('button');
                newRectBtn.innerText = 'New Rect';
                newRectBtn.title = 'Start drawing a new rectangle';
                newRectBtn.addEventListener('click', () => this.drawer.activateDrawingMode());

                // Create Clear All Button using DOM methods
                const clearAllBtn = document.createElement('button');
                clearAllBtn.innerText = 'Clear All';
                clearAllBtn.title = 'Remove all rectangles';
                clearAllBtn.addEventListener('click', () => {
                    if (confirm('Are you sure you want to remove all rectangles?')) {
                        this.drawer.clearAllRects();
                    }
                });

                // Append buttons to the UI container
                uiContainer.appendChild(newRectBtn);
                uiContainer.appendChild(clearAllBtn);

                // Append UI container to the body using Trusted Types if available
                if (TTP) {
                    document.body.appendChild(uiContainer);
                } else {
                    document.body.appendChild(uiContainer);
                }
        }
    }

    // Instantiate the RectangleDrawer
    const drawer = new RectangleDrawer({
        persistent: true, // Set to false if rectangles should not remain after drawing
    });

    // Instantiate the UI Manager
    const uiManager = new UIManager(drawer);

    // Optional: Expose drawer and uiManager to the global scope for debugging
    window.RectangleDrawer = drawer;
    window.UIManager = uiManager;

})();
"""

1. how should the delete button for each rect be designed? right now its just a red button at top right of rect which is weird looking.
2. anything to improve?