// bridge.jsx \u2014\u2014 AI\u7ed8\u5320 CEP \u9762\u677f\u7684 ExtendScript \u6865\uff08\u517c\u5bb9 PS CC2015.5 ~ 2021\uff09
// \u9762\u677f\u901a\u8fc7 evalScript \u8c03\u7528\u8fd9\u91cc\u7684\u51fd\u6570\uff1b\u6240\u6709\u8fd4\u56de\u90fd\u662f\u5b57\u7b26\u4e32\uff08ERR: \u524d\u7f00\u8868\u793a\u5931\u8d25\uff09

/* ExtendScript \u4e0d\u4fdd\u8bc1\u63d0\u4f9b\u539f\u751f JSON\uff1b\u6865\u63a5\u8fd4\u56de\u503c\u81ea\u884c\u5e8f\u5217\u5316\u3002 */
function hjJsonQuote(value) {
  return '"' + String(value).replace(/\\/g, "\\\\").replace(/"/g, '\\"')
    .replace(/\r/g, "\\r").replace(/\n/g, "\\n") + '"';
}

function hjJsonNumberArray(values) {
  var out = [];
  for (var i = 0; i < values.length; i++) out.push(Number(values[i]));
  return "[" + out.join(",") + "]";
}

function hjVersionInfo() {
  try {
    return '{"version":' + hjJsonQuote(app.version) + ',"docs":' + app.documents.length + '}';
  } catch (e) {
    return "ERR:" + e.toString();
  }
}

/* \u5f53\u524d\u9009\u533a bounds\uff08px\uff09\uff0c\u65e0\u9009\u533a\u8fd4\u56de ERR:none */
function hjSelectionBounds() {
  try {
    var sb = app.activeDocument.selection.bounds;
    return hjJsonNumberArray([sb[0].as("px"), sb[1].as("px"), sb[2].as("px"), sb[3].as("px")]);
  } catch (e) {
    return "ERR:none";
  }
}

/* \u6293\u53d6\u56fe\u50cf\uff1amode = layer | selection | document
   \u5b9e\u73b0\uff1a\u590d\u5236\u6587\u6863 \u2192 \u53ea\u4fdd\u7559\u76ee\u6807\u56fe\u5c42\u53ef\u89c1 \u2192 \u88c1\u526a \u2192 \u53e6\u5b58 PNG \u5230\u4e34\u65f6\u76ee\u5f55 \u2192 \u5173\u95ed\u526f\u672c */
function hjCapture(mode) {
  var dup = null;
  try {
    if (app.documents.length === 0) return "ERR:\u8bf7\u5148\u6253\u5f00\u4e00\u4e2a\u6587\u6863";
    var doc = app.activeDocument;
    if (doc.activeLayer == null) return "ERR:\u8bf7\u9009\u4e2d\u4e00\u4e2a\u56fe\u5c42";

    var selBounds = null;
    if (mode == "selection") {
      try {
        var sb = doc.selection.bounds;
        selBounds = [sb[0].as("px"), sb[1].as("px"), sb[2].as("px"), sb[3].as("px")];
      } catch (e) { selBounds = null; }
    }

    dup = doc.duplicate("hj_capture_tmp", false);
    app.activeDocument = dup;
    var target = dup.activeLayer;

    // \u9690\u85cf\u6240\u6709\u9876\u5c42\u975e\u7956\u5148\u56fe\u5c42\uff08\u76ee\u6807\u56fe\u5c42\u7684\u7236\u7ea7\u7ec4\u4fdd\u6301\u53ef\u89c1\uff09
    hjHideOthers(dup, target);

    if (selBounds) {
      dup.crop(selBounds);
    } else if (mode == "layer") {
      try { dup.trim(TrimType.TRANSPARENT); } catch (e) {}
    }

    // PNG \u8f93\u51fa\u7edf\u4e00\u8f6c\u4e3a RGB 8 \u4f4d\uff0c\u517c\u5bb9 CMYK / 16 \u4f4d\u539f\u7a3f\u3002
    try { if (dup.mode != DocumentMode.RGB) dup.changeMode(ChangeMode.RGB); } catch (e) {}
    try { dup.bitsPerChannel = BitsPerChannelType.EIGHT; } catch (e) {}
    var outW = dup.width.as("px"), outH = dup.height.as("px");
    var f = new File(Folder.temp.fsName + "/hj_" + new Date().getTime() + ".png");
    var opts = new PNGSaveOptions();
    dup.saveAs(f, opts, true, Extension.LOWERCASE);
    dup.close(SaveOptions.DONOTSAVECHANGES);
    dup = null;
    return '{"path":' + hjJsonQuote(f.fsName) + ',"bounds":' +
      (selBounds ? hjJsonNumberArray(selBounds) : "null") + ',"width":' + Number(outW) +
      ',"height":' + Number(outH) + '}';
  } catch (e) {
    if (dup) { try { dup.close(SaveOptions.DONOTSAVECHANGES); } catch (e2) {} }
    return "ERR:" + e.toString();
  }
}

function hjIsAncestor(maybe, layer) {
  var p = layer.parent;
  while (p && p.typename == "LayerSet") {
    if (p == maybe) return true;
    p = p.parent;
  }
  return false;
}

function hjHideOthers(doc, target) {
  for (var i = 0; i < doc.layers.length; i++) {
    var L = doc.layers[i];
    if (L == target || hjIsAncestor(L, target)) continue;
    try { L.visible = false; } catch (e) {}
  }
}

/* \u63d2\u5165\u751f\u6210\u56fe\uff1a\u65e0\u6587\u6863\u65f6\u76f4\u63a5\u6253\u5f00\u4e3a\u65b0\u6587\u6863\uff1b\u6709\u6587\u6863\u65f6 place \u4e3a\u65b0\u56fe\u5c42\u3002
   boundsJson\uff08\u53ef\u9009\uff09= {"left":l,"top":t,"right":r,"bottom":b}\uff08px\uff09
   \u2014\u2014 \u7b49\u6bd4\u94fa\u6ee1 bounds\u3001\u5c45\u4e2d\u5e76\u521b\u5efa\u9009\u533a\u8499\u7248\uff08\u9009\u533a\u5916\u4e0d\u53ef\u89c1\uff09 */
function hjInsert(path, boundsJson) {
  try {
    var f = new File(path);
    if (!f.exists) return "ERR:\u6587\u4ef6\u4e0d\u5b58\u5728";
    if (app.documents.length === 0) {
      var d = app.open(f);
      if (d) return "OK:opened";
      return "ERR:\u6253\u5f00\u56fe\u7247\u5931\u8d25";
    }
    var placeDesc = new ActionDescriptor();
    placeDesc.putPath(charIDToTypeID("null"), f);
    placeDesc.putEnumerated(charIDToTypeID("FTcs"), charIDToTypeID("QCSt"), charIDToTypeID("Qcsa"));
    executeAction(charIDToTypeID("Plc "), placeDesc, DialogModes.NO);

    if (boundsJson) {
      try {
        var b = eval("(" + boundsJson + ")");
        var tw = b.right - b.left, th = b.bottom - b.top;
        var L = app.activeDocument.activeLayer;
        var lb = L.bounds;
        var w = lb[2].as("px") - lb[0].as("px");
        var h = lb[3].as("px") - lb[1].as("px");
        if (w > 0 && h > 0 && tw > 0 && th > 0) {
          var scale = Math.max(tw / w, th / h) * 100;
          L.resize(scale, scale, AnchorPosition.MIDDLECENTER);
          lb = L.bounds;
          w = lb[2].as("px") - lb[0].as("px");
          h = lb[3].as("px") - lb[1].as("px");
          var cx = (lb[0].as("px") + lb[2].as("px")) / 2;
          var cy = (lb[1].as("px") + lb[3].as("px")) / 2;
          var dx = (b.left + b.right) / 2 - cx;
          var dy = (b.top + b.bottom) / 2 - cy;
          if (Math.abs(dx) > 0.5 || Math.abs(dy) > 0.5) L.translate(dx, dy);
          hjMaskToBounds(b);
        }
      } catch (e) { return "ERR:\u8d34\u56de\u9009\u533a\u5931\u8d25\uff1a" + e.toString(); }
    }
    return "OK";
  } catch (e) {
    return "ERR:" + e.toString();
  }
}

function hjMaskToBounds(b) {
  var doc = app.activeDocument;
  doc.selection.select([[b.left,b.top],[b.right,b.top],[b.right,b.bottom],[b.left,b.bottom]]);
  var d = new ActionDescriptor();
  d.putClass(charIDToTypeID("Nw  "), charIDToTypeID("Chnl"));
  var r = new ActionReference();
  r.putEnumerated(charIDToTypeID("Chnl"), charIDToTypeID("Chnl"), charIDToTypeID("Msk "));
  d.putReference(charIDToTypeID("At  "), r);
  d.putEnumerated(charIDToTypeID("Usng"), charIDToTypeID("UsrM"), charIDToTypeID("RvlS"));
  executeAction(charIDToTypeID("Mk  "), d, DialogModes.NO);
}
