/// <summary>
        /// Builds a dictionary containing the values to display for each of the calculations defined in
        /// CharacterDisplayCalculationLabels. The key should be the Label of each display calculation,
        /// and the value should be the value to display, optionally appended with '*' followed by any
        /// string you'd like displayed as a tooltip on the value.
        /// </summary>
        /// <returns>A Dictionary<string, string> containing the values to display for each of the
        /// calculations defined in CharacterDisplayCalculationLabels.</returns>
        public override Dictionary <string, string> GetCharacterDisplayCalculationValues()
        {
            Dictionary <string, string> dictValues = new Dictionary <string, string>();

            #region Simulation stats
            dictValues.Add("Rotation", String.Format("{0}*{1}", Name, Abilities));
            dictValues.Add("Warlock DPS", String.Format("{0:0}", DpsPoints));
            dictValues.Add("Pet DPS", String.Format("{0:0}", PetDPSPoints));
            dictValues.Add("Total DPS", String.Format("{0:0}", OverallPoints));
            dictValues.Add("Damage Done", String.Format("{0:0}", OverallDamage));
            dictValues.Add("Mana Used", String.Format("{0:0}", TotalManaCost));
            #endregion

            #region HP/Mana stats
            dictValues.Add("Health", String.Format("{0:0}", TotalStats.Health));
            dictValues.Add("Mana", String.Format("{0:0}", TotalStats.Mana));
            #endregion

            #region Base stats
            dictValues.Add("Strength", String.Format("{0}", TotalStats.Strength));
            dictValues.Add("Agility", String.Format("{0}", TotalStats.Agility));
            dictValues.Add("Stamina", String.Format("{0}", TotalStats.Stamina));
            dictValues.Add("Intellect", String.Format("{0}", TotalStats.Intellect));
            dictValues.Add("Spirit", String.Format("{0}", TotalStats.Spirit));
            dictValues.Add("Armor", String.Format("{0}", TotalStats.Armor));
            #endregion

            #region Pet stats
            Minion minion = MinionFactory.CreateMinion(Options.Pet, Character, TotalStats);
            if (minion != null)
            {
                dictValues.Add("Pet Strength", String.Format("{0}", minion.Strength()));
                dictValues.Add("Pet Agility", String.Format("{0}", minion.Agility()));
                dictValues.Add("Pet Stamina", String.Format("{0:0}", minion.Stamina()));
                dictValues.Add("Pet Intellect", String.Format("{0:0}", minion.Intellect()));
                dictValues.Add("Pet Spirit", String.Format("{0}", minion.Spirit()));
                dictValues.Add("Pet Armor", String.Format("{0}", minion.Armor()));
            }
            #endregion

            #region Spell stats
            //pet scaling consts: http://www.wowwiki.com/Warlock_minions
            const float petInheritedAttackPowerPercentage = 0.57f;
            const float petInheritedSpellPowerPercentage  = 0.15f;

            dictValues.Add("Bonus Damage", String.Format("{0}*Shadow Damage\t{1}\r\nFire Damage\t{2}\r\n\r\nYour Fire Damage increases your pet's Attack Power by {3} and Spell Damage by {4}.",
                                                         TotalStats.SpellPower,
                                                         TotalStats.SpellPower + TotalStats.SpellShadowDamageRating,
                                                         TotalStats.SpellPower + TotalStats.SpellFireDamageRating,
                                                         Math.Round((TotalStats.SpellPower + TotalStats.SpellFireDamageRating) * petInheritedAttackPowerPercentage, 0),
                                                         Math.Round((TotalStats.SpellPower + TotalStats.SpellFireDamageRating) * petInheritedSpellPowerPercentage, 0)
                                                         ));

            #region Hit / Miss chance
            //float bonusHit = TotalStats.SpellHit;
            float onePercentOfHitRating = (1 / StatConversion.GetSpellHitFromRating(1));
            float hitFromRating         = StatConversion.GetSpellHitFromRating(TotalStats.HitRating);
            float hitFromTalents        = (Character.WarlockTalents.Suppression * 0.01f);
            float hitFromBuffs          = (TotalStats.SpellHit - hitFromRating - hitFromTalents);
            float targetHit             = (Options.TargetHit / 100f);
            float totalHit   = (targetHit + TotalStats.SpellHit);
            float missChance = (totalHit > 1 ? 0 : (1 - totalHit));

            //calculate the amount of hit rating that is over or under the cap
            float hitDelta = (totalHit > 1)
                                 ? (float)Math.Floor((totalHit - 1) * onePercentOfHitRating)
                                 : (float)Math.Ceiling((1 - totalHit) * onePercentOfHitRating);
            //now we can calculate the hitcap value
            float hitCap = (totalHit > 1)
                               ? TotalStats.HitRating - hitDelta
                               : TotalStats.HitRating + hitDelta;

            dictValues.Add("Hit Rating", String.Format("{0}*{1:0.00%} Hit Chance (max 100%) | {2:0.00%} Miss Chance \r\n\r\n"
                                                       + "{3:0.00%}\t Base Hit Chance on a Level {4:0} target\r\n"
                                                       + "{5:0.00%}\t from {6:0} Hit Rating [gear, food and/or flasks]\r\n"
                                                       + "{7:0.00%}\t from Talent: Suppression\r\n"
                                                       + "{8:0.00%}\t from Buffs: Racial and/or Spell Hit Chance Taken\r\n\r\n"
                                                       + "{9}\r\n\r\n"
                                                       + "Hit Rating caps:\r\n"
                                                       + "446 - hard cap (no hit from talents, gear or buffs)\r\n"
                                                       + "420 - Heroic Presence\r\n"
                                                       + "368 - Suppression\r\n"
                                                       + "342 - Suppression and Heroic Presence\r\n"
                                                       + "289 - Suppression, Improved Faerie Fire / Misery\r\n"
                                                       + "263 - Suppression, Improved Faerie Fire / Misery and Heroic Presence",
                                                       TotalStats.HitRating, totalHit, missChance,
                                                       targetHit, Options.TargetLevel,
                                                       hitFromRating, TotalStats.HitRating,
                                                       hitFromTalents,
                                                       hitFromBuffs,
                                                       String.Format("You are {0} hit rating {1} the {2} cap.", hitDelta, ((totalHit > 1) ? "above" : "below"), hitCap)
                                                       ));

            dictValues.Add("Miss chance", String.Format("{0:0.00%}", missChance));
            #endregion

            #region Crit %
            Stats statsBase         = BaseStats.GetBaseStats(Character);
            float critFromRating    = StatConversion.GetSpellCritFromRating(TotalStats.CritRating);
            float critFromIntellect = StatConversion.GetSpellCritFromIntellect(TotalStats.Intellect);
            float critFromBuffs     = TotalStats.SpellCrit - statsBase.SpellCrit - critFromRating - critFromIntellect
                                      - (Character.WarlockTalents.DemonicTactics * 0.02f)
                                      - (Character.WarlockTalents.Backlash * 0.01f);

            dictValues.Add("Crit Chance", String.Format("{0:0.00%}*"
                                                        + "{1:0.00%}\tfrom {2:0} Spell Crit rating\r\n"
                                                        + "{3:0.00%}\tfrom {4:0} Intellect\r\n"
                                                        + "{5:0.000%}\tfrom Warlock Class Bonus\r\n"
                                                        + "{6:0%}\tfrom Talent: Demonic Tactics\r\n"
                                                        + "{7:0%}\tfrom Talent: Backlash\r\n"
                                                        + "{8:0%}\tfrom Buffs",
                                                        TotalStats.SpellCrit,
                                                        critFromRating, TotalStats.CritRating,
                                                        critFromIntellect, TotalStats.Intellect,
                                                        statsBase.SpellCrit,
                                                        (Character.WarlockTalents.DemonicTactics * 0.02f),
                                                        (Character.WarlockTalents.Backlash * 0.01f),
                                                        critFromBuffs
                                                        ));
            #endregion

            dictValues.Add("Haste Rating", String.Format("{0}%*{1}%\tfrom {2} Haste rating\r\n{3}%\tfrom Buffs\r\n{4}s\tGlobal Cooldown",
                                                         (TotalStats.SpellHaste * 100f).ToString("0.00"),
                                                         (StatConversion.GetSpellHasteFromRating(TotalStats.HasteRating) * 100f).ToString("0.00"),
                                                         TotalStats.HasteRating,
                                                         (TotalStats.SpellHaste * 100f - StatConversion.GetSpellHasteFromRating(TotalStats.HasteRating) * 100f).ToString("0.00"),
                                                         Math.Max(1.0f, 1.5f / (1 + TotalStats.SpellHaste)).ToString("0.00")));

            dictValues.Add("Mana Regen", String.Format("{0}*{0} mana regenerated every 5 seconds while not casting\r\n{1} mana regenerated every 5 seconds while casting",
                                                       GetManaRegenOutOfCombat(),
                                                       GetManaRegenInCombat()));
            #endregion

            #region Shadow school
            dictValues.Add("Shadow Bolt", new ShadowBolt(TotalStats, Character, Options).ToString());
            if (Character.WarlockTalents.Haunt > 0)
            {
                dictValues.Add("Haunt", new Haunt(TotalStats, Character, Options).ToString());
            }
            else
            {
                dictValues.Add("Haunt", "- *Required talent not available");
            }
            dictValues.Add("Corruption", new Corruption(TotalStats, Character, Options).ToString());
            dictValues.Add("Curse of Agony", new CurseOfAgony(TotalStats, Character, Options).ToString());
            dictValues.Add("Curse of Doom", new CurseOfDoom(TotalStats, Character, Options).ToString());
            if (Character.WarlockTalents.UnstableAffliction > 0)
            {
                dictValues.Add("Unstable Affliction", new UnstableAffliction(TotalStats, Character, Options).ToString());
            }
            else
            {
                dictValues.Add("Unstable Affliction", "- *Required talent not available");
            }
            dictValues.Add("Death Coil", new DeathCoil(TotalStats, Character, Options).ToString());
            dictValues.Add("Drain Life", new DrainLife(TotalStats, Character, Options).ToString());
            dictValues.Add("Drain Soul", new DrainSoul(TotalStats, Character, Options).ToString());
            dictValues.Add("Seed of Corruption", new SeedOfCorruption(TotalStats, Character, Options).ToString());
            dictValues.Add("Shadowflame", new Shadowflame(TotalStats, Character, Options).ToString());
            if (Character.WarlockTalents.Shadowburn > 0)
            {
                dictValues.Add("Shadowburn", new Shadowburn(TotalStats, Character, Options).ToString());
            }
            else
            {
                dictValues.Add("Shadowburn", "- *Required talent not available");
            }
            if (Character.WarlockTalents.Shadowfury > 0)
            {
                dictValues.Add("Shadowfury", new Shadowfury(TotalStats, Character, Options).ToString());
            }
            else
            {
                dictValues.Add("Shadowfury", "- *Required talent not available");
            }
            dictValues.Add("Life Tap", new LifeTap(TotalStats, Character, Options).ToString());
            if (Character.WarlockTalents.DarkPact > 0)
            {
                dictValues.Add("Dark Pact", new DarkPact(TotalStats, Character, Options).ToString());
            }
            else
            {
                dictValues.Add("Dark Pact", "- *Required talent not available");
            }

            #endregion

            #region Fire school
            dictValues.Add("Incinerate", new Incinerate(TotalStats, Character, Options).ToString());
            dictValues.Add("Immolate", new Immolate(TotalStats, Character, Options).ToString());
            if (Character.WarlockTalents.Conflagrate > 0)
            {
                dictValues.Add("Conflagrate", new Conflagrate(TotalStats, Character, Options).ToString());
            }
            else
            {
                dictValues.Add("Conflagrate", "- *Required talent not available");
            }
            if (Character.WarlockTalents.ChaosBolt > 0)
            {
                dictValues.Add("Chaos Bolt", new ChaosBolt(TotalStats, Character, Options).ToString());
            }
            else
            {
                dictValues.Add("Chaos Bolt", "- *Required talent not available");
            }
            dictValues.Add("Rain of Fire", new RainOfFire(TotalStats, Character, Options).ToString());
            dictValues.Add("Hellfire", new Hellfire(TotalStats, Character, Options).ToString());

            if (Character.WarlockTalents.Metamorphosis > 0)
            {
                dictValues.Add("Immolation Aura", new ImmolationAura(TotalStats, Character, Options).ToString());
            }
            else
            {
                dictValues.Add("Immolation Aura", "- *Required talent not available");
            }

            dictValues.Add("Searing Pain", new SearingPain(TotalStats, Character, Options).ToString());
            dictValues.Add("Soul Fire", new SoulFire(TotalStats, Character, Options).ToString());
            #endregion

            return(dictValues);
        }