1using CommunityToolkit.Mvvm.ComponentModel;
2using System.Collections.ObjectModel;
11 public class Person : ObservableObject, IEquatable<Person>, ICloneable
20 Starts =
new Dictionary<SwimmingStyles, PersonStart>();
29 newStart.PropertyChanged += PersonStart_PropertyChanged;
40 if (other ==
null) {
return; }
41 this.Name = other.
Name;
43 this.Gender = other.
Gender;
47 this.FriendGroupIDs = (other.FriendGroupIDs !=
null) ?
new ObservableCollection<int>(other.
FriendGroupIDs) :
null;
48 this.Friends = (other.Friends !=
null) ?
new List<Person>(other.
Friends) :
null;
51 this.Starts = other.
Starts.ToDictionary(kvp => kvp.Key, kvp => kvp.Value?.Clone() as
PersonStart);
58 #region Basic properties
60 private string _name =
string.Empty;
68 set => SetProperty(ref _name, value);
71 private string _firstName =
string.Empty;
79 set => SetProperty(ref _firstName, value);
90 set => SetProperty(ref _gender, value);
93 private UInt16 _birthYear;
101 set => SetProperty(ref _birthYear, value);
108 #region Competition related properties
110 private Dictionary<SwimmingStyles, Competition> _availableCompetitions =
new Dictionary<SwimmingStyles, Competition>();
117 get => _availableCompetitions;
120 if (SetProperty(ref _availableCompetitions, value))
135 Dictionary<SwimmingStyles, bool> availableCompetitionsFlags =
new Dictionary<SwimmingStyles, bool>();
138 availableCompetitionsFlags.Add(kvp.Key, kvp.Value !=
null);
140 return availableCompetitionsFlags;
152 Dictionary<SwimmingStyles, int> availableCompetitionsIDs =
new Dictionary<SwimmingStyles, int>();
155 availableCompetitionsIDs.Add(kvp.Key, kvp.Value?.Id ?? -1);
157 return availableCompetitionsIDs;
161 private Dictionary<SwimmingStyles, bool> _isUsingMaxAgeCompetitionDict =
new Dictionary<SwimmingStyles, bool>();
168 get => _isUsingMaxAgeCompetitionDict;
169 set => SetProperty(ref _isUsingMaxAgeCompetitionDict, value);
172 private Dictionary<SwimmingStyles, bool> _isUsingExactAgeCompetitionDict =
new Dictionary<SwimmingStyles, bool>();
179 get => _isUsingExactAgeCompetitionDict;
180 set => SetProperty(ref _isUsingExactAgeCompetitionDict, value);
187 #region Starts management
193 private Dictionary<SwimmingStyles, PersonStart>
_availableStartsDict =
new Dictionary<SwimmingStyles, PersonStart>();
195 private Dictionary<SwimmingStyles, PersonStart> _starts =
new Dictionary<SwimmingStyles, PersonStart>();
200 public Dictionary<SwimmingStyles, PersonStart>
Starts
203 set => SetProperty(ref _starts, value);
230 if (start ==
null && available)
234 else if (start !=
null && !available)
238 OnPropertyChanged(nameof(
Starts));
240 OnPropertyChanged(nameof(
IsActive));
251 if (start ==
null) {
return; }
259 #region Properties derived from the starts
292 get =>
Starts?.Values?.Where(s => s !=
null)?.Any(s => s.IsActive) ??
false;
295 if (
Starts ==
null) {
return; }
296 Starts?.Values?.Where(s => s !=
null)?.ToList()?.ForEach(s => s.IsActive = value);
297 OnPropertyChanged(nameof(
IsActive));
305 #region Other properties
307 private bool _hasDuplicates =
false;
315 get => _hasDuplicates;
316 set => SetProperty(ref _hasDuplicates, value);
319 private int _resultListPlace = 0;
327 get => _resultListPlace;
328 set => SetProperty(ref _resultListPlace, value);
335 #region PersonStart PropertyChanged event handler
337 private void PersonStart_PropertyChanged(
object sender,
System.ComponentModel.PropertyChangedEventArgs e)
339 OnPropertyChanged(nameof(
Starts));
343 switch(e.PropertyName)
346 OnPropertyChanged(nameof(
IsActive));
356 #region Style Properties for faster access and file saving
422 #region Time Properties for faster access and file saving
488 #region Friendship properties
490 private ObservableCollection<int> _friendGroupIDs =
new ObservableCollection<int>();
498 get => _friendGroupIDs;
501 if (_friendGroupIDs !=
null) { _friendGroupIDs.CollectionChanged -= _friendGroupIDs_CollectionChanged; }
502 if (SetProperty(ref _friendGroupIDs, value))
504 if (_friendGroupIDs !=
null)
506 _friendGroupIDs.Sort((a, b) => a.CompareTo(b));
507 _friendGroupIDs.CollectionChanged += _friendGroupIDs_CollectionChanged;
513 private void _friendGroupIDs_CollectionChanged(
object sender,
System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
518 private List<Person> _friends =
new List<Person>();
527 set => SetProperty(ref _friends, value);
534 #region SetPropertyFromString helper
549 if(
string.IsNullOrEmpty(value))
return;
551 switch (propertyName)
553 case nameof(
FirstName): dataObj.FirstName = value;
break;
554 case nameof(
Name): dataObj.Name = value;
break;
555 case nameof(
Gender):
if (EnumCoreLocalizedStringHelper.TryParse(value, out
Genders parsedGender)) { dataObj.Gender = parsedGender; }
break;
556 case nameof(
BirthYear): dataObj.BirthYear = UInt16.Parse(value);
break;
558 dataObj.Breaststroke = !
string.IsNullOrEmpty(value);
562 dataObj.Freestyle = !
string.IsNullOrEmpty(value);
566 dataObj.Backstroke = !
string.IsNullOrEmpty(value);
570 dataObj.Butterfly = !
string.IsNullOrEmpty(value);
574 dataObj.Medley = !
string.IsNullOrEmpty(value);
578 dataObj.WaterFlea = !
string.IsNullOrEmpty(value);
581 case nameof(
BreaststrokeTime): dataObj.BreaststrokeTime = TimeSpan.Parse(value);
break;
582 case nameof(
FreestyleTime): dataObj.FreestyleTime = TimeSpan.Parse(value);
break;
583 case nameof(
BackstrokeTime): dataObj.BackstrokeTime = TimeSpan.Parse(value);
break;
584 case nameof(
ButterflyTime): dataObj.ButterflyTime = TimeSpan.Parse(value);
break;
585 case nameof(
MedleyTime): dataObj.MedleyTime = TimeSpan.Parse(value);
break;
586 case nameof(
WaterFleaTime): dataObj.WaterFleaTime = TimeSpan.Parse(value);
break;
587 case nameof(
FriendGroupIDs): dataObj.FriendGroupIDs =
new ObservableCollection<int>(value.Split(
',').Select(s =>
int.Parse(s))); dataObj.
FriendGroupIDs.Sort((a, b) => a.CompareTo(b));
break;
596 #region Equality, HashCode, ToString, Clone
621 => base.GetHashCode();
649 if (dict1 == dict2)
return true;
650 if ((dict1 ==
null) || (dict2 ==
null))
return false;
651 if (dict1.Count != dict2.Count)
return false;
653 EqualityComparer<TValue> valueComparer = EqualityComparer<TValue>.Default;
655 foreach (KeyValuePair<TKey, TValue> kvp
in dict1)
658 if (!dict2.TryGetValue(kvp.Key, out value2))
return false;
659 if (!valueComparer.Equals(kvp.Value, value2))
return false;
Class describing a competition.
double HighestScore
This is score of the start in the Starts dictionary with the highest score value.
Competition HighestScoreCompetition
This is the competition of the start in the Starts dictionary for which the highest score value was r...
string FirstName
First name of the person.
bool Breaststroke
Starting with Breaststroke.
override bool Equals(object obj)
Compare if two Persons are equal.
Dictionary< SwimmingStyles, int > AvailableCompetitionsIDs
Get the competition IDs for the AvailableCompetitions (-1 = when Competition is null)
TimeSpan ButterflyTime
Time for Butterfly.
TimeSpan WaterFleaTime
Time for WaterFlea.
Person(Person other)
Clone constructor for a Person object.
void SetStartAvailable(SwimmingStyles style, bool available)
Set the flag if the start is available.
bool HasStarts
True if at least one of the starts in the Starts dictionary is not null.
void SetStartTime(SwimmingStyles style, TimeSpan time)
Set the time for the matching start if available.
ObservableCollection< int > FriendGroupIDs
IDs of the friend groups the person belongs to.
TimeSpan FreestyleTime
Time for Freestyle.
PersonStart GetStartByStyle(SwimmingStyles style)
Get the first start in the list of starts of the person that matches the style.
TimeSpan MedleyTime
Time for Medley.
bool WaterFlea
Starting with WaterFlea.
const string START_INACTIVE_MARKER_STRING
String used to mark a start as inactive in the file (case-insensitive)
Dictionary< SwimmingStyles, bool > IsUsingMaxAgeCompetitionDict
Dictionary with flags if the max age competition will be used for the person and the style.
Dictionary< SwimmingStyles, bool > IsUsingExactAgeCompetitionDict
Dictionary with flags if the exact age competition will be used for the person and the style.
Dictionary< SwimmingStyles, Competition > AvailableCompetitions
Dictionary with all available Competition of the person.
bool Equals(Person other)
Indicates wheather the current object is equal to another object of the same type.
Dictionary< SwimmingStyles, bool > AvailableCompetitionsFlags
Representation for the AvailableCompetitions as boolean flags (true = when competition is available,...
List< Person > Friends
Friends of the person.
UInt16 BirthYear
Birth year of the person.
Dictionary< SwimmingStyles, PersonStart > _availableStartsDict
This dictionary holds all available starts of the person (no matter if assigned or not).
TimeSpan BreaststrokeTime
Time for Breaststroke.
TimeSpan BackstrokeTime
Time for Backstroke.
bool HasDuplicates
This flag indicates if there are duplicates of this in the person list.
bool Butterfly
Starting with Butterfly.
Person()
Constructor for a new Person object.
string Name
Last name of the person.
PersonStart HighestScoreStart
This is the start in the Starts dictionary with the highest score value.
Genders Gender
Gender of the person.
bool Backstroke
Starting with Backstroke.
bool IsActive
Check if at least one of the starts in the Starts dictionary is active.
object Clone()
Create a new object that has the same property values than this one.
Dictionary< SwimmingStyles, PersonStart > Starts
Dictionary with all starts of the person.
static void SetPropertyFromString(Person dataObj, string propertyName, string value)
Set the requested property in the Person object by parsing the given string value.
override string ToString()
Returns a string that represents the current object.
SwimmingStyles HighestScoreStyle
This is the style of the start in the Starts dictionary for which the highest score value was reached...
override int GetHashCode()
Serves as the default hash function.
bool Freestyle
Starting with Freestyle.
bool CompareDictionaries< TKey, TValue >(Dictionary< TKey, TValue > dict1, Dictionary< TKey, TValue > dict2)
Compare if two dictionaries are equal (same keys and same values)
bool Medley
Starting with Medley.
int ResultListPlace
This is the place in the overall result list of the person.
Class describing a start of a person.
TimeSpan Time
Time the person needed during the race of this start.
SwimmingStyles
Available swimming styles.
Genders
Available genders for a person.