{
    Author: Hert van Zwietering
    Initial Date: 3 may 2020

    Version history:
        1.01
            5 may 2020
            Fix for quoted strings
        1.0
            3 may 2020
            initial version
}

  function WideQuotedStr(AStr: WideString): WideString;
  begin
    result := UTF8Decode(QuotedStr(UTF8Encode(AStr)));
  end;

  function FileNameExistsInCatalog(AFileName: WideString): Boolean;
  var
    ADs: TDBXOMClientDataset;
  begin
    result := False;
    ADs := PublicCatalog.NewDataset;
    try
      ADs.CommandText := 'select GUID from idCatalogItem  where FileName = ' + WideQuotedStr(AFileName) + ' ' + iif(IsSQLite, 'collate nocase', '') + ' ' +
                         'union all ' +
                         'select GUID from idImageVersion where FileName = ' + WideQuotedStr(AFileName) + ' ' + iif(IsSQLite, 'collate nocase', '') + ' ' +
                         '';
      ADs.OpenSet;
      try
        result := ADs.RecordsInSet > 0;
      finally
        ADs.CloseSet;
      end;
    finally
      PublicCatalog.FreeDataSet(ADs);
    end;
  end;

  procedure HandleDir(ADir: WideString);
  var
    AResult, AFiles: TTntStringList;
    i: Integer;
    AItem: TCatalogItem;
    AProgress: TxomProgress;
  begin
    AProgress := TxomProgress.Create(nil);
    try
      AResult := TTntStringList.Create;
      AFiles := TTntStringList.Create;
      try
        SearchFiles(ADir, SupportedExtensions.CommaText, 0, AFiles, True, -1, nil);

        AProgress.Caption := 'Scanning folder for missing files';
        AProgress.Cancel := False;
        AProgress.ProgressBar := True;
        AProgress.Max := AFiles.Count;
        AProgress.Show;

        for i := 0 to AFiles.Count - 1 do
        begin
          AProgress.ProgressText := WideExtractFileName(AFiles.Strings[i]);
          AProgress.Pos := i + 1;

          AItem := TCatalogItem.Create(nil);
          try
            if not FileNameExistsInCatalog(WideExtractFileName(AFiles.Strings[i])) then
              AResult.Add(AFiles.Strings[i]);
          finally
            AItem.Free;
          end;
        end;

        AProgress.Hide;

        if AResult.Count = 0 then
          Say('No missing files.')
        else
          Say(AResult.Text);
      finally
        AFiles.Free;
        AResult.Free;
      end;
    finally
      AProgress.Free;
    end;
  end;

var
  i: Integer;
  AProgress: TxomProgress;
  ADir: WideString;
begin
  ADlg := TxomSelectDirectoryDialog.Create(nil);
  try
    ADlg.Title := 'Select the folder to scan for missing files...';
    if not ADlg.Execute then
      exit;
    ADir := ADlg.FileName;
  finally
    ADlg.Free;
  end;

  HandleDir(ADir)
end;

