{ ============================================

  Software Name : 	UPM
  ============================================ }
{ ******************************************** }
{ Written By WalWalWalides                     }
{ CopyRight © 2019                             }
{ Email : WalWalWalides@gmail.com              }
{ GitHub :https://github.com/walwalwalides     }
{ ******************************************** }

unit AttributesU;

interface

uses
  ValidatorU;

type

  ValidationAttribute = class abstract(TCustomAttribute)
  private
    FContext: String;
  protected
    FErrorMessage: string;
    function DoValidate(AValue: string): Boolean; virtual; abstract;
  public
    constructor Create(AErrorMessage: string; AContext: String = '');
    function Validate(AValue: string): TValidationResult;
    function AcceptContext(AContext: String): Boolean;
  end;

  RequiredValidationAttribute = class(ValidationAttribute)
  public
    function DoValidate(AValue: string): Boolean; override;
  end;

  MaxLengthValidationAttribute = class(ValidationAttribute)
  protected
    FLength: Integer;
  public
    constructor Create(AErrorMessage: string; ALength: Integer; AContext: String = '');
    function DoValidate(AValue: string): Boolean; override;
  end;

  MinLengthValidationAttribute = class(MaxLengthValidationAttribute)
  public
    function DoValidate(AValue: string): Boolean; override;
  end;

  RegexValidationAttribute = class(ValidationAttribute)
  private
    FRegex: string;
  public
    constructor Create(AErrorMessage: string; ARegex: string; AContext: String = '');
    function DoValidate(AValue: string): Boolean; override;
  end;

implementation

uses
  System.SysUtils, System.RegularExpressions, InsertEmployee;

{ ValidationAttribute }

function ValidationAttribute.AcceptContext(AContext: String): Boolean;
var
  LContexts: TArray<String>;
  LContext: String;
begin
  Result := False;
  LContexts := FContext.Split([';']); // used if yiu have more context
  for LContext in LContexts do
    if LContext.ToLower = AContext.ToLower then
      Exit(true)
end;

constructor ValidationAttribute.Create(AErrorMessage: string; AContext: String = '');
begin

  FErrorMessage := AErrorMessage;
  FContext := AContext;
end;

function ValidationAttribute.Validate(AValue: string): TValidationResult;    //add error to record in validator
begin
  if not DoValidate(AValue) then
    Result.ErrorMessage := FErrorMessage;
end;

{ RequiredValidationAttribute }

function RequiredValidationAttribute.DoValidate(AValue: string): Boolean;
begin
  // value cannot be empty
  Result := not AValue.IsEmpty;
end;

{ MaxLengthValidationAttribute }

constructor MaxLengthValidationAttribute.Create(AErrorMessage: string; ALength: Integer; AContext: String = '');
begin
  inherited Create(AErrorMessage, AContext);
  FLength := ALength;
end;

function MaxLengthValidationAttribute.DoValidate(AValue: string): Boolean;
begin
  // length of value must be less than or equal to length provided in attributes
  Result := Length(AValue) <= FLength;
  if (Result = False) then
    frmInsertEmployee.GlystatUser.ImageIndex := 0;
end;

{ MinLengthValidationAttribute }

function MinLengthValidationAttribute.DoValidate(AValue: string): Boolean;
begin
  // length of value must be greather than or equal to length provided in attributes
  Result := Length(AValue) >= FLength;
  if (Result = False) then
    frmInsertEmployee.GlystatUser.ImageIndex := 0
  else
  frmInsertEmployee.GlystatUser.ImageIndex := 1;
end;

{ RegexValidationAttribute }

constructor RegexValidationAttribute.Create(AErrorMessage: string; ARegex: string; AContext: String = '');
begin
  inherited Create(AErrorMessage, AContext);
  FRegex := ARegex;
end;

function RegexValidationAttribute.DoValidate(AValue: string): Boolean;
begin
  // Match the value of regular expression
  Result := TRegEx.IsMatch(AValue, FRegex);

  if ((Pos('@',AValue) <> 0) and (Result = true)) then
   frmInsertEmployee.GlystatEmail.ImageIndex := 1;


    if ((Result = true) and (Pos('@',AValue)= 0)) then
      frmInsertEmployee.GlystatPass.ImageIndex := 1;






end;

end.
