private void LoadIndicators(int seats, ReplayerViewModel viewModel, IEnumerable <Stat> heatMapStats)
        {
            var tasksToLoad = new List <Task>();

            var selectedPlayer = storageModel.PlayerSelectedItem;

            var players = viewModel.PlayersCollection.Select(x => x.Name).ToArray();

            for (var i = 0; i < seats; i++)
            {
                var player = players[i];

                if (playerIndicators.ContainsKey(player))
                {
                    continue;
                }

                var playerData = new HudIndicators(heatMapStats);

                // read data from statistic
                var taskToReadPlayerStats = Task.Run(() =>
                {
                    if (selectedPlayer != null &&
                        player == selectedPlayer.Name &&
                        (short?)selectedPlayer.PokerSite == viewModel.CurrentHand.PokersiteId)
                    {
                        storageModel
                        .GetStatisticCollection()
                        .Where(stat => (stat.PokersiteId == (short)viewModel.CurrentGame.GameDescription.Site) &&
                               stat.IsTourney == viewModel.CurrentGame.GameDescription.IsTournament &&
                               GameTypeUtils.CompareGameType((GameType)stat.PokergametypeId, viewModel.CurrentGame.GameDescription.GameType))
                        .ForEach(stat => playerData.AddStatistic(stat));

                        playerIndicators.AddOrUpdate(player, playerData, (key, old) => playerData);
                        return;
                    }

                    playerStatisticRepository
                    .GetPlayerStatistic(player, (short)viewModel.CurrentGame.GameDescription.Site)
                    .Where(stat => (stat.PokersiteId == (short)viewModel.CurrentGame.GameDescription.Site) &&
                           stat.IsTourney == viewModel.CurrentGame.GameDescription.IsTournament &&
                           GameTypeUtils.CompareGameType((GameType)stat.PokergametypeId, viewModel.CurrentGame.GameDescription.GameType))
                    .ForEach(stat => playerData.AddStatistic(stat));

                    playerIndicators.AddOrUpdate(player, playerData, (key, old) => playerData);
                });

                tasksToLoad.Add(taskToReadPlayerStats);
            }

            Task.WhenAll(tasksToLoad).Wait();
        }
        public HandHistory[] GetPlayerHands(string playerName, string pokerSite, string date)
        {
            EnumPokerSites site = EnumPokerSites.Unknown;

            if (!Enum.TryParse(pokerSite, out site) || site == EnumPokerSites.Unknown)
            {
                throw new WebFaultException <string>($"Cannot recognise site {pokerSite}", System.Net.HttpStatusCode.BadRequest);
            }

            var statistic = playerStatisticRepository.GetPlayerStatistic(playerName, (short)site);

            DateTime parsedDate = ParseDate(date, statistic.Max(x => x.Time));

            var handsToSelect = statistic.Where(x => x.Time.Date == parsedDate.Date);

            if (!handsToSelect.Any())
            {
                return(new HandHistory[] { });
            }

            var pokerSiteId = handsToSelect.FirstOrDefault().PokersiteId;

            return(dataService.GetGames(handsToSelect.Select(x => x.GameNumber), (short)pokerSiteId).ToArray());
        }
        /// <summary>
        /// Builds report data
        /// </summary>
        private void BuildReportData(CancellationToken cancellationToken)
        {
            LogProvider.Log.Info("Building population report.");

            lock (syncLock)
            {
                try
                {
                    var tableType = GetTableType();

                    var playerTypes = hudPlayerTypeService.CreateDefaultPlayerTypes(tableType);

                    var players = dataService.GetPlayersList();

                    var populationIndicators = playerTypes.Select(x => new PopulationReportIndicators
                    {
                        PlayerTypeName = x.Name,
                        PlayerType     = x
                    }).ToDictionary(x => x.PlayerTypeName);

                    var allPlayersType = CreateAllPlayersType();

                    var allPlayersIndicator = new PopulationReportIndicators
                    {
                        PlayerTypeName = allPlayersType.Name,
                        PlayerType     = allPlayersType,
                        CanAddHands    = true
                    };

                    var filterPredicate = storageModel.CashFilterPredicate.Compile();
                    var heroId          = storageModel.PlayerSelectedItem?.PlayerId ?? 0;

                    Parallel.ForEach(players, (player, loopState) =>
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            loopState.Break();
                        }

                        if (player.PlayerId == heroId)
                        {
                            return;
                        }

                        var playerIndicators = new LightIndicators();

                        playerStatisticRepository.GetPlayerStatistic(player.PlayerId)
                        .Where(x => !x.IsTourney && FilterStatistic(x) && filterPredicate(x))
                        .ForEach(x =>
                        {
                            if (cancellationToken.IsCancellationRequested)
                            {
                                return;
                            }

                            playerIndicators.AddStatistic(x);

                            if (filterPredicate(x))
                            {
                                lock (allPlayersIndicator)
                                {
                                    allPlayersIndicator.AddStatistic(x);
                                }
                            }
                        }
                                 );

                        var playerType = hudPlayerTypeService.Match(playerIndicators, playerTypes, true);

                        if (playerType != null)
                        {
                            if (cancellationToken.IsCancellationRequested)
                            {
                                return;
                            }

                            playerStatisticRepository.GetPlayerStatistic(player.PlayerId)
                            .Where(x => !x.IsTourney && FilterStatistic(x) && filterPredicate(x))
                            .ForEach(x =>
                            {
                                if (cancellationToken.IsCancellationRequested)
                                {
                                    return;
                                }

                                lock (populationIndicators[playerType.Name])
                                {
                                    populationIndicators[playerType.Name].AddStatistic(x);
                                }
                            }
                                     );
                        }
                    });

                    populationIndicators.Add(allPlayersIndicator.PlayerTypeName, allPlayersIndicator);

                    populationIndicators.Values.ForEach(x => x.PrepareHands());

                    populationData.Report = populationIndicators.Values.ToList();

                    if (cancellationToken.IsCancellationRequested)
                    {
                        LogProvider.Log.Info("Population report has been cancelled.");
                        populationData.Report = new List <PopulationReportIndicators>();
                        return;
                    }

                    SaveCachedData();

                    LogProvider.Log.Info("Population report has been built.");
                }
                catch (Exception e)
                {
                    LogProvider.Log.Error(this, "Could build population report data.", e);
                }
            }
        }