{
  Author: IDimager Support
  Initial Date: 10 dec 2020
  Changes: Initial release
}

const
  cWithCounts = 1;  // 1=True; 0=False
  cSeparator = ';';
  cIndentString = #9;

  procedure AddToOutput(AOutput: TTntStringList; AIndent: WideString; AName: WideString; ACount: Integer);
  var
    ALine: WideString;
  begin
    ALine := AIndent + AName;

    if cWithCounts = 1 then
      ALine := ALine + WideString(cSeparator) + WideString(IntToStr(ACount));

    AOutput.Add(ALine);
  end;

  procedure AddProp(AProp: TCatalogItemProp; AOutput: TTntStringList; AIndent: WideString);
  var
    AProps: TCatalogItemProps;
    i: Integer;
  begin
    AddToOutput(AOutput, AIndent, AProp.PropName, AProp.PhotoCount);

    AProps := TCatalogItemProps.Create(TCatalogItemProp, '');
    try
      PublicCatalog.EnumPropsForParent(AProp.GUID, AProps, False, True);

      for i := 0 to AProps.Count - 1 do
      begin
        AddProp(AProps.Items[i], AOutput, AIndent + WideString(cIndentString));
      end;
    finally
      AProps.Free;
    end;
  end;

  procedure AddCategory(ACat: TCatalogPropCategory; AOutput: TidElement);
  var
    AProps: TCatalogItemProps;
    i: Integer;
  begin
    AddToOutput(AOutput, '', ACat.CategoryName, ACat.PhotoCount);

    AProps := TCatalogItemProps.Create(TCatalogItemProp, '');
    try
      PublicCatalog.EnumPropsForParent(ACat.GUID, AProps, False, True);

      for i := 0 to AProps.Count - 1 do
      begin
        AddProp(AProps.Items[i], AOutput, '');
      end;
    finally
      AProps.Free;
    end;
  end;

var
  ACats: TCatalogPropCategories;
  AOutput: TTntStringList;
  i: Integer;
  AOld: TCursor;
begin
  AOld := Screen.Cursor;
  Screen.Cursor := crHourglass;
  ACats := TCatalogPropCategories.Create(TCatalogPropCategory, '');
  AOutput := TTntStringList.Create;
  try
    PublicCatalog.EnumCategories(ACats, True);

    for i := 0 to ACats.Count - 1 do
    begin
      AddCategory(ACats.Items[i], AOutput);
    end;

    SaveDialog.Title := 'Save Catalog Structure As...';
    SaveDialog.Filter := 'Text Files (*.txt)|*.txt|All Files (*.*)|*.*';
    SaveDialog.DefaultExt := '.txt';
    SaveDialog.InitialDir := WindowsDesktopDir;
    SaveDialog.FileName := ReadFromRegistry('Scripts\DumpCatStruct', 'FileName', '');
    if SaveDialog.Execute then
    begin
      AOutput.SaveToFile(SaveDialog.FileName);
      WriteToRegistry('Scripts\DumpCatStruct', 'FileName', SaveDialog.FileName);
      Say2('Catalog Structure is saved.', SaveDialog.FileName);
    end;
  finally
    AOutput.Free;
    ACats.Free;
    Screen.Cursor := AOld;
  end;
end;
