public BullTrait StringMatches(TraitVM trait, string bullVal)
 {
     return new BullTrait
         {
             Trait = trait,
             MatchType = MatchTypeEnum.StringCompare,
             BullValue = bullVal.ToString(CultureInfo.InvariantCulture),
             Qualifies = trait.ExactValue.Equals(bullVal, StringComparison.InvariantCultureIgnoreCase)
         };
 }
 public BullTrait InDecimalRange(TraitVM trait, decimal bullVal)
 {
     return new BullTrait
         {
             Trait = trait,
             MatchType = MatchTypeEnum.InRange,
             BullValue = bullVal.ToString(CultureInfo.InvariantCulture),
             Qualifies =
                 (bullVal >= decimal.Parse(trait.RangeMinValue) && bullVal <= decimal.Parse(trait.RangeMaxValue))
         };
 }
 public BullTrait FeetLegs(TraitVM trait, int front, int hind)
 {
     return new BullTrait
         {
             Trait = trait,
             MatchType = MatchTypeEnum.StringCompare,
             BullValue =
                 front.ToString(CultureInfo.InvariantCulture) + "/" + hind.ToString(CultureInfo.InvariantCulture),
             Qualifies = (
                             ((front >= int.Parse(trait.RangeMinValue)) &&
                              (front <= int.Parse(trait.RangeMaxValue)))
                             &&
                             ((hind >= int.Parse(trait.RangeMinValue)) &&
                              (hind <= int.Parse(trait.RangeMaxValue)))
                         )
         };
 }
 //============================================================================================
 //NOTE:  as of today (Apr 2013) they can only select desired traits for percentiles as
 //  10, 25, or 40   
 // This translates to 90, 75 or 60 
 //============================================================================================
 public BullTrait WithInPercentile(TraitVM trait, StrainPercentiles strainPercentile, decimal bullVal)
 {
     var bt = new BullTrait
         {
             Trait = trait,
             BullValue = bullVal.ToString(CultureInfo.InvariantCulture),
         };
     try
     {
         //int desiredPercentile = int.Parse(trait.ExactValue);
         
         // the desired percentile is stored in the "ExactValue" column
         bool upper = trait.ExactValue.Substring(0, 1) == "T";
         int desiredPercentile = int.Parse(trait.ExactValue.Substring(1));
         switch (desiredPercentile)
         {
             case 10:
                 if (upper)
                 {
                     bt.MatchType = MatchTypeEnum.WithinPercentileTop10;
                     bt.PercentileRangeValue = strainPercentile.Percentiles[90];
                     bt.Qualifies = bullVal >= bt.PercentileRangeValue;
                 }
                 else
                 {
                     bt.MatchType = MatchTypeEnum.WithinPercentileBottom10;
                     bt.PercentileRangeValue = strainPercentile.Percentiles[10];
                     bt.Qualifies = bullVal <= bt.PercentileRangeValue;
                 }
                 break;
             case 25:
                 if (upper)
                 {
                     bt.MatchType = MatchTypeEnum.WithinPercentileTop25;
                     bt.PercentileRangeValue = strainPercentile.Percentiles[75];
                     bt.Qualifies = bullVal >= bt.PercentileRangeValue;
                 }
                 else
                 {
                     bt.MatchType = MatchTypeEnum.WithinPercentileBottom25;
                     bt.PercentileRangeValue = strainPercentile.Percentiles[25];
                     bt.Qualifies = bullVal <= bt.PercentileRangeValue;                           
                 }
                 break;
             case 40:
                 if (upper)
                 {
                     bt.MatchType = MatchTypeEnum.WithinPercentileTop40;
                     bt.PercentileRangeValue = strainPercentile.Percentiles[60];
                     bt.Qualifies = bullVal >= bt.PercentileRangeValue;
                 }
                 else
                 {
                     bt.MatchType = MatchTypeEnum.WithinPercentileBottom40;
                     bt.PercentileRangeValue = strainPercentile.Percentiles[40];
                     bt.Qualifies = bullVal <= bt.PercentileRangeValue;                           
                 }
                 break;
             default:
                 throw new Exception("Desired trait percentile is not one of the calcuated percentiles.");
         }
     }
     catch (KeyNotFoundException)
     {
    
         bt.PercentileRangeValue = 0;
         bt.Qualifies = true;
     }
     return bt;
 }