public WINTER_2012_SwimTimeRuleProcessor(IList <ISwimTimeRule> theRules)
        {
            if (theRules == null)
            {
                throw new ArgumentException("Cannot have a null list of rules");
            }

            this.ruleBucketTree = new List <SwimTimeRuleBucket>();

            IList <ISwimTimeRule> rulesDecomposedIntoDiscreteTimePeriods = new List <ISwimTimeRule>();

            foreach (ISwimTimeRule aRule in theRules)
            {
                if (Math.Sqrt(aRule.GetRuleRepeatabilityPeriodInHours() * aRule.GetRuleRepeatabilityPeriodInHours()) <= 1.0 / 60.0)//Rules less than 1 minute in repeatability are considered constant rules
                {
                    rulesDecomposedIntoDiscreteTimePeriods.Add(aRule);
                }
                else//repeated rule, so explcitly make it a concrete one
                {
                    DateTime            startDate;//When the rule starts
                    DateTime            endDate; //When the rule ends
                    DateTime            repDate; //The "zero" date; the repition period "hops" forwards from this date.
                    double              repPeriod;
                    ISwimTimeRule       temp;
                    ApplicableMinAndMax ruleMinAndMax = aRule.GetMinAndMaxHours();

                    startDate = aRule.GetAbsoluteStartingDate();
                    endDate   = aRule.GetAbsoluteEndingDate();
                    repDate   = aRule.GetRuleStartDate();
                    repPeriod = aRule.GetRuleRepeatabilityPeriodInHours();

                    DateTime hopDate = repDate;
                    while (hopDate < startDate)//The hop date could be "funky"; move it forward until it is inside the time period we care about.
                    {
                        hopDate = hopDate.Add(TimeSpan.FromHours(repPeriod));
                    }
                    DateTime currentConcreteRuleStartDate = startDate;
                    DateTime currentConcreteRuleEndDate   = (hopDate < endDate) ? hopDate : endDate;

                    while (currentConcreteRuleStartDate < endDate)
                    {
                        temp = SwimTimeRuleFactory.CreateSwimTimeRule(ruleMinAndMax.GetMinimumVisitLengthInHoursThatCounts(), ruleMinAndMax.GetMaximumHoursAllowedInThisTimePeriod(), currentConcreteRuleStartDate, currentConcreteRuleEndDate);
                        rulesDecomposedIntoDiscreteTimePeriods.Add(temp);

                        //Now move forward one repition period
                        currentConcreteRuleStartDate = currentConcreteRuleEndDate;
                        hopDate = hopDate.Add(TimeSpan.FromHours(repPeriod));
                        currentConcreteRuleEndDate = (hopDate < endDate) ? hopDate : endDate;
                    }
                }
            }

            SwimTimeRuleBucket tempBucket;

            foreach (ISwimTimeRule decoRules in rulesDecomposedIntoDiscreteTimePeriods)
            {
                tempBucket = new SwimTimeRuleBucket(decoRules);
                ruleBucketTree.Add(tempBucket);
            }
        }
 private bool RuleAppliesToThisVisit(DateTime startTime, SwimTimeRuleBucket ctrb)
 {
     return(startTime >= ctrb.GetStartDate() && startTime <= ctrb.GetEndDate());
 }