#!/usr/bin/osascript -l JavaScript 
ObjC.import('Foundation'); /* allgemeine Klassen wie NSURL */
ObjC.import('Vision');  /* OCR */
ObjC.import('AppKit'); /* NSImage */
//ObjC.import('stdio'); /* Kommandozeilen-Argumente */

function textFromImage(image) { /* IMAGE! */
  const error = $();
  const languageCodes = ["de-DE", "en-US"];
  const recognizedLanguages = 
    languageCodes.map( lang => $(lang));
  
  const imageWidth = $.CGImageGetWidth(image);
  const imageHeight = $.CGImageGetHeight(image);
  /* Request: erzeugen und konfigurieren */
  const request = $.VNRecognizeTextRequest.alloc.init;
  request.setRecognitionLanguages($(recognizedLanguages));
  request.usesLanguageCorrection = true;
  const OCRresult = [];

  /* Request-Array für Handler */
  const reqArray = $([request]);
  
  /* Request-Handler erzeugen */
  const imageRequestHandler = 
    $.VNImageRequestHandler.alloc.initWithCGImageOptions(image, {});
  
  /* Texterkennung starten */
  const success = imageRequestHandler.performRequestsError(reqArray, error);
  if (success) {
    /* Erkannte Textfragmente häppchenweise in ein Array schreiben */
    const snippets = request.results.js;
    snippets.forEach(s => {
      OCRresult.push({
        "string":  s.topCandidates(1).js[0].string.js,
        "origin" : { x: s.bottomLeft.x * imageWidth, 
                     y: s.bottomLeft.y * imageHeight }, 
      })
    });
  } else {
    console.log($(error.localizedDescription).js)
  }
  return OCRresult;    
}

function OCRFile(dateiName) {
  const nil = $();
  /*
  URL zur Datei besorgen
  */
  const fileURL = $.NSURL.fileURLWithPath(dateiName);
  /*
   Bild aus Datei laden und an OCR-Funktion schicken.
  */
  const NSimage = $.NSImage.alloc.initWithContentsOfURL(fileURL);
  const image = NSimage.CGImageForProposedRectContextHints(nil, nil, nil);
  return textFromImage(image);
}

function comparePosition(a,b) {
  const diff = b.origin.y - a.origin.y;
  if (diff > -5 && diff < 5) {
    return a.origin.x - b.origin.x;
  } else {
    return diff;
  }
}

/* "text" in das extended attribute kMDItemKComment 
   der Datei "file" schreiben */
function addTextAsComment(text, file) {
  /* Einzelne Anführungszeichen für die Shell schützen */
  const escapedText = text.replaceAll(/'/g,"'\\''");
  const XMPList = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<string>${escapedText}</string>
</plist>`;
  const cmd = `xattr -w com.apple.metadata:kMDItemComment '${XMPList}' "${file}"`;
  const curApp =  Application.currentApplication();
  curApp.includeStandardAdditions = true;
  curApp.doShellScript(cmd);
}

(() => {
  var args = $.NSProcessInfo.processInfo.arguments;
  const filename = (() => {
    if (args.count == 5) {
       return args.js[4].js;
    } else {
       return './Hazel-Regel.png'
    }
  })()
//  const filename = './Hazel-Regel.png';
  const snippets = OCRFile(filename);
  const completeText = [];
  snippets.sort(comparePosition).forEach((s,index) => {
      console.log(`${index}: ${s.string}`)
      completeText.push(s.string);
  })
  /* completeText enthält die Textschnipsel in korrekter Reihenfolge.
     Durch Zeilenumbruch getrennt in "filename"-Kommentar schreiben
  */
  console.log(completeText.join('\n'))
  addTextAsComment(completeText.join('\n'), filename);
})()


