program person_class;

{$mode objfpc}{$H+}

uses sysutils, dateutils;

type
	TPerson = class
		FAwards: array of string;
		FBirth, FDeath: TDate;
		FName, FNationality, FRole: string;

		constructor Create(aName, aNationality, aRole, aBirth, aDeath: string);
		destructor Destroy; override;
		function GetAwards(index: integer): string;
		function GetLifespan: integer;
		function GetNumberOfAwards: integer;
		procedure DisplayInfo;
		procedure SetAwards(index: integer; AValue: string);

		property Awards[index: integer]: string read GetAwards write SetAwards;
		property Birth: TDate read FBirth;
		property Death: TDate read FDeath;
		property Lifespan: integer read GetLifespan;
		property Name: string read FName;
		property NumberOfAwards: integer read GetNumberOfAwards;
		property Role: string read FRole;
	end;

function TPerson.GetAwards(index: integer): string;
begin
	if Length(FAwards) > index
		then Result := FAwards[index]
	else Result := EmptyStr;
end;

function TPerson.GetNumberOfAwards: integer;
begin
	Result := Length(FAwards);
end;

procedure TPerson.SetAwards(index: integer; AValue: string);
begin
	SetLength(FAwards, index+1);
	FAwards[index] := AValue;
end;

function TPerson.GetLifespan: integer;
begin
	if FDeath = 0 then Result := YearsBetween(Now, FBirth)
	else Result := YearsBetween(FDeath, FBirth);
end;

constructor TPerson.Create(aName, aNationality, aRole, aBirth, aDeath: string);
begin
	inherited Create;
	FName := aName;
	FNationality := aNationality;
	FRole := aRole;
	FBirth := StrToDate(aBirth);

	if (aDeath = EmptyStr) then FDeath := 0
	else FDeath := StrToDate(aDeath);
end;

destructor TPerson.Destroy;
begin
	SetLength(FAwards, 0);
	inherited Destroy;
end;

procedure TPerson.DisplayInfo;
var n: integer;
begin
	WriteLn('The ', FNationality, ' ', FRole, ' ', Name, ' was born on ', DateToStr(Birth));

	case FDeath = 0 of
		True: WriteLn(' is alive today and is ', Lifespan, ' years old');
		False: WriteLn(' and died on ', DateToStr(Death), ' aged ', Lifespan, ' years');
	end;

	if NumberOfAwards > 0
		then for n := Low(FAwards) to High(FAwards)
			do WriteLn('    achieved in ', Awards[n]);

	WriteLn;
end;

var person: TPerson;
begin
	person := TPerson.Create(
		'John Lennon',
		'British',
		'songwriter',
		'09-10-1940',
		'08-12-1980'
	);
	person.DisplayInfo;
	person.Free;

	person := TPerson.Create(
		'Arvo Part',
		'Estonian',
		'composer',
		'11-08-1935',
		''
	);
	person.displayInfo;
	person.Free;

	person := TPerson.Create(
		'Usain Bolt',
		'Jamaican',
		'sprinter',
		'21-08-1986',
		''
	);
	person.Awards[0] := 'Berlin 2009 100m world record of 9.58s';
	person.Awards[1] := 'Berlin 2009 200m world record of 19.19s';
	person.Awards[2] := 'London 2012 100m Olympic record of 9.69s';
	person.Awards[3] := 'London 2012 200m Olympic record of 19.30s';
	person.DisplayInfo;
	person.Free;

	{$IFDEF WINDOWS}
	ReadLn;
	{$ENDIF}
end.
