public void Add(UserMatchData userMatchData)
        {
            //get correct elo(s) types to display
            var formatingTargetTypes = EloFormattController.GetTargetEloTypes(userMatchData.MatchType);

            var playerPanel = new PlayerPanel2
            {
                //PlayerName = userStats.Name,
                //Civilization = userStats.Civilization,
                //PlayerColor = userStats.Color,
                //OneVsOneElo = null,
                //TeamGameElo = null,
                PrimaryUserRankModeDisplay   = formatingTargetTypes.Item1,
                SecondaryUserRankModeDisplay = formatingTargetTypes.Item2,
                UserMatchData = userMatchData,
                Width         = 275
            };

            if (userMatchData.Team == 1)
            {
                playerPanel.ContentAlign = PlayerPanelContentAlignMode.Left;
                team1.Children.Add(playerPanel);
            }
            else if (userMatchData.Team == 2)
            {
                playerPanel.ContentAlign = PlayerPanelContentAlignMode.Right;
                team2.Children.Add(playerPanel);
            }
        }
        public static void MergeUserRank(this UserMatchData userMatchData, UserData userRankData)
        {
            //iterate over all rank types
            foreach (var rank in Enum.GetValues(typeof(Ladders)))
            {
                var rankType = (Ladders)rank;

                //check what ranting type we can expect to be update
                if (userRankData.AviableRatings.Contains(rankType))
                {
                    //update if already exist
                    if (userMatchData.UserRankData.UserRatings.ContainsKey(rankType))
                    {
                        userMatchData.UserRankData.UserRatings[rankType] = userRankData.UserRatings[rankType];
                    }
                    //add new if not exist
                    else
                    {
                        userMatchData.UserRankData.UserRatings.Add(rankType, userRankData.UserRatings[rankType]);
                    }
                }
            }
        }
        Match IUserDataProcessingService.ProcessMatch(string jsonResponse, AoeNetAPIStringResources apiStringResources)
        {
            var matchResponse = JsonConvert.DeserializeObject <MatchResponse>(
                jsonResponse
                );

            var match = new Match
            {
                //todo: handle opened as separate state independent then start
                Opened = matchResponse.last_match.started,

                Finished = matchResponse.last_match.finished,
                MatchId  = matchResponse.last_match.match_id,

                Users     = new List <UserMatchData>(),
                MatchType = (MatchType)matchResponse.last_match.leaderboard_id
            };

            //create user match data models from response model
            foreach (var player in matchResponse.last_match.players)
            {
                //assign basic data
                UserMatchData userMatchData = new UserMatchData
                {
                    Name = player.name,


                    Team  = player.team,
                    Color = ((UserColors)player.color).ToString()
                };

                //for compatibility with: MatchMinimalResponse set, cause API is returning null civs sometimes
                string civilization = "";

                try
                {
                    civilization = apiStringResources.Civ //find matching civilization from API resources
                                   .First(id => id.Id == player.civ)
                                   .String;
                }
                catch (Exception e)
                {
                    if (
                        e is StackOverflowException ||
                        e is ThreadAbortException ||
                        e is AccessViolationException
                        )
                    {
                        throw e;
                    }

                    civilization = "Unknown uivilization";
                }
                finally
                {
                    userMatchData.Civilization = civilization;
                }

                //assign game profile id
                var userGameProfileId = new UserGameProfileId
                {
                    ProfileId = player.profile_id.ToString()
                };
                userMatchData.UserGameProfileId = userGameProfileId;
                userMatchData.UserRankData      = new UserData();
                userMatchData.MatchType         = (MatchType)matchResponse.last_match.leaderboard_id;

                //assign ratings if aviable
                if (player.rating != null)
                {
                    var ratingType = (Ladders)matchResponse.last_match.leaderboard_id;

                    var userRank = new UserRank
                    {
                        Elo    = player.rating.Value,
                        Ladder = null //we have to send separate request to check ladder
                    };

                    userMatchData.UserRankData.UserRatings.Add(ratingType, userRank);
                }

                match.Users.Add(userMatchData);
            }

            return(match);
        }
        void HandleUserRatingChanged(Tuple <UserGameProfileId, UserData> userRatingData)
        {
            var id   = userRatingData.Item1;
            var rank = userRatingData.Item2;

            UserMatchData targetData    = null;
            PlayerPanel2  targetControl = null;

            team1.Dispatcher.Invoke(() =>
            {
                //search for data related with userGameProfileId in fisrt collection (team 1)
                foreach (var child in team1.Children)
                {
                    var control = child as PlayerPanel2;

                    if (control.UserMatchData.UserGameProfileId.ProfileId == id.ProfileId)
                    {
                        targetData    = control.UserMatchData;
                        targetControl = control;
                        break;
                    }
                }

                //search for data related with userGameProfileId in second collection (team 2)
                foreach (var child in team2.Children)
                {
                    if (targetData != null)
                    {
                        break;
                    }

                    var control = child as PlayerPanel2;

                    if (control.UserMatchData.UserGameProfileId.ProfileId == id.ProfileId)
                    {
                        targetData    = control.UserMatchData;
                        targetControl = control;
                        break;
                    }
                }

                //if found
                if (targetData != null)
                {
                    team1.Dispatcher.Invoke(() =>
                    {
                        var logPropertiesBeforeUpdate = new Dictionary <string, object>
                        {
                            { "update target", targetData.ToString() }
                        };

#if DEBUG
                        LogService.Debug($"Updating user data {id} rank", logPropertiesBeforeUpdate);
#else
                        LogService.Trace($"Updating user data {id} rank");
#endif

                        try
                        {
                            targetData.MergeUserRank(rank);

                            //todo: refactor implementing INotifyPropertyChanged chain in models to auto perform property update
                            targetControl.UpdateUserELO();
                        }
                        catch (Exception e)
                        {
                            //rethrow if should be handled ie: if exception is StackOverflowException
                            e.RethrowIfExceptionCantBeHandled();

                            var logProperties = new Dictionary <string, object>();
                            logProperties.Add("id", id);
                            logProperties.Add("stack", e.StackTrace);

                            LogService.Warning($"Unable to merge user ratings: {e.ToString()}", logProperties);
                        }
                    });
                }
                else
                {
                    var logProperties = new Dictionary <string, object>
                    {
                        //logProperties.Add("Team 1: ", team1.Children);
                        //logProperties.Add("Team 2: ", team2.Children);
                        { "User id to update: ", id }
                    };
                    LogService.Error("Unable to find game profileId to update");
                }
            });
        }
 public void Clear()
 {
     UserMatchData.Clear();
     team1.Children.Clear();
     team2.Children.Clear();
 }