{ Description: This script will migrate the existing ratings/color labels as written by
iView to XMP rating/color label

  Original Author: Hert van Zwietering
  Version history:

  v1.2 - 4 aug 2020
  Dedicated progress box and filename only in progress text

  v1.1 - 08 March 2019
  Fixed typo in the script's description

  v1.0 - 08 March 2019
  Initial release.
}

const
  cUpdateTags = 0;  // set to 1 to have metadata updated and EM/iView tag removed

function ConvertColorNumberToColorLabel(ANumber: Integer): WideString;
begin
  // iView uses 0..8
  if ANumber = 0 then  // none
    result := ''
  else if ANumber = 1 then  // yellow
    result := 'Yellow'  // PublicOptions.LabelYellowCaption
  else if ANumber = 2 then  // orange -> red
    result := 'Orange'
  else if ANumber = 3 then  // pink -> purple
    result := 'Pink'
  else if ANumber = 4 then  // purple
    result := 'Purple'  // PublicOptions.LabelPurpleCaption
  else if ANumber = 5 then  // blue
    result := 'Blue'  // PublicOptions.LabelBlueCaption
  else if ANumber = 6 then  // red
    result := 'Red'  // PublicOptions.LabelRedCaption
  else if ANumber = 7 then  // gray
    result := 'Gray'
  else if ANumber = 8 then  // green
    result := 'Green'  // PublicOptions.LabelGreenCaption
  else if ANumber = 9 then  // cyan
    result := 'Cyan'
  else
    result := '';
end;

procedure Process_iView (ACatItem: TCatalogItem; ATif: TTif; AXmp: TXMP);
var
  i: Integer;

  ARatingVal: WideString;
  AHasRatingVal: Boolean;

  AColorVal: WideString;
  AHasColorVal: Boolean;

  AColorLabel: WideString;

begin
  ARatingVal := '';
  AHasRatingVal := False;
  AColorVal  := '';
  AHasColorVal := False;

  for i := ATif.IPTCIFD.Tags.Count - 1 downto 0 do
  begin
    ATag := ATif.IPTCIFD.Tags.Items[i];

    if ATag.TagNumber = 10 then        // color label number is in Urgency field
    begin
      AHasColorVal := True;
      AColorVal := ATag.Value;
      ATag.Free;
    end
    else if ATag.TagNumber = 242 then        // rating number is in undocumented 242 field
    begin
      AHasRatingVal := True;
      ARatingVal := ATag.Value;
      ATag.Free;
    end;
  end;

  // convert rating to XMP
  if AHasRatingVal then
  begin
    if IsValidIntNumberString(ARatingVal, False, True) then
      AXmp.QuickSetProperty('http://ns.adobe.com/xap/1.0/', 'xmp:Rating', StrToInt(ARatingVal));
  end;

  if AHasColorVal then
  begin
    if IsValidIntNumberString(AColorVal, False, True) then
    begin
      //Say('map color number to string');
      AColorLabel := ConvertColorNumberToColorLabel(StrToInt(AColorVal));
      AXmp.QuickSetProperty('http://ns.adobe.com/xap/1.0/', 'xmp:Label', AColorLabel);
    end;
  end;
end;

var
  ATif: TTif;
  AXmp: TXMP;
  AItem: TImageItem;
  i: Integer;
  ACatItem: TCatalogItem;
  AProgress: TxomProgress;
begin
  if Selected.Count = 0 then
  begin
    Say ('No images selected');
    exit;
  end;

  if not Ask ('This script will migrate Ratings/ColorLabel entries as written with EM/iView to XMP.' + CrLf2 + 'Are you sure you want to continue?') then
    exit;

  AProgress := TxomProgress.Create(nil);
  try
    AProgress.Cancel := False;
    AProgress.Caption := 'Migrate EM-iView Ratings/Colors';
    AProgress.ProgressBar := True;
    AProgress.Max := Selected.Count;
    AProgress.Show;

    AXmp := TXmp.Create (True);
    ATif := TTif.Create (nil);
    try
      //ATif.UseCache := False;
      for i := 0 to Selected.Count - 1 do
      begin
        AProgress.ProgressText := Selected.Items[i].FileNameOnly;
        AProgress.Pos := i + 1;
        if AProgress.Cancel then
          break;

        ATif.Reset;
        AXmp.Reset;

        ATif.FileName := Selected.Items[i].ExifFileName;
        ATif.Load (True, False);

        ACatItem := TCatalogItem.Create (nil);
        try
          // now update the XMP
          if not PublicCatalog.FindImageCombined (Selected.Items[i], ACatItem, False, phtNone) then
          begin
            if not PublicCatalog.AddFile (Selected.Items[i], AcatItem, False) then
              Continue;
          end;

          PublicCatalog.LoadXMPForItem (ACatItem, AXmp, PublicOptions.CachedXMP);
          AXmp.InitializeFromTif (ATif, True, True, True, False, txusAll);

          Process_iView (ACatItem, ATif, AXmp);

          ACatItem.Rating := AXmp.QuickGetProperty('http://ns.adobe.com/xap/1.0/', 'xmp:Rating');
          ACatItem.ColorLabel := AXmp.QuickGetProperty('http://ns.adobe.com/xap/1.0/', 'xmp:Label');
          PublicCatalog.StoreItemToDatabase (ACatItem, False);

          if cUpdateTags <> 0 then
            ATif.UpdateTags;
          PublicCatalog.SaveXMPForItem (ACatItem, AXmp, PublicOptions.CachedXMP);
        finally
          ACatItem.Free;
        end
      end;
    finally
      AXmp.Free;
      ATif.Free;
    end;

    AProgress.Hide;

    if AProgress.Cancel then
      Say ('Cancelled');
  finally
    AProgress.Free;
  end;

end;

