/// <summary>
        /// Initializes a new instance of the <see cref="T:Core.Domain.Items.Armor.Paizo.CoreRulebook.ScaleMail"/> class.
        /// </summary>
        /// <param name="size">The size of the character intended to wear the armor.</param>
        /// <param name="material">The material the chainmail is made from.</param>
        /// <exception cref="System.ComponentModel.InvalidEnumArgumentException">Thrown when an argument is a nonstandard enum.</exception>
        public ScaleMail(SizeCategory size, ScaleMailMaterial material)
            : base(5, GetHardnessForMaterial(material))
        {
            const byte   ARMOR_CHECK_PENALTY = 4;
            const byte   MAX_DEX_BONUS       = 3;
            const double WEIGHT        = 30;
            const double PRICE         = 50;
            const float  SPEED_PENALTY = 0.25f;
            NameFragment standardName  = new NameFragment("Scale Mail", "http://www.d20pfsrd.com/equipment/Armor/scale-mail");

            switch (material)
            {
            case ScaleMailMaterial.Adamantine:
                this.IsMasterwork           = true;
                this.MasterworkIsToggleable = false;
                this.ArmorCheckPenalty      = () => StandardArmorCheckPenaltyCalculation(ARMOR_CHECK_PENALTY);
                this.MaximumDexterityBonus  = () => MAX_DEX_BONUS;
                this.MundaneMarketPrice     = () => Adamantine.GetMediumArmorBaseMarketPrice(MarketValueScaledBySize(size, PRICE));
                this.Weight      = () => WeightScaledBySize(size, WEIGHT);
                this.MundaneName = () => new INameFragment[] {
                    new NameFragment("Adamantine", Adamantine.WebAddress),
                    standardName
                };
                this.SpeedPenalty    = SPEED_PENALTY;
                var(drMag, drBypass) = Adamantine.GetMediumArmorDamageReduction();
                this.OnApplied      += (sender, e) => {
                    e.Character?.DamageReduction?.Add(drMag, drBypass);
                };
                break;

            case ScaleMailMaterial.Mithral:
                this.IsMasterwork           = true;
                this.MasterworkIsToggleable = false;
                this.ArmorCheckPenalty      = () => Mithral.GetArmorCheckPenalty(ARMOR_CHECK_PENALTY);
                this.MaximumDexterityBonus  = () => Mithral.GetArmorMaximumDexterityBonus(MAX_DEX_BONUS);
                this.MundaneMarketPrice     = () => Mithral.GetMediumArmorBaseMarketPrice(MarketValueScaledBySize(size, PRICE));
                this.Weight      = () => Mithral.GetWeight(WeightScaledBySize(size, WEIGHT));
                this.MundaneName = () => new INameFragment[] {
                    new NameFragment("Mithral", Mithral.WebAddress),
                    standardName
                };
                this.SpeedPenalty = 0;
                break;

            case ScaleMailMaterial.Steel:
                this.ArmorCheckPenalty     = () => StandardArmorCheckPenaltyCalculation(ARMOR_CHECK_PENALTY);
                this.MaximumDexterityBonus = () => MAX_DEX_BONUS;
                this.MundaneMarketPrice    = () => StandardMundaneMarketPriceCalculation(MarketValueScaledBySize(size, PRICE));
                this.Weight       = () => WeightScaledBySize(size, WEIGHT);
                this.MundaneName  = () => new INameFragment[] { standardName };
                this.SpeedPenalty = SPEED_PENALTY;
                break;

            default:
                throw new InvalidEnumArgumentException(nameof(material), (int)material, material.GetType());
            }
        }
        private static byte GetHardnessForMaterial(ScaleMailMaterial material)
        {
            switch (material)
            {
            case ScaleMailMaterial.Adamantine: return(Adamantine.Hardness);

            case ScaleMailMaterial.Mithral:       return(Mithral.Hardness);

            case ScaleMailMaterial.Steel:           return(Steel.Hardness);

            default:
                throw new InvalidEnumArgumentException(nameof(material), (int)material, material.GetType());
            }
        }