unit Azure.CognitiveServices.FaceDetection.JSON;

interface

uses
  System.Generics.Collections, System.JSON, System.SysUtils,
  Azure.CognitiveServices.FaceDetection.Types;

type

  TAcsFaceDetectJSON = class
  private
    class function ToRecognitionModelEnum(const AIdent: string): TAcsFaceRecognitionModel;
  public
    class procedure Parse(AValue: TJSONValue; out AData: TAcsFaceMaskAttribute); overload;
    class procedure Parse(AValue: TJSONValue; out AData: TAcsFaceGlassesAttribute); overload;
    class procedure Parse(AValue: TJSONValue; out AData: TAcsFaceAgeAttribute); overload;
    class procedure Parse(AValue: TJSONValue; out AData: TAcsFaceRecognitionAttribute); overload;
    class procedure Parse(AValue: TJSONValue; out AData: TAcsFaceHairAttribute); overload;
    class procedure Parse(AValue: TJSONValue; out AData: TAcsFaceHairColor); overload;
    class procedure Parse(AValue: TJSONValue; out AData: TAcsFaceAccessory); overload;
    class procedure Parse(AValue: TJSONArray; out AData: TAcsFaceAccessories); overload;
    class procedure Parse(AValue: TJSONValue; out AData: TAcsFaceOcclusionAttribute); overload;
    class procedure Parse(AValue: TJSONValue; out AData: TAcsFaceMakeupAttribute); overload;
    class procedure Parse(AValue: TJSONValue; out AData: TAcsFaceNoiseAttribute); overload;
    class procedure Parse(AValue: TJSONValue; out AData: TAcsFaceExposureAttribute); overload;
    class procedure Parse(AValue: TJSONValue; out AData: TAcsFaceBlurAttribute); overload;
    class procedure Parse(AValue: TJSONValue; out AData: TAcsFaceEmotionAttribute); overload;
    class procedure Parse(AValue: TJSONValue; out AData: TAcsFaceGenderAttribute); overload;
    class procedure Parse(AValue: TJSONValue; out AData: TAcsFaceFacialHairAttribute); overload;
    class procedure Parse(AValue: TJSONValue; out AData: TAcsFaceHeadPoseAttribute); overload;
    class procedure Parse(AValue: TJSONValue; out AData: TAcsFaceSmileAttribute); overload;
    class procedure Parse(AValue: TJSONValue; out AData: TAcsFaceAttributes); overload;
    class procedure Parse(AValue: TJSONValue; out AData: TAcsFaceLandmark); overload;
    class procedure Parse(AValue: TJSONValue; out AData: TAcsFaceLandmarks); overload;
    class procedure Parse(AValue: TJSONValue; out AData: TAcsFaceRectangle); overload;
    class procedure Parse(AValue: TJSONValue; out AData: TAcsFaceDetectResponse); overload;
    class procedure Parse(AValue: TJSONValue; out AData: TAcsFaceDetectResult); overload;
  end;

implementation

uses
  System.Rtti, Azure.CognitiveServices.ResourceStrings;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONValue;
  out AData: TAcsFaceDetectResponse);
var
  LFaceArray: TJSONArray;
  LIndex: Integer;
begin
  LFaceArray := TJSONArray(AValue);
  SetLength(AData.Faces, LFaceArray.Count);
  for LIndex := 0 to LFaceArray.Count - 1 do
    Parse(LFaceArray[LIndex], AData.Faces[LIndex]);
end;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONValue;
  out AData: TAcsFaceDetectResult);
begin
  AData.FaceId := AValue.GetValue<string>('faceId');
  Parse(AValue.GetValue<TJSONObject>('faceRectangle'), AData.FaceRectangle);
  Parse(AValue.GetValue<TJSONObject>('faceLandmarks'), AData.FaceLandmarks);
  Parse(AValue.GetValue<TJSONObject>('faceAttributes'), AData.FaceAttributes);
  Parse(AValue.GetValue<TJSONValue>('recognitionModel'),
    AData.RecognitionAttribute);
end;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONArray;
  out AData: TAcsFaceAccessories);
var
  LIndex: Integer;
begin
  SetLength(AData, AValue.Count);
  for LIndex := 0 to AValue.Count - 1 do
    Parse(AValue[LIndex], AData[LIndex]);
end;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONValue;
  out AData: TAcsFaceMaskAttribute);
begin
  if AValue = nil then
  begin
    AData.Available := False;
    Exit;
  end;
  AData.MaskType := AValue.GetValue<TAcsFaceMaskType>('type');
  AData.NoseAndMouthCovered := AValue.GetValue<Boolean>('noseAndMouthCovered');
  AData.Available := True;
end;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONValue;
  out AData: TAcsFaceGlassesAttribute);
begin
  if AValue = nil then
  begin
    AData.Available := False;
    Exit;
  end;
  AData.Glasses := AValue.AsType<TAcsFaceGlassesType>();
  AData.Available := True;
end;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONValue;
  out AData: TAcsFaceAgeAttribute);
begin
  if AValue = nil then
  begin
    AData.Available := False;
    Exit;
  end;
  AData.Age := AValue.AsType<Double>();
  AData.Available := True;
end;

class function TAcsFaceDetectJSON.ToRecognitionModelEnum
  (const AIdent: string): TAcsFaceRecognitionModel;
const
FaceRecognitionModelIdents: array [TAcsFaceRecognitionModel]
  of string = ('recognition_01', 'recognition_02', 'recognition_03',
  'recognition_04');
var
  LEnum: TAcsFaceRecognitionModel;
begin
  for LEnum := Low(TAcsFaceRecognitionModel) to High(TAcsFaceRecognitionModel) do
    if FaceRecognitionModelIdents[LEnum] = AIdent then
    begin
      Result := LEnum;
      Exit;
    end;
  raise EArgumentException.Create(StrErrRecognitionModelInvalid);
end;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONValue;
  out AData: TAcsFaceRecognitionAttribute);
begin
  if AValue = nil then
  begin
    AData.Available := False;
    Exit;
  end;
  AData.RecognitionModel := ToRecognitionModelEnum(AValue.AsType<string>());
  AData.Available := True;
end;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONValue;
  out AData: TAcsFaceHairAttribute);
var
  LHairColors: TJSONArray;
  LIndex: Integer;
begin
  if AValue = nil then
  begin
    AData.Available := False;
    Exit;
  end;
  AData.Bald := AValue.GetValue<Double>('bald');
  AData.Invisible := AValue.GetValue<Boolean>('invisible');
  LHairColors := AValue.GetValue<TJSONArray>('hairColor');
  SetLength(AData.HairColors, LHairColors.Count);
  for LIndex := 0 to LHairColors.Count - 1 do
    Parse(LHairColors[LIndex], AData.HairColors[LIndex]);
  AData.Available := True;
end;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONValue;
  out AData: TAcsFaceHairColor);
begin
  if AValue = nil then
  begin
    AData.Available := False;
    Exit;
  end;
  AData.Color := AValue.GetValue<string>('color');
  AData.Confidence := AValue.GetValue<Double>('confidence');
  AData.Available := True;
end;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONValue;
  out AData: TAcsFaceAccessory);
begin
  if AValue = nil then
  begin
    AData.Available := False;
    Exit;
  end;
  AData.AccessoryType := AValue.GetValue<string>('type');
  AData.Confidence := AValue.GetValue<Double>('confidence');
  AData.Available := True;
end;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONValue;
  out AData: TAcsFaceOcclusionAttribute);
begin
  if AValue = nil then
  begin
    AData.Available := False;
    Exit;
  end;
  AData.ForeheadOccluded := AValue.GetValue<Boolean>('foreheadOccluded');
  AData.EyeOccluded := AValue.GetValue<Boolean>('eyeOccluded');
  AData.MouthOccluded := AValue.GetValue<Boolean>('mouthOccluded');
  AData.Available := True;
end;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONValue;
  out AData: TAcsFaceMakeupAttribute);
begin
  if AValue = nil then
  begin
    AData.Available := False;
    Exit;
  end;
  AData.EyeMakeup := AValue.GetValue<Boolean>('eyeMakeup');
  AData.LipMakeup := AValue.GetValue<Boolean>('lipMakeup');
  AData.Available := True;
end;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONValue;
  out AData: TAcsFaceNoiseAttribute);
begin
  if AValue = nil then
  begin
    AData.Available := False;
    Exit;
  end;
  AData.NoiseLevel := AValue.GetValue<TAcsFaceNoiseLevel>('noiseLevel');
  AData.Value := AValue.GetValue<Double>('value');
  AData.Available := True;
end;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONValue;
  out AData: TAcsFaceExposureAttribute);
begin
  if AValue = nil then
  begin
    AData.Available := False;
    Exit;
  end;
  AData.ExposureLevel := AValue.GetValue<TAcsFaceExposureLevel>
    ('exposureLevel');
  AData.Value := AValue.GetValue<Double>('value');
  AData.Available := True;
end;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONValue;
  out AData: TAcsFaceBlurAttribute);
begin
  if AValue = nil then
  begin
    AData.Available := False;
    Exit;
  end;
  AData.BlurLevel := AValue.GetValue<TAcsFaceBlurLevel>('blurLevel');
  AData.Value := AValue.GetValue<Double>('value');
  AData.Available := True;
end;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONValue;
  out AData: TAcsFaceEmotionAttribute);
begin
  if AValue = nil then
  begin
    AData.Available := False;
    Exit;
  end;
  AData.Anger := AValue.GetValue<Double>('anger');
  AData.Contempt := AValue.GetValue<Double>('contempt');
  AData.Disgust := AValue.GetValue<Double>('disgust');
  AData.Fear := AValue.GetValue<Double>('fear');
  AData.Happiness := AValue.GetValue<Double>('happiness');
  AData.Neutral := AValue.GetValue<Double>('neutral');
  AData.Sadness := AValue.GetValue<Double>('sadness');
  AData.Surprise := AValue.GetValue<Double>('surprise');
  AData.Available := True;
end;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONValue;
  out AData: TAcsFaceGenderAttribute);
begin
  if AValue = nil then
  begin
    AData.Available := False;
    Exit;
  end;
  AData.Gender := AValue.AsType<TAcsFaceGenderType>();
  AData.Available := True;
end;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONValue;
  out AData: TAcsFaceFacialHairAttribute);
begin
  if AValue = nil then
  begin
    AData.Available := False;
    Exit;
  end;
  AData.Moustache := AValue.GetValue<Double>('moustache');
  AData.Beard := AValue.GetValue<Double>('beard');
  AData.Sideburns := AValue.GetValue<Double>('sideburns');
  AData.Available := True;
end;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONValue;
  out AData: TAcsFaceHeadPoseAttribute);
begin
  if AValue = nil then
  begin
    AData.Available := False;
    Exit;
  end;
  AData.Pitch := AValue.GetValue<Double>('pitch');
  AData.Roll := AValue.GetValue<Double>('roll');
  AData.Yaw := AValue.GetValue<Double>('yaw');
  AData.Available := True;
end;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONValue;
  out AData: TAcsFaceSmileAttribute);
begin
  if AValue = nil then
  begin
    AData.Available := False;
    Exit;
  end;
  AData.Smile := AValue.AsType<Double>();
  AData.Available := True;
end;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONValue;
  out AData: TAcsFaceAttributes);
var
  LValue: TJSONValue;
  LArray: TJSONArray;
begin
  if AValue = nil then
  begin
    AData.Available := False;
    Exit;
  end;
  if AValue.TryGetValue<TJSONValue>('smile', LValue) then
    Parse(LValue, AData.Smile);
  if AValue.TryGetValue<TJSONValue>('headPose', LValue) then
    Parse(LValue, AData.HeadPose);
  if AValue.TryGetValue<TJSONValue>('gender', LValue) then
    Parse(LValue, AData.Gender);
  if AValue.TryGetValue<TJSONValue>('age', LValue) then
    Parse(LValue, AData.Age);
  if AValue.TryGetValue<TJSONValue>('facialHair', LValue) then
    Parse(LValue, AData.FacialHair);
  if AValue.TryGetValue<TJSONValue>('glasses', LValue) then
    Parse(LValue, AData.Glasses);
  if AValue.TryGetValue<TJSONValue>('emotion', LValue) then
    Parse(LValue, AData.Emotion);
  if AValue.TryGetValue<TJSONValue>('blur', LValue) then
    Parse(LValue, AData.Blur);
  if AValue.TryGetValue<TJSONValue>('exposure', LValue) then
    Parse(LValue, AData.Exposure);
  if AValue.TryGetValue<TJSONValue>('noise', LValue) then
    Parse(LValue, AData.Noise);
  if AValue.TryGetValue<TJSONValue>('makeup', LValue) then
    Parse(LValue, AData.Makeup);
  if AValue.TryGetValue<TJSONValue>('occlusion', LValue) then
    Parse(LValue, AData.Occlusion);
  if AValue.TryGetValue<TJSONValue>('hair', LValue) then
    Parse(LValue, AData.Hair);
  if AValue.TryGetValue<TJSONValue>('mask', LValue) then
    Parse(LValue, AData.Mask);
  if AValue.TryGetValue<TJSONArray>('accessories', LArray) then
    Parse(LArray, AData.Accessories);
  AData.Available := True;
end;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONValue;
  out AData: TAcsFaceRectangle);
begin
  if AValue = nil then
  begin
    AData.Available := False;
    Exit;
  end;
  AData.Top := AValue.GetValue<Integer>('top');
  AData.Left := AValue.GetValue<Integer>('left');
  AData.Width := AValue.GetValue<Integer>('width');
  AData.Height := AValue.GetValue<Integer>('height');
  AData.Available := True;
end;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONValue;
  out AData: TAcsFaceLandmark);
begin
  if AValue = nil then
  begin
    AData.Available := False;
    Exit;
  end;
  AData.X := AValue.GetValue<Double>('x');
  AData.Y := AValue.GetValue<Double>('y');
  AData.Available := True;
end;

class procedure TAcsFaceDetectJSON.Parse(AValue: TJSONValue;
  out AData: TAcsFaceLandmarks);
var
  LObject: TJSONObject;
begin
  if AValue = nil then
  begin
    AData.Available := False;
    Exit;
  end;
  LObject := TJSONObject(AValue);
  Parse(LObject.GetValue('eyebrowLeftOuter'), AData.EyebrowLeftOuter);
  Parse(LObject.GetValue('eyebrowLeftInner'), AData.EyebrowLeftInner);
  Parse(LObject.GetValue('eyebrowRightInner'), AData.EyebrowRightInner);
  Parse(LObject.GetValue('eyebrowRightOuter'), AData.EyebrowRightOuter);
  Parse(LObject.GetValue('eyeLeftOuter'), AData.EyeLeftOuter);
  Parse(LObject.GetValue('eyeLeftInner'), AData.EyeLeftInner);
  Parse(LObject.GetValue('eyeLeftTop'), AData.EyeLeftTop);
  Parse(LObject.GetValue('eyeLeftBottom'), AData.EyeLeftBottom);
  Parse(LObject.GetValue('eyeRightOuter'), AData.EyeRightOuter);
  Parse(LObject.GetValue('eyeRightInner'), AData.EyeRightInner);
  Parse(LObject.GetValue('eyeRightTop'), AData.EyeRightTop);
  Parse(LObject.GetValue('eyeRightBottom'), AData.EyeRightBottom);
  Parse(LObject.GetValue('pupilLeft'), AData.PupilLeft);
  Parse(LObject.GetValue('pupilRight'), AData.PupilRight);
  Parse(LObject.GetValue('mouthLeft'), AData.MouthLeft);
  Parse(LObject.GetValue('mouthRight'), AData.MouthRight);
  Parse(LObject.GetValue('noseTip'), AData.NoseTip);
  Parse(LObject.GetValue('noseRootLeft'), AData.NoseRootLeft);
  Parse(LObject.GetValue('noseRootRight'), AData.NoseRootRight);
  Parse(LObject.GetValue('noseLeftAlarTop'), AData.NoseLeftAlarTop);
  Parse(LObject.GetValue('noseRightAlarTop'), AData.NoseRightAlarTop);
  Parse(LObject.GetValue('noseLeftAlarOutTip'), AData.NoseLeftAlarOutTip);
  Parse(LObject.GetValue('noseRightAlarOutTip'), AData.NoseRightAlarOutTip);
  Parse(LObject.GetValue('upperLipTop'), AData.UpperLipTop);
  Parse(LObject.GetValue('upperLipBottom'), AData.UpperLipBottom);
  Parse(LObject.GetValue('underLipTop'), AData.UnderLipTop);
  Parse(LObject.GetValue('underLipBottom'), AData.UnderLipBottom);
  AData.Available := False;
end;

end.
