// tnMatchStatsController's INTERFACE

    protected override void ShowStats(tnMatchController i_Controller)
    {
        base.ShowStats(i_Controller);

        if (i_Controller == null)
        {
            return;
        }

        tnBaseMatchController matchController = (tnBaseMatchController)i_Controller;

        InternalSetStats(matchController);
    }
    private void FillGoalScoredData(int i_SlotIndex, tnBaseMatchController i_MatchController)
    {
        if (i_MatchController == null)
        {
            return;
        }

        int charcatersCount = i_MatchController.charactersCount;

        // Compute total shots count.

        int totalGoalScored = 0;

        for (int characterIndex = 0; characterIndex < charcatersCount; ++characterIndex)
        {
            tnBaseMatchCharacterResults characterResults = (tnBaseMatchCharacterResults)i_MatchController.GetCharacterResultsByIndex(characterIndex);
            if (characterResults != null)
            {
                totalGoalScored += characterResults.goalScored;
            }
        }

        // Get best character for this stat.

        int selectedCharacterIndex = -1;

        int selectedCharacterId = Hash.s_NULL;
        int selectedPlayerId    = Hash.s_NULL;

        int maxGoalScored = int.MinValue;

        for (int characterIndex = 0; characterIndex < charcatersCount; ++characterIndex)
        {
            tnBaseMatchCharacterResults characterResults = (tnBaseMatchCharacterResults)i_MatchController.GetCharacterResultsByIndex(characterIndex);
            if (characterResults != null)
            {
                int characterGoalScored = characterResults.goalScored;

                if (characterGoalScored > maxGoalScored)
                {
                    selectedCharacterIndex = characterIndex;

                    selectedCharacterId = characterResults.id;
                    selectedPlayerId    = characterResults.playerId;

                    maxGoalScored = characterGoalScored;
                }
            }
        }

        if (selectedCharacterIndex < 0)
        {
            return;
        }

        // Fill data.

        string playerName     = "";
        Sprite playerPortrait = null;

        Color playerColor = Color.white;

        {
            tnCharacterData characterData = tnGameData.GetCharacterDataMain(selectedCharacterId);
            if (characterData != null)
            {
                playerName     = characterData.displayName;
                playerPortrait = characterData.uiIconFacingRight;
            }

            tnPlayerData playerData = tnGameData.GetPlayerDataMain(selectedPlayerId);
            if (playerData != null)
            {
                playerColor = playerData.color;
            }
        }

        string statValue = maxGoalScored.ToString();

        float partecipationPercentage = 0f;

        if (totalGoalScored > 0)
        {
            partecipationPercentage  = (float)maxGoalScored / (float)totalGoalScored;
            partecipationPercentage *= 100f;

            partecipationPercentage = Mathf.Clamp(partecipationPercentage, 0f, 100f);
        }

        string partecipationValue = partecipationPercentage.ToString("0.00");

        partecipationValue += "%";

        FillData(i_SlotIndex, playerName, playerPortrait, playerColor, s_StatName_GoalScored, statValue, s_PartecipationLabel, partecipationValue);
    }
    private void FillAttractTimeData(int i_SlotIndex, tnBaseMatchController i_MatchController)
    {
        if (i_MatchController == null)
        {
            return;
        }

        int charcatersCount = i_MatchController.charactersCount;

        // Compute total shots count.

        FP totalAttractTime = FP.Zero;

        for (int characterIndex = 0; characterIndex < charcatersCount; ++characterIndex)
        {
            tnBaseMatchCharacterResults characterResults = (tnBaseMatchCharacterResults)i_MatchController.GetCharacterResultsByIndex(characterIndex);
            if (characterResults != null)
            {
                totalAttractTime += characterResults.attractTime;
            }
        }

        // Get best character for this stat.

        int selectedCharacterIndex = -1;

        int selectedCharacterId = Hash.s_NULL;
        int selectedPlayerId    = Hash.s_NULL;

        FP maxAttractTime = FP.MinValue;

        for (int characterIndex = 0; characterIndex < charcatersCount; ++characterIndex)
        {
            tnBaseMatchCharacterResults characterResults = (tnBaseMatchCharacterResults)i_MatchController.GetCharacterResultsByIndex(characterIndex);
            if (characterResults != null)
            {
                FP characterAttractTime = characterResults.attractTime;

                if (characterAttractTime > maxAttractTime)
                {
                    selectedCharacterIndex = characterIndex;

                    selectedCharacterId = characterResults.id;
                    selectedPlayerId    = characterResults.playerId;

                    maxAttractTime = characterAttractTime;
                }
            }
        }

        if (selectedCharacterIndex < 0)
        {
            return;
        }

        // Fill data.

        string playerName     = "";
        Sprite playerPortrait = null;

        Color playerColor = Color.white;

        {
            tnCharacterData characterData = tnGameData.GetCharacterDataMain(selectedCharacterId);
            if (characterData != null)
            {
                playerName     = characterData.displayName;
                playerPortrait = characterData.uiIconFacingRight;
            }

            tnPlayerData playerData = tnGameData.GetPlayerDataMain(selectedPlayerId);
            if (playerData != null)
            {
                playerColor = playerData.color;
            }
        }

        string statValue = maxAttractTime.ToString(2);

        statValue += " s";

        FP partecipationPercentage = FP.Zero;

        if (totalAttractTime > FP.Zero)
        {
            partecipationPercentage  = maxAttractTime / totalAttractTime;
            partecipationPercentage *= 100f;

            partecipationPercentage = MathFP.Clamp(partecipationPercentage, FP.Zero, 100f);
        }

        string partecipationValue = partecipationPercentage.ToString(2);

        partecipationValue += "%";

        FillData(i_SlotIndex, playerName, playerPortrait, playerColor, s_StatName_AttractTime, statValue, s_PartecipationLabel, partecipationValue);
    }
    // INTERNALS

    private void InternalSetStats(tnBaseMatchController i_MathController)
    {
        if (m_StatsPanels == null)
        {
            return;
        }

        // Disable all slots.

        for (int slotIndex = 0; slotIndex < m_StatsPanels.Length; ++slotIndex)
        {
            tnStatsPanel statsPanel = m_StatsPanels[slotIndex];
            if (statsPanel != null)
            {
                statsPanel.gameObject.SetActive(false);
            }
        }

        if (i_MathController == null)
        {
            return;
        }

        int charactersCount = i_MathController.charactersCount;

        int statsCount = Mathf.Max(1, charactersCount /* / 2*/);

        // Select N random stats.

        int[] statsIndices = SelectStats(statsCount);

        for (int index = 0; index < statsIndices.Length; ++index)
        {
            // Get target stat index.

            int statIndex = statsIndices[index];

            // Select the best character for this stat.

            StatType statType = (StatType)statIndex;

            switch (statType)
            {
            case StatType.Shots:

                FillShotsData(index, i_MathController);
                break;

            case StatType.ShotsOnTarget:

                FillShotsOnTarget(index, i_MathController);
                break;

            case StatType.DistanceRun:

                FillDistanceRunData(index, i_MathController);
                break;

            case StatType.DashCount:

                FillDashCountData(index, i_MathController);
                break;

            case StatType.BallTouches:

                FillBallTouchesData(index, i_MathController);
                break;

            case StatType.AttractTime:

                FillAttractTimeData(index, i_MathController);
                break;

            case StatType.Tackles:

                FillTacklesData(index, i_MathController);
                break;

            case StatType.GoalScored:

                FillGoalScoredData(index, i_MathController);
                break;
            }
        }
    }