﻿#target indesign
#targetengine "bgLinkUI"

(function () {
    if ($.global.bgLinkUI && $.global.bgLinkUI instanceof Window) {
        try {
            $.global.bgLinkUI.show();
            $.global.bgLinkUI.active = true;
            return;
        } catch (e0) {}
    }

    function qq(s) {
        return '"' + String(s).replace(/\\/g, "\\\\").replace(/"/g, '\\"') + '"';
    }

    function pageItemFromLink(link) {
        try {
            return link.parent.parent;
        } catch (e) {
            return null;
        }
    }

    function isSupportedLink(link) {
        try {
            return /\.(jpg|jpeg|png|tif|tiff|psd|bmp)$/i.test(link.name);
        } catch (e) {
            return false;
        }
    }

    function labelFor(link) {
        var t = link.name;
        try {
            var it = pageItemFromLink(link);
            if (it && it.parentPage) t += " — Page " + it.parentPage.name;
        } catch (e) {}
        return t;
    }

    function photoshopAvailable() {
        try {
            return BridgeTalk.getSpecifier("photoshop") !== null;
        } catch (e) {
            return false;
        }
    }

    var w = new Window("palette", "Links: Remove Background");
    $.global.bgLinkUI = w;

    w.orientation = "column";
    w.alignChildren = "fill";
    w.spacing = 8;
    w.margins = 12;

    w.add("statictext", undefined, "Scan links, choose one, then select it or remove background + relink.");

    var lb = w.add("listbox", undefined, [], {multiselect:false});
    lb.preferredSize = [560, 280];

    var g = w.add("group");
    g.orientation = "row";

    var bScan   = g.add("button", undefined, "Scan Links");
    var bSelect = g.add("button", undefined, "Select Link");
    var bRun    = g.add("button", undefined, "Remove BG + Relink");

    var status = w.add("statictext", undefined, "Ready");
    status.characters = 75;

    w._links = [];

    function refreshLinks() {
        lb.removeAll();
        w._links = [];

        if (app.documents.length === 0) {
            status.text = "Open an InDesign document first.";
            return;
        }

        var doc = app.activeDocument;
        var i, ln;

        for (i = 0; i < doc.links.length; i++) {
            ln = doc.links[i];
            if (isSupportedLink(ln)) {
                w._links.push(ln);
                lb.add("item", labelFor(ln));
            }
        }

        if (w._links.length > 0) {
            lb.selection = 0;
            status.text = "Found " + w._links.length + " supported image links.";
        } else {
            status.text = "No supported raster links found.";
        }
    }

    function currentLink() {
        if (!lb.selection) return null;
        return w._links[lb.selection.index];
    }

    function selectChosenLink() {
        var link = currentLink();
        if (!link) {
            alert("Choose a link first.");
            return;
        }

        if (app.layoutWindows.length === 0) {
            alert("Open a document window first.");
            return;
        }

        try {
            var it = pageItemFromLink(link);
            if (!it || !it.isValid) {
                alert("Could not locate the page item for this link.");
                return;
            }

            try {
                if (it.parentPage) app.activeWindow.activePage = it.parentPage;
            } catch (e1) {}

            app.select(it);
            status.text = "Selected: " + link.name;
        } catch (e) {
            alert("Could not select that link:\r" + e);
        }
    }

    function runRemoveBackground() {
        var link = currentLink();
        if (!link) {
            alert("Choose a link first.");
            return;
        }

        if (!photoshopAvailable()) {
            alert("Photoshop is not available to BridgeTalk.");
            return;
        }

        var src;
        try {
            src = File(link.filePath);
        } catch (e0) {
            alert("Could not read the link file path.");
            return;
        }

        if (!src || !src.exists) {
            alert("Link file not found:\r" + (src ? src.fsName : "[unknown]"));
            return;
        }

        var base = src.name.replace(/\.[^\.]+$/, "");
        var out = File(src.path + "/" + base + "_nobg.psd");

        status.text = "Sending to Photoshop...";

        var ps = [];
        ps.push("app.displayDialogs = DialogModes.NO;");
        ps.push("var inFile = File(" + qq(src.fsName) + ");");
        ps.push("var outFile = File(" + qq(out.fsName) + ");");
        ps.push("if (!inFile.exists) throw new Error('Input file missing: ' + inFile.fsName);");
        ps.push("var doc = app.open(inFile);");
        ps.push("try { if (doc.activeLayer.isBackgroundLayer) doc.activeLayer.isBackgroundLayer = false; } catch(e) {}");

        // Try Remove Background first, then Select Subject fallback
        ps.push("var ok = false;");
        ps.push("try { executeAction(stringIDToTypeID('autoCutout'), new ActionDescriptor(), DialogModes.NO); ok = true; } catch(e1) {}");
        ps.push("if (!ok) { try { executeAction(stringIDToTypeID('selectSubject'), new ActionDescriptor(), DialogModes.NO); ok = true; } catch(e2) {} }");
        ps.push("if (!ok) throw new Error('Remove Background / Select Subject is unavailable in Photoshop.');");

        // Make layer mask from selection
        ps.push("var d = new ActionDescriptor();");
        ps.push("d.putClass(charIDToTypeID('Nw  '), charIDToTypeID('Chnl'));");
        ps.push("var r = new ActionReference();");
        ps.push("r.putEnumerated(charIDToTypeID('Chnl'), charIDToTypeID('Chnl'), charIDToTypeID('Msk '));");
        ps.push("d.putReference(charIDToTypeID('At  '), r);");
        ps.push("d.putEnumerated(charIDToTypeID('Usng'), charIDToTypeID('UsrM'), charIDToTypeID('RvlS'));");
        ps.push("executeAction(charIDToTypeID('Mk  '), d, DialogModes.NO);");

        ps.push("try { doc.trim(TrimType.TRANSPARENT, true, true, true, true); } catch(e3) {}");

        ps.push("var o = new PhotoshopSaveOptions();");
        ps.push("o.layers = true;");
        ps.push("o.embedColorProfile = true;");
        ps.push("doc.saveAs(outFile, o, true, Extension.LOWERCASE);");
        ps.push("doc.close(SaveOptions.DONOTSAVECHANGES);");
        ps.push("outFile.fsName.toSource();");

        var bt = new BridgeTalk();
        bt.target = "photoshop";
        bt.body = ps.join("\n");

        bt.onResult = function (res) {
            try {
                var newPath = eval(res.body);
                var f = File(newPath);

                if (!f.exists) {
                    alert("PSD was not created.");
                    status.text = "PSD missing.";
                    return;
                }

                link.relink(f);
                try { link.update(); } catch (e4) {}

                status.text = "Done: " + f.name;
                refreshLinks();
            } catch (e5) {
                alert("Photoshop finished, but relink failed:\r" + e5);
                status.text = "Relink failed.";
            }
        };

        bt.onError = function (err) {
            alert("BridgeTalk / Photoshop error:\r" + err.body);
            status.text = "Photoshop error.";
        };

        bt.send();
    }

    bScan.onClick = refreshLinks;
    bSelect.onClick = selectChosenLink;
    bRun.onClick = runRemoveBackground;

    w.onShow = function () {
        refreshLinks();
    };

    w.center();
    w.show();
})();