void UpdateAttributePanel(
            IBowPanel bowPanel,
            IBowConfigData bowConfigData
            )
        {
            int[] attributeLevels = bowConfigData.GetAttributeLevels();
            int   bowIndex        = bowPanel.GetIndex();
            int   attributeIndex  = 0;

            foreach (int attributeLevel in attributeLevels)
            {
                bowPanel.SetAttributeLevel(
                    attributeIndex,
                    attributeLevel,
                    true
                    );
                IBowAttributeLevelUpHoldButton levelUpButton = bowPanel.GetBowAttributeLevelUpHoldButtons()[attributeIndex];
                if (attributeLevel == thisPlayerDataManager.GetMaxAttributeLevel())
                {
                    levelUpButton.MaxOut();
                }
                else
                {
                    int nextLevel = attributeLevel + 1;
                    int nextCost  = CalculateCost(
                        bowIndex,
                        nextLevel
                        );
                    levelUpButton.SetNextCost(nextCost);

                    int currency = thisPlayerDataManager.GetCurrency();
                    if (currency < nextCost)
                    {
                        levelUpButton.InvalidateForShortMoney();
                    }
                    else
                    {
                        levelUpButton.ValidateForLevelUp();
                    }
                }
                attributeIndex += 1;
            }
            int equippedBowIndex = thisPlayerDataManager.GetEquippedBowIndex();

            Debug.Log(
                "BowPanel " + bowPanel.GetIndex().ToString() + ", " +
                "unlocked: " + bowConfigData.IsUnlocked().ToString() + ", " +
                "equipped: " + (bowIndex == equippedBowIndex).ToString() + ", " +
                "bowLevel: " + bowConfigData.GetBowLevel().ToString() + ", " +
                "attLevels: " + DKUtility.DebugHelper.GetIndicesString(attributeLevels)
                );
        }
        public void UnlockPanel(int index)
        {
            if (!thisPlayerDataManager.PlayerDataIsLoaded())
            {
                thisPlayerDataManager.Load();
            }

            IBowConfigData data = thisPlayerDataManager.GetBowConfigDataArray()[index];

            data.Unlock();

            int currency    = thisPlayerDataManager.GetCurrency();
            int cost        = thisPlayerDataManager.GetBowUnlockCostArray()[index];
            int newCurrency = currency - cost;

            UpdateCurrency(newCurrency);

            TrySetEquippedBow(index);

            IBowPanel panel = thisBowPanels[index];

            panel.Unlock(false);
        }
        public void IncreaseAttributeLevel(int attributeIndex)
        {
            if (!thisPlayerDataManager.PlayerDataIsLoaded())
            {
                thisPlayerDataManager.Load();
            }

            thisPlayerDataManager.IncreaseAttributeLevel(attributeIndex);

            int       equippedBowIndex = thisPlayerDataManager.GetEquippedBowIndex();
            IBowPanel panel            = thisBowPanels[equippedBowIndex];

            IBowConfigData[] dataArray = thisPlayerDataManager.GetBowConfigDataArray();
            IBowConfigData   data      = dataArray[equippedBowIndex];
            int bowLevel = data.GetBowLevel();

            panel.SetBowLevel(bowLevel, false);

            IBowAttributeLevelUpHoldButton button = panel.GetBowAttributeLevelUpHoldButtons()[attributeIndex];

            int currency    = thisPlayerDataManager.GetCurrency();
            int newCurrency = currency - button.GetCost();

            UpdateCurrency(newCurrency);

            foreach (IBowPanel bowPanel in thisBowPanels)
            {
                IBowConfigData configData = dataArray[bowPanel.GetIndex()];
                UpdateAttributePanel(
                    bowPanel,
                    configData
                    );
            }
            UpdateUnlockButtons();
            thisPlayerDataManager.Save();
        }
        /* Data Manipulation */
        public void TrySetEquippedBow(int index)
        {
            if (!thisPlayerDataManager.PlayerDataIsLoaded())
            {
                thisPlayerDataManager.Load();
            }
            int prevEquippedBowIndex = thisPlayerDataManager.GetEquippedBowIndex();

            if (prevEquippedBowIndex != index)
            {
                IBowConfigData configData = thisPlayerDataManager.GetBowConfigDataArray()[index];
                if (configData.IsUnlocked())
                {
                    thisPlayerDataManager.SetEquippedBow(index);
                    thisPlayerDataManager.Save();

                    IBowPanel panelToEquip   = thisBowPanels[index];
                    IBowPanel panelToUnequip = thisBowPanels[prevEquippedBowIndex];

                    panelToEquip.SetEquippedness(true, false);
                    panelToUnequip.SetEquippedness(false, false);
                }
            }
        }