// ISO_RenameCompUsingLowestLayer.jsx
// Artist: https://www.jasonfletcher.info/
// Code generated by ChatGPT-5.5
// Date: June 11, 2026
// Description: This After Effects script will rename a comp based on the name of the lowest layer within said comp. If that layer is footage or an image sequence then the file extension, frame range, and trailing underscore will be removed from the name. This operation will be executed for the selected comps in the Project window.

(function () {
    app.beginUndoGroup("Rename Comps From Lowest Layer");

    try {
        var selection = app.project.selection;
        var selectedComps = [];
        var i;

        if (!selection || selection.length === 0) {
            alert("Please select one or more compositions in the Project panel.");
            return;
        }

        for (i = 0; i < selection.length; i++) {
            if (selection[i] instanceof CompItem) {
                selectedComps.push(selection[i]);
            }
        }

        if (selectedComps.length === 0) {
            alert("Please select one or more compositions in the Project panel.");
            return;
        }

        var renamedCount = 0;
        var skippedNoLayers = 0;
        var skippedAlreadyNamed = 0;

        function getCleanName(name) {
            var cleanName = name;

            // Remove extension
            cleanName = cleanName.replace(/\.[^\.]+$/, "");

            // Remove image sequence range suffixes like [0000-0250]
            cleanName = cleanName.replace(/\s*\[[0-9]+-[0-9]+\]$/, "");

            // Remove trailing underscore left behind by sequence imports
            cleanName = cleanName.replace(/[_\-\s]+$/, "");

            return cleanName;
        }

        for (i = 0; i < selectedComps.length; i++) {
            var comp = selectedComps[i];

            if (comp.numLayers < 1) {
                skippedNoLayers++;
                continue;
            }

            // Lowest layer in AE is the highest layer index
            var lowestLayer = comp.layer(comp.numLayers);

            if (lowestLayer === null || lowestLayer.source === null) {
                skippedNoLayers++;
                continue;
            }

            var newName = getCleanName(lowestLayer.source.name);

            if (newName === "") {
                skippedNoLayers++;
                continue;
            }

            if (comp.name === newName) {
                skippedAlreadyNamed++;
                continue;
            }

            comp.name = newName;
            renamedCount++;
        }

        alert(
            "Rename Complete\n\n" +
            "Selected Comps: " + selectedComps.length + "\n" +
            "Renamed: " + renamedCount + "\n" +
            "Skipped (No Valid Source): " + skippedNoLayers + "\n" +
            "Skipped (Already Named): " + skippedAlreadyNamed
        );

    } catch (err) {
        alert(
            "An error occurred:\n\n" +
            err.toString()
        );
    } finally {
        app.endUndoGroup();
    }
})();