<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Box Packaging Design Selector</title>
<style>
    body, html {
        margin: 0;
        overflow: hidden;
        height: 100%;
        display: flex;
        flex-direction: column;
    }
    #toolbar {
        display: flex;
        align-items: center;
        padding: 5px;
        background-color: #f0f0f0;
    }
    #importImageButton {
        margin-right: 10px;
    }
    #faceList {
        display: flex;
        gap: 10px;
    }
    .face-item {
        display: flex;
        align-items: center;
        gap: 5px;
    }
    .face-label {
        width: 50px;
    }
    #canvasContainer {
        flex: 1;
        position: relative;
    }
    #imageCanvas {
        width: 100%;
        height: 100%;
        background-color: #ccc;
        cursor: crosshair;
    }
    .handle {
        position: absolute;
        width: 10px;
        height: 10px;
        background: red;
        border: 1px solid #fff;
        border-radius: 50%;
        cursor: pointer;
    }
    .selection-label {
        position: absolute;
        background-color: rgba(255, 255, 255, 0.5);
        padding: 2px 5px;
        border-radius: 3px;
        pointer-events: none;
        font-weight: bold;
    }
</style>
</head>
<body>

<div id="toolbar">
    <button id="importImageButton">Import Image</button>
    <input type="file" id="imageLoader" accept="image/*" style="display:none"/>
    <div id="faceList">
        <!-- Faces will be dynamically added here -->
    </div>
</div>

<div id="canvasContainer">
    <canvas id="imageCanvas"></canvas>
</div>

<script>
    // JavaScript code

    // Get references to DOM elements
    const importImageButton = document.getElementById('importImageButton');
    const imageLoader = document.getElementById('imageLoader');
    const canvas = document.getElementById('imageCanvas');
    const faceList = document.getElementById('faceList');
    const canvasContainer = document.getElementById('canvasContainer');
    const ctx = canvas.getContext('2d');

    // Variables for canvas manipulation
    let image = new Image();
    let imgScale = 1;
    let imgPos = { x: 0, y: 0 };
    let isPanning = false;
    let panStart = { x: 0, y: 0 };
    let mouseStart = { x: 0, y: 0 };

    // Variables for selection
    let faces = ['front', 'back', 'right', 'left', 'top', 'bottom'];
    let selections = {};
    let currentFace = null;
    let isDrawing = false;
    let isEditing = false;
    let editHandle = null;
    let hoverHandle = null;
    let handles = [];
    const handleSize = 10;

    // Initialize canvas size
    function resizeCanvas() {
        canvas.width = canvasContainer.clientWidth;
        canvas.height = canvasContainer.clientHeight;
        draw();
    }
    window.addEventListener('resize', resizeCanvas);
    resizeCanvas();

    // Import image button click
    importImageButton.addEventListener('click', () => {
        imageLoader.click();
    });

    // Load selected image
    imageLoader.addEventListener('change', (e) => {
        const file = e.target.files[0];
        if (!file) return;
        const reader = new FileReader();
        reader.onload = (event) => {
            image.src = event.target.result;
            image.onload = () => {
                imgScale = 1;
                imgPos = { x: (canvas.width - image.width) / 2, y: (canvas.height - image.height) / 2 };
                draw();
            };
        };
        reader.readAsDataURL(file);
    });

    // Set up faces list
    faces.forEach(faceName => {
        // Create face item
        const faceItem = document.createElement('div');
        faceItem.className = 'face-item';

        // Add elements to face item
        const faceLabel = document.createElement('span');
        faceLabel.textContent = faceName;
        faceLabel.className = 'face-label';

        const addButton = document.createElement('button');
        addButton.textContent = 'Add';
        addButton.disabled = false;

        const deleteButton = document.createElement('button');
        deleteButton.textContent = 'Delete';
        deleteButton.disabled = true;

        const editButton = document.createElement('button');
        editButton.textContent = 'Edit';
        editButton.disabled = true;

        faceItem.appendChild(faceLabel);
        faceItem.appendChild(addButton);
        faceItem.appendChild(deleteButton);
        faceItem.appendChild(editButton);
        faceList.appendChild(faceItem);

        // Event listeners for buttons
        addButton.addEventListener('click', () => {
            currentFace = faceName;
            isDrawing = true;
            addButton.disabled = true;
            deleteButton.disabled = false;
            editButton.disabled = false;
        });

        deleteButton.addEventListener('click', () => {
            delete selections[faceName];
            addButton.disabled = false;
            deleteButton.disabled = true;
            editButton.disabled = true;
            draw();
        });

        editButton.addEventListener('click', () => {
            currentFace = faceName;
            isEditing = !isEditing;
            editButton.textContent = isEditing ? 'Done' : 'Edit';
            draw();
        });
    });

    // Canvas event handlers
    canvas.addEventListener('mousedown', (e) => {
        const rect = canvas.getBoundingClientRect();
        const mouseX = (e.clientX - rect.left);
        const mouseY = (e.clientY - rect.top);

        const imgMouseX = (mouseX - imgPos.x) / imgScale;
        const imgMouseY = (mouseY - imgPos.y) / imgScale;

        if (e.button === 1) {
            // Middle mouse button for panning
            isPanning = true;
            panStart = { x: imgPos.x, y: imgPos.y };
            mouseStart = { x: e.clientX, y: e.clientY };
        } else if (isDrawing && currentFace) {
            // Start drawing selection rectangle
            selections[currentFace] = {
                x: imgMouseX,
                y: imgMouseY,
                width: 0,
                height: 0
            };
            isDrawing = true;
        } else if (isEditing && selections[currentFace]) {
            // Check if clicked on handle
            const handle = getHandleUnderMouse(mouseX, mouseY);
            if (handle) {
                editHandle = handle;
            } else {
                // Start moving the selection
                editHandle = 'move';
                panStart = { x: selections[currentFace].x, y: selections[currentFace].y };
                mouseStart = { x: imgMouseX, y: imgMouseY };
            }
        }
    });

    canvas.addEventListener('mousemove', (e) => {
        const rect = canvas.getBoundingClientRect();
        const mouseX = (e.clientX - rect.left);
        const mouseY = (e.clientY - rect.top);

        const imgMouseX = (mouseX - imgPos.x) / imgScale;
        const imgMouseY = (mouseY - imgPos.y) / imgScale;

        if (isPanning) {
            // Panning
            imgPos.x = panStart.x + (e.clientX - mouseStart.x);
            imgPos.y = panStart.y + (e.clientY - mouseStart.y);
            draw();
        } else if (isDrawing && selections[currentFace]) {
            // Update selection rectangle size
            const sel = selections[currentFace];
            sel.width = imgMouseX - sel.x;
            sel.height = imgMouseY - sel.y;
            draw();
        } else if (isEditing && editHandle && selections[currentFace]) {
            // Edit selection rectangle
            const sel = selections[currentFace];
            if (editHandle === 'move') {
                sel.x = panStart.x + (imgMouseX - mouseStart.x);
                sel.y = panStart.y + (imgMouseY - mouseStart.y);
            } else {
                // Adjust selection based on handle
                adjustSelection(sel, editHandle, imgMouseX, imgMouseY);
            }
            draw();
        } else {
            // Update hover state for handles
            hoverHandle = getHandleUnderMouse(mouseX, mouseY);
            canvas.style.cursor = hoverHandle ? 'pointer' : 'default';
        }
    });

    canvas.addEventListener('mouseup', (e) => {
        isPanning = false;
        isDrawing = false;
        editHandle = null;
    });

    canvas.addEventListener('wheel', (e) => {
        // Zooming
        e.preventDefault();
        const delta = e.deltaY < 0 ? 1.1 : 0.9;
        const rect = canvas.getBoundingClientRect();
        const mouseX = (e.clientX - rect.left);
        const mouseY = (e.clientY - rect.top);

        const imgMouseX = (mouseX - imgPos.x) / imgScale;
        const imgMouseY = (mouseY - imgPos.y) / imgScale;

        imgScale *= delta;
        imgPos.x = mouseX - imgMouseX * imgScale;
        imgPos.y = mouseY - imgMouseY * imgScale;

        draw();
    });

    canvas.addEventListener('contextmenu', (e) => {
        e.preventDefault();
    });

    function draw() {
        // Clear canvas
        ctx.clearRect(0, 0, canvas.width, canvas.height);

        // Draw image
        if (image.src) {
            ctx.drawImage(image, imgPos.x, imgPos.y, image.width * imgScale, image.height * imgScale);
        }

        // Draw selections
        for (const faceName in selections) {
            const sel = selections[faceName];
            drawSelection(sel, faceName, faceName === currentFace && isEditing);
        }
    }

    function drawSelection(sel, label, showHandles) {
        ctx.save();
        ctx.strokeStyle = 'red';
        ctx.lineWidth = 2;
        ctx.strokeRect(
            sel.x * imgScale + imgPos.x,
            sel.y * imgScale + imgPos.y,
            sel.width * imgScale,
            sel.height * imgScale
        );

        // Draw label
        ctx.fillStyle = 'rgba(255, 255, 255, 0.5)';
        ctx.font = 'bold 14px Arial';
        const textWidth = ctx.measureText(label).width;
        ctx.fillRect(
            (sel.x + sel.width / 2) * imgScale + imgPos.x - textWidth / 2 - 5,
            (sel.y + sel.height / 2) * imgScale + imgPos.y - 15,
            textWidth + 10,
            20
        );
        ctx.fillStyle = 'black';
        ctx.fillText(
            label,
            (sel.x + sel.width / 2) * imgScale + imgPos.x - textWidth / 2,
            (sel.y + sel.height / 2) * imgScale + imgPos.y
        );

        // Draw handles if editing
        if (showHandles) {
            updateHandles(sel);
            handles.forEach(handle => {
                ctx.fillStyle = 'red';
                ctx.fillRect(handle.x - handleSize / 2, handle.y - handleSize / 2, handleSize, handleSize);
            });
        }

        ctx.restore();
    }

    function updateHandles(sel) {
        handles = [];
        const points = [
            { x: sel.x, y: sel.y }, // Top-left
            { x: sel.x + sel.width, y: sel.y }, // Top-right
            { x: sel.x, y: sel.y + sel.height }, // Bottom-left
            { x: sel.x + sel.width, y: sel.y + sel.height } // Bottom-right
        ];
        points.forEach((pt, idx) => {
            handles.push({
                x: pt.x * imgScale + imgPos.x,
                y: pt.y * imgScale + imgPos.y,
                pos: ['nw', 'ne', 'sw', 'se'][idx]
            });
        });
    }

    function getHandleUnderMouse(mouseX, mouseY) {
        return handles.find(handle => {
            return (
                mouseX >= handle.x - handleSize / 2 &&
                mouseX <= handle.x + handleSize / 2 &&
                mouseY >= handle.y - handleSize / 2 &&
                mouseY <= handle.y + handleSize / 2
            );
        })?.pos;
    }

    function adjustSelection(sel, handlePos, imgMouseX, imgMouseY) {
        switch (handlePos) {
            case 'nw':
                sel.width += sel.x - imgMouseX;
                sel.height += sel.y - imgMouseY;
                sel.x = imgMouseX;
                sel.y = imgMouseY;
                break;
            case 'ne':
                sel.width = imgMouseX - sel.x;
                sel.height += sel.y - imgMouseY;
                sel.y = imgMouseY;
                break;
            case 'sw':
                sel.width += sel.x - imgMouseX;
                sel.x = imgMouseX;
                sel.height = imgMouseY - sel.y;
                break;
            case 'se':
                sel.width = imgMouseX - sel.x;
                sel.height = imgMouseY - sel.y;
                break;
        }
    }

</script>

</body>
</html>

--------------------------
HTML Structure:
- A toolbar at the top with the "Import Image" button and the list of faces with their controls.
- A canvas inside a container that takes up the remaining space of the page. The canvas will display the image and handle user interactions.

- CSS Styles:
- Styles to ensure the canvas fills the available space and the toolbar and face list are properly aligned.
- Styles for the selection handles and labels to make them visible and interactive.

- JavaScript Functionality:
- Image Importing:
- When the user clicks "Import Image," it triggers a hidden file input to select an image.
- The selected image is loaded and displayed on the canvas.

- Zooming and Panning:
- The user can zoom in and out using the mouse wheel. The zoom focuses on the cursor position.
- Panning is done using the middle mouse button (button 1). Pressing it allows dragging the image around.

- Selection of Faces:
- Each face in the list (front, back, right, left, top, bottom) has associated buttons:
- Add: Allows the user to start drawing a selection rectangle for that face.
- Delete: Removes the selection rectangle for that face.
- Edit: Toggles edit mode, enabling handles for resizing and moving the selection.
- When adding a face, the user clicks and drags on the canvas to draw a rectangle. The rectangle sticks to the image and scales/moves with it.
- The selection rectangles are stored in the selections object, keyed by face name.

- Editing Selections:
- In edit mode, handles appear at the corners of the selection rectangle.
- The user can drag these handles to resize the rectangle.
- If the user clicks inside the rectangle but not on a handle, they can move the entire rectangle.

- Drawing Function (draw):
- Clears the canvas and redraws the image and all selection rectangles.
- Selection rectangles are drawn with red borders and have labels at their centers.

- Event Handlers:
- Mouse Events:
- mousedown, mousemove, and mouseup handle drawing, panning, and editing interactions.
- Wheel Event:
- wheel handles zooming in and out.
- Resize Event:
- Adjusts the canvas size when the window is resized.
-----------------------
- add Export .uv1 file button
after the user select all the faces that data need to be exported as .uv1 file to use later..
the .uv1 is text file that contain data for every face 

the .uv1 template is like so:
first line is the imported image size by pixel
the other 6 line tells the plasment of the selected faces, that we need to make formatted line so:
face_name,  rect_x_cordinate, rect_y_cordinate, rect_x_size, rect_y_size

for example the .uv1 file should be:
size,2000,2000
front,452.150,139.000,568.000,752.050
back,1034.550,161.080,252.500,572.010
right,286.401,165.099,205.010,426.010
left,338.502,263.720,156.009,355.401
top,470.011,310.420,631.100,599.507
bottom,218.000,652.104,597.670,196.208

- add load .uv1 file button
this button will delate current faces and replace them with the data from the .uv1 file the user just loaded