private void OptimizeCharacter(GameData.DataBuddyInformation character, string stat, bool ignoreRecordMateria, int numberOfEquipment)
        {
            DataPartyDetails party = FFRKProxy.Instance.GameState.PartyDetails;
            int index = -1;
            for (int i = 0; i < 5; i++)
            {
                if (characters[i] != null && characters[i].BuddyId == character.BuddyId)
                {
                    index = i;
                    break;
                }
            }
            if (index == -1)
            {
                return;
            }

            List<uint> equippedWeapons = new List<uint>();
            List<uint> equippedArmor = new List<uint>();
            List<uint> equippedAccessories = new List<uint>();
            List<DataRecordMateriaInformation> equippedRecordMateria = new List<DataRecordMateriaInformation>();
            for (int i = 0; i < 5; i++)
            {
                if (i == index)
                {
                    continue;
                }

                if (weaponBoxes[i].SelectedItem != null)
                {
                    equippedWeapons.Add(((DataEquipmentInformation)weaponBoxes[i].SelectedItem).InstanceId);
                }

                if (armorBoxes[i].SelectedItem != null)
                {
                    equippedArmor.Add(((DataEquipmentInformation)armorBoxes[i].SelectedItem).InstanceId);
                }

                if (accessoryBoxes[i].SelectedItem != null)
                {
                    equippedAccessories.Add(((DataEquipmentInformation)accessoryBoxes[i].SelectedItem).InstanceId);
                }

                if (recordMateriaBoxes[i].SelectedItem != null)
                {
                    equippedRecordMateria.Add(((DataRecordMateriaInformation)recordMateriaBoxes[i].SelectedItem));
                }
            }

            List<DataEquipmentInformation> atkWeapons = new List<DataEquipmentInformation>();
            foreach (DataEquipmentInformation weapon in party.Equipments.Where(equip => equip.Type == GameData.SchemaConstants.ItemType.Weapon && !equippedWeapons.Contains(equip.InstanceId)))
            {
                if (characters[index].UsableEquipCategories.Contains(weapon.Category))
                {
                    atkWeapons.Add(weapon);
                }
            }

            List<DataEquipmentInformation> atkArmor = new List<DataEquipmentInformation>();
            foreach (DataEquipmentInformation armor in party.Equipments.Where(equip => equip.Type == GameData.SchemaConstants.ItemType.Armor && !equippedArmor.Contains(equip.InstanceId)))
            {
                if (characters[index].UsableEquipCategories.Contains(armor.Category))
                {
                    atkArmor.Add(armor);
                }
            }

            atkWeapons = atkWeapons.OrderByDescending(weapon => weapon.StatWithSynergy(stat,
                weapon.SeriesId == RealmSynergy.SeriesId || character.EligibleForNightmareShift(RealmSynergy.NightmareCategory))).ToList();
            List<DataEquipmentInformation> possibleWeapons = new List<DataEquipmentInformation>();
            foreach (DataEquipmentInformation weapon in atkWeapons)
            {
                if (FFRKInspector.GameData.EquipmentElementalInformation.ElementalEquipment.ContainsKey(weapon.EquipmentId) ||
                    possibleWeapons.Count(item => item.Category == weapon.Category) < numberOfEquipment)
                {
                    possibleWeapons.Add(weapon);
                }
            }

            atkArmor = atkArmor.OrderByDescending(armor => armor.StatWithSynergy(stat,
                armor.SeriesId == RealmSynergy.SeriesId || character.EligibleForNightmareShift(RealmSynergy.NightmareCategory)))
                .ThenByDescending(armor => armor.StatWithSynergy("Res", armor.SeriesId == RealmSynergy.SeriesId
                    || character.EligibleForNightmareShift(RealmSynergy.NightmareCategory))
                        + armor.StatWithSynergy("Def", armor.SeriesId == RealmSynergy.SeriesId
                        || character.EligibleForNightmareShift(RealmSynergy.NightmareCategory)))
                .ToList();
            List<DataEquipmentInformation> possibleArmor = new List<DataEquipmentInformation>();
            foreach (DataEquipmentInformation armor in atkArmor)
            {
                if (FFRKInspector.GameData.EquipmentElementalInformation.ElementalEquipment.ContainsKey(armor.EquipmentId) ||
                    possibleArmor.Count(item => item.Category == armor.Category) < numberOfEquipment)
                {
                    possibleArmor.Add(armor);
                }
            }

            DataEquipmentInformation accessory = party.Equipments.Where(equip => equip.Type == GameData.SchemaConstants.ItemType.Accessory
                && !equippedAccessories.Contains(equip.InstanceId))
                .OrderByDescending(acc => acc.StatWithSynergy(stat, acc.SeriesId == RealmSynergy.SeriesId
                    || character.EligibleForNightmareShift(RealmSynergy.NightmareCategory)))
                    .ThenByDescending(acc => acc.StatWithSynergy("Res", acc.SeriesId == RealmSynergy.SeriesId
                    || character.EligibleForNightmareShift(RealmSynergy.NightmareCategory))
                        + acc.StatWithSynergy("Def", acc.SeriesId == RealmSynergy.SeriesId
                        || character.EligibleForNightmareShift(RealmSynergy.NightmareCategory)))
                    .First();

            List<DataRecordMateriaInformation> possibleRecordMateria = new List<DataRecordMateriaInformation>();
            if (!ignoreRecordMateria)
            {
                possibleRecordMateria = party.RecordMaterias.Where(rm => !equippedRecordMateria.Any(eRM => eRM.RecordMateriaId == rm.RecordMateriaId)).ToList();
                if ((character.BuddyId == (uint)GameData.SchemaConstants.BuddyID.DESHI && character.UsableSoulBreaks.Any(sb => sb.SoulBreakId == new GameData.SoulBreaks.SentinelsGrimoire().SoulBreakId))
                    || (character.BuddyId == (uint)GameData.SchemaConstants.BuddyID.YSHTOLA && character.UsableSoulBreaks.Any(sb => sb.SoulBreakId == new GameData.SoulBreaks.StoneskinII().SoulBreakId))
                    || (character.BuddyId == (uint)GameData.SchemaConstants.BuddyID.RAMZA && character.UsableSoulBreaks.Any(sb => sb.SoulBreakId == new GameData.SoulBreaks.Shout().SoulBreakId))
                    )
                {
                    if (possibleRecordMateria.Any(rm => rm.RecordMateriaId == new GameData.RecordMaterias.MakoMight().RecordMateriaId || rm.RecordMateriaId == new GameData.RecordMaterias.DrMogsTeachings().RecordMateriaId))
                    {
                        possibleRecordMateria.RemoveAll(rm => !(rm.RecordMateriaId == new GameData.RecordMaterias.MakoMight().RecordMateriaId
                            || rm.RecordMateriaId == new GameData.RecordMaterias.DrMogsTeachings().RecordMateriaId));
                    }
                }
            }

            DataEquipmentInformation weaponToEquip = null;
            DataEquipmentInformation armorToEquip = null;
            DataRecordMateriaInformation recordMateriaToEquip = null;

            double maxDamage = 0;
            GameData.SchemaConstants.Formulas formulaToUse;
            switch (stat)
            {
                case "Mag":
                    formulaToUse = GameData.SchemaConstants.Formulas.Magical;
                    break;
                case "Mnd":
                    formulaToUse = GameData.SchemaConstants.Formulas.Healing;
                    break;
                default:
                    formulaToUse = GameData.SchemaConstants.Formulas.Physical;
                    break;
            }
            GameData.Ability ability = (GameData.Ability)abilityBoxes[index * 2].SelectedItem;
            if (ability == null || ability.Formula != formulaToUse || ability.Category == GameData.SchemaConstants.AbilityCategory.None)
            {
                switch (formulaToUse)
                {
                    case GameData.SchemaConstants.Formulas.Magical:
                        ability = new GameData.Abilities.Ruin();
                        break;

                    case GameData.SchemaConstants.Formulas.Healing:
                        ability = new GameData.Abilities.Cure();
                        break;

                    default:
                        ability = new GameData.Abilities.Attack();
                        break;
                }
            }
            bool characterHasNightmareShift = character.EligibleForNightmareShift(RealmSynergy.NightmareCategory);
            bool characterHasSynergy = character != null && (character.SeriesId == RealmSynergy.SeriesId ||
                characterHasNightmareShift);
            bool accessoryHasSynergy = accessory != null && (accessory.SeriesId == RealmSynergy.SeriesId ||
                characterHasNightmareShift);

            int recordMateriaCount = possibleRecordMateria.Count;
            Dictionary<GameData.SchemaConstants.EquipmentCategory, int> categoriesChecked = new Dictionary<GameData.SchemaConstants.EquipmentCategory, int>();
            foreach (DataEquipmentInformation weapon in possibleWeapons)
            {
                bool weaponHasSynergy = weapon != null && (weapon.SeriesId == RealmSynergy.SeriesId ||
                    characterHasNightmareShift);
                foreach (DataEquipmentInformation armor in possibleArmor)
                {
                    bool armorHasSynergy = armor != null && (armor.SeriesId == RealmSynergy.SeriesId ||
                        characterHasNightmareShift);
                    if (recordMateriaCount > 0)
                    {
                        foreach (DataRecordMateriaInformation recordMateria in possibleRecordMateria)
                        {
                            double atk = CalculateStat("Atk", character, weapon, armor, accessory, recordMateria, characterHasSynergy, weaponHasSynergy, armorHasSynergy, accessoryHasSynergy);
                            double mag = CalculateStat("Mag", character, weapon, armor, accessory, recordMateria, characterHasSynergy, weaponHasSynergy, armorHasSynergy, accessoryHasSynergy);
                            double mnd = CalculateStat("Mnd", character, weapon, armor, accessory, recordMateria, characterHasSynergy, weaponHasSynergy, armorHasSynergy, accessoryHasSynergy);
                            double damage = damagePerHit(character, weapon, armor, accessory, recordMateria, atk, mag, mnd, ability);
                            if (damage > maxDamage)
                            {
                                if (damage > 9999 && maxDamage >= 9999)
                                {
                                    continue;
                                }
                                maxDamage = damage;
                                weaponToEquip = weapon;
                                armorToEquip = armor;
                                recordMateriaToEquip = recordMateria;
                            }
                            else if (damage == maxDamage && weapon == weaponToEquip && armor != armorToEquip)
                            {
                                bool otherArmorSynergy = armorToEquip.SeriesId == RealmSynergy.SeriesId || characterHasNightmareShift;
                                if ((armor.StatWithSynergy("Def", armorHasSynergy) + armor.StatWithSynergy("Res", armorHasSynergy)) >
                                    (armorToEquip.StatWithSynergy("Def", otherArmorSynergy) + armorToEquip.StatWithSynergy("Res", otherArmorSynergy)))
                                {
                                    armorToEquip = armor;
                                }
                            }
                        }
                    }
                    else
                    {
                        DataRecordMateriaInformation recordMateria = recordMaterias[index];
                        double atk = CalculateStat("Atk", character, weapon, armor, accessory, recordMateria, characterHasSynergy, weaponHasSynergy, armorHasSynergy, accessoryHasSynergy);
                        double mag = CalculateStat("Mag", character, weapon, armor, accessory, recordMateria, characterHasSynergy, weaponHasSynergy, armorHasSynergy, accessoryHasSynergy);
                        double mnd = CalculateStat("Mnd", character, weapon, armor, accessory, recordMateria, characterHasSynergy, weaponHasSynergy, armorHasSynergy, accessoryHasSynergy);
                        double damage = damagePerHit(character, weapon, armor, accessory, recordMateria, atk, mag, mnd, ability);
                        if (damage > maxDamage)
                        {
                            if (damage > 9999 && maxDamage >= 9999)
                            {
                                continue;
                            }
                            maxDamage = damage;
                            weaponToEquip = weapon;
                            armorToEquip = armor;
                            recordMateriaToEquip = recordMateria;
                        }
                        else if (damage == maxDamage && weapon == weaponToEquip && armor != armorToEquip)
                        {
                            bool otherArmorSynergy = armorToEquip.SeriesId == RealmSynergy.SeriesId || characterHasNightmareShift;
                            if ((armor.StatWithSynergy("Def", armorHasSynergy) + armor.StatWithSynergy("Res", armorHasSynergy)) >
                                (armorToEquip.StatWithSynergy("Def", otherArmorSynergy) + armorToEquip.StatWithSynergy("Res", otherArmorSynergy)))
                            {
                                armorToEquip = armor;
                            }
                        }
                    }
                }
            }

            if (weaponToEquip != null)
            {
                for (int i = 0; i < weaponBoxes[index].Items.Count; i++)
                {
                    if (((DataEquipmentInformation)weaponBoxes[index].Items[i]).InstanceId == weaponToEquip.InstanceId)
                    {
                        weaponBoxes[index].SelectedIndex = i;
                        break;
                    }
                }
            }

            if (armorToEquip != null)
            {
                for (int i = 0; i < armorBoxes[index].Items.Count; i++)
                {
                    if (((DataEquipmentInformation)armorBoxes[index].Items[i]).InstanceId == armorToEquip.InstanceId)
                    {
                        armorBoxes[index].SelectedIndex = i;
                        break;
                    }
                }
            }

            if (accessory != null)
            {
                for (int i = 0; i < accessoryBoxes[index].Items.Count; i++)
                {
                    if (((DataEquipmentInformation)accessoryBoxes[index].Items[i]).InstanceId == accessory.InstanceId)
                    {
                        accessoryBoxes[index].SelectedIndex = i;
                        break;
                    }
                }
            }

            if (recordMateriaToEquip != null)
            {
                for (int i = 0; i < recordMateriaBoxes[index].Items.Count; i++)
                {
                    if (((DataRecordMateriaInformation)recordMateriaBoxes[index].Items[i]).RecordMateriaId == recordMateriaToEquip.RecordMateriaId)
                    {
                        recordMateriaBoxes[index].SelectedIndex = i;
                        break;
                    }
                }
            }
        }