
/////////////////////////////////////////////////////////////////
// Custom Swatch Information Script for Illustrator
// Copyright SebVTL
// Supports Pantone, RGB, CMYK, HSL, and Hex values.
// Handles Global Colors and renames temporary layers to "info-couleurs".
// Generates text with color details inside selected shapes.
// Adapts text color for strong contrast with background.
// Creates temporary layer directly above the selected shape's layer.
// Adds dynamic padding for text based on the size of the selected shape.
/////////////////////////////////////////////////////////////////

var doc = app.activeDocument;

if (doc.selection.length > 0) {
    for (var i = 0; i < doc.selection.length; i++) {
        var selectedItem = doc.selection[i];
        if (selectedItem.typename !== "PathItem") continue;

        var fillColor = selectedItem.fillColor;
        var activeLayer = selectedItem.layer;

        // Unlock the active layer if locked
        if (activeLayer.locked) activeLayer.locked = false;

        // Ensure a temporary layer is created above the active layer
        var tempLayer = getOrCreateLayerAbove("info-couleurs", activeLayer);

        // Extract color details
        var colorDetails = getColorDetails(fillColor);
        if (!colorDetails) continue;

        // Create text frame with color information
        createTextFrameWithPadding(selectedItem, colorDetails, tempLayer);
    }
}

// Function to create or get a layer directly above the specified layer
function getOrCreateLayerAbove(layerName, referenceLayer) {
    var newLayer = null;

    // Check if a layer with the specified name already exists above the reference layer
    for (var j = 0; j < doc.layers.length; j++) {
        if (doc.layers[j].name === layerName && doc.layers[j].zOrderPosition > referenceLayer.zOrderPosition) {
            return doc.layers[j]; // Return the existing layer
        }
    }

    // Create a new layer and move it above the reference layer
    newLayer = doc.layers.add();
    newLayer.name = layerName;
    newLayer.move(referenceLayer, ElementPlacement.PLACEBEFORE);
    return newLayer;
}

// Function to extract color details
function getColorDetails(color) {
    var details = {
        pantone: "N/A",
        rgb: { red: 0, green: 0, blue: 0 },
        cmyk: { cyan: 0, magenta: 0, yellow: 0, black: 0 },
        hsl: "H:0 S:0 L:0",
        hex: "#000000"
    };

    if (color.typename === "SpotColor" || color.typename === "GlobalColor") {
        details.pantone = color.spot ? color.spot.name || "N/A" : "N/A";
        if (color.spot && color.spot.color.rgb) {
            details.rgb = color.spot.color.rgb;
            details.hex = rgbToHex(details.rgb.red, details.rgb.green, details.rgb.blue);
        }
        if (color.spot && color.spot.color.cmyk) details.cmyk = color.spot.color.cmyk;
        if (color.spot && color.spot.color.hue !== undefined) {
            details.hsl = "H:" + Math.round(color.spot.color.hue || 0) +
                          " S:" + Math.round(color.spot.color.saturation || 0) +
                          " L:" + Math.round(color.spot.color.lightness || 0);
        }
    } else if (color.typename === "RGBColor") {
        details.rgb = color;
        details.cmyk = convertToCMYK(color);
        details.hsl = convertToHSL(color);
        details.hex = rgbToHex(color.red, color.green, color.blue);
    } else if (color.typename === "CMYKColor") {
        details.cmyk = color;
        details.rgb = convertToRGB(color);
        details.hsl = convertToHSL(details.rgb);
        details.hex = rgbToHex(details.rgb.red, details.rgb.green, details.rgb.blue);
    } else {
        return null;
    }

    return details;
}

// Function to create a text frame with dynamic padding
function createTextFrameWithPadding(item, colorDetails, targetLayer) {
    var content = "Pantone: " + colorDetails.pantone + "\n" +
                  "RVB: " + Math.round(colorDetails.rgb.red) + ", " + Math.round(colorDetails.rgb.green) + ", " + Math.round(colorDetails.rgb.blue) + "\n" +
                  "CMJN: " + Math.round(colorDetails.cmyk.cyan) + "%, " + Math.round(colorDetails.cmyk.magenta) + "%, " + Math.round(colorDetails.cmyk.yellow) + "%, " + Math.round(colorDetails.cmyk.black) + "%\n" +
                  "TLS: " + colorDetails.hsl + "\n" +
                  "Hex: " + colorDetails.hex;

    // Calculate dynamic padding based on the item's dimensions
    var paddingX = item.width * 0.1;  // 10% of the item's width
    var paddingY = item.height * 0.1; // 10% of the item's height

    
    // Définir explicitement le calque temporaire comme calque actif
    app.activeDocument.activeLayer = targetLayer;
    if (targetLayer.locked) targetLayer.locked = false;
    if (!targetLayer.visible) targetLayer.visible = true;

    var textFrame = doc.textFrames.add();
    
    textFrame.contents = content;
    textFrame.position = [item.left + paddingX, item.top - paddingY];

    var textColor = new RGBColor();
    if (isDarkColor(colorDetails.rgb)) {
        textColor.red = 255;
        textColor.green = 255;
        textColor.blue = 255;
    } else {
        textColor.red = 0;
        textColor.green = 0;
        textColor.blue = 0;
    }
    textFrame.textRange.fillColor = textColor;

    // Move the text frame to the target layer
    textFrame.move(targetLayer, ElementPlacement.PLACEATBEGINNING);
}

// Utility functions
function rgbToHex(r, g, b) {
    function componentToHex(c) {
        var hex = Math.round(c).toString(16);
        return hex.length === 1 ? "0" + hex : hex;
    }
    return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
}

function convertToRGB(cmyk) {
    return {
        red: (1 - cmyk.cyan / 100) * (1 - cmyk.black / 100) * 255,
        green: (1 - cmyk.magenta / 100) * (1 - cmyk.black / 100) * 255,
        blue: (1 - cmyk.yellow / 100) * (1 - cmyk.black / 100) * 255
    };
}

function convertToCMYK(rgb) {
    var r = rgb.red / 255, g = rgb.green / 255, b = rgb.blue / 255;
    var k = 1 - Math.max(r, g, b);
    if (k === 1) return { cyan: 0, magenta: 0, yellow: 0, black: 100 };
    return {
        cyan: ((1 - r - k) / (1 - k)) * 100 || 0,
        magenta: ((1 - g - k) / (1 - k)) * 100 || 0,
        yellow: ((1 - b - k) / (1 - k)) * 100 || 0,
        black: k * 100
    };
}

function convertToHSL(rgb) {
    var r = rgb.red / 255, g = rgb.green / 255, b = rgb.blue / 255;
    var max = Math.max(r, g, b), min = Math.min(r, g, b);
    var h, s, l = (max + min) / 2;

    if (max == min) {
        h = s = 0;
    } else {
        var d = max - min;
        s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
        switch (max) {
            case r: h = (g - b) / d + (g < b ? 6 : 0); break;
            case g: h = (b - r) / d + 2; break;
            case b: h = (r - g) / d + 4; break;
        }
        h /= 6;
    }
    return "H:" + Math.round(h * 360) + " S:" + Math.round(s * 100) + " L:" + Math.round(l * 100);
}

function isDarkColor(color) {
    return (color.red * 0.299 + color.green * 0.587 + color.blue * 0.114) < 128;
}
