private GameMetrics CalculateGameMetrics(
            bool isHome,
            NFLGame game,
            DateTime focusDate)
        {
            string teamRatings;
            string oppRatings;

            var gm = new GameMetrics();

            if (isHome)
            {
                oppRatings = RatingsService.GetUnitRatingsFor(
                    game.AwayNflTeam,
                    focusDate);
                teamRatings = RatingsService.GetUnitRatingsFor(
                    game.HomeNflTeam,
                    focusDate);
                //  pump up the defence ratings if its divisional game
                if (game.IsDivisionalGame())
                {
                    teamRatings = PumpIt(
                        teamRatings);
                }
                game.AwayNflTeam.Ratings = oppRatings;
                game.HomeNflTeam.Ratings = teamRatings;
            }
            else
            {
                teamRatings = RatingsService.GetUnitRatingsFor(
                    game.AwayNflTeam,
                    focusDate);
                oppRatings = RatingsService.GetUnitRatingsFor(
                    game.HomeNflTeam,
                    focusDate);
                //  pump up the defence ratings if its divisional game
                if (game.IsDivisionalGame())
                {
                    oppRatings = PumpIt(
                        oppRatings);
                }
                game.HomeNflTeam.Ratings = oppRatings;
                game.AwayNflTeam.Ratings = teamRatings;
            }

            var score = 0;

            if (string.IsNullOrEmpty(teamRatings) ||
                string.IsNullOrEmpty(oppRatings))
            {
                Announce("Ratings not found - skipping score calculation");
            }
            else
            {
                //  Part 0 - Calculate field goals
                var fg = isHome ? 2 : 1;
                if (game.IsDomeGame())
                {
                    fg++;
                }
                else
                {
                    if (game.IsBadWeather())
                    {
                        fg--;
                    }
                }

                //  Part 1 - Calculate Tdp
                var po  = teamRatings.Substring(0, 1);
                var pd  = oppRatings.Substring(5, 1);
                var tdp = TouchdownPasses(po, pd);
                var ydp = YardsPassing(po, pd);
                gm.TDp = tdp;
                gm.YDp = ydp;

                //  Part 2 - Adjust for protection
                var pp  = teamRatings.Substring(2, 1);
                var pr  = oppRatings.Substring(3, 1);
                var ppr = ProtectionAdjustment(pp, pr);

                tdp += ppr;
                if (tdp < 0)
                {
                    tdp = 0;
                }

                //  Part 3 - Calculate Tdr
                var ro  = teamRatings.Substring(1, 1);
                var rd  = oppRatings.Substring(4, 1);
                var tdr = TouchdownRuns(ro, rd);
                var ydr = YardsRushing(ro, rd);
                gm.TDp = tdp;
                gm.TDr = tdr;
                gm.YDr = ydr;

                var tdd = DefensiveScores(
                    game.IsDivisionalGame(),
                    isHome);

                var tds = SpecialTeamScores(
                    game.IsMondayNight(),
                    isHome);

                gm.TDd = tdd;
                gm.TDs = tds;
                gm.FG  = fg;

                //TODO:  Short week adjustment
                //TODO:  Opponent had Route last game adjustment
                //TODO:  Revenge adjustment

                // Total up all the parts of a score
                score = (tdp + tdr + tdd + tds) * 7 + (fg * 3);

                DumpCalculations(
                    isHome,
                    game,
                    tdr,
                    pr,
                    pp,
                    ro,
                    tds,
                    tdd,
                    rd,
                    oppRatings,
                    teamRatings,
                    ppr,
                    tdp,
                    score,
                    pd,
                    po,
                    fg);

                if (isHome)
                {
                    _homeTDp = tdp;
                    _homeTDr = tdr;
                    _homeFg  = fg;
                    _homeTDd = tdd;
                    _homeTDs = tds;
                    _homeYDr = ydr;
                    _homeYDp = ydp;
                }
                else
                {
                    _awayTDp = tdp;
                    _awayTDr = tdr;
                    _awayFg  = fg;
                    _awayTDd = tdd;
                    _awayTDs = tds;
                    _awayYDr = ydr;
                    _awayYDp = ydp;
                }
            }
            gm.Score = score;
            return(gm);
        }
        private GameMetrics CalculateGameMetrics( bool isHome, NFLGame game, DateTime focusDate )
        {
            string teamRatings;
            string oppRatings;

            var gm = new GameMetrics();

            if ( isHome )
            {
                oppRatings = RatingsService.GetUnitRatingsFor( game.AwayNflTeam, focusDate );
                teamRatings = RatingsService.GetUnitRatingsFor( game.HomeNflTeam, focusDate );
                game.AwayNflTeam.Ratings = oppRatings;
                game.HomeNflTeam.Ratings = teamRatings;
            }
            else
            {
                teamRatings = RatingsService.GetUnitRatingsFor( game.AwayNflTeam, focusDate );
                oppRatings = RatingsService.GetUnitRatingsFor( game.HomeNflTeam, focusDate );
                game.HomeNflTeam.Ratings = oppRatings;
                game.AwayNflTeam.Ratings = teamRatings;
            }

            var score = 0;
            if ( string.IsNullOrEmpty( teamRatings ) || string.IsNullOrEmpty( oppRatings ))
                Utility.Announce( "Ratings not found - skipping score calculation" );
            else
            {
                var fg = isHome ? 2 : 1;
                if (game.IsDomeGame())
                    fg++;
                else
                {
                    if (game.IsBadWeather())
                        fg--;
                }

                //  Part 1 - Calculate Tdp
                var po = teamRatings.Substring( 0, 1 );
                var pd = oppRatings.Substring( 5, 1 );
                var tdp = TouchdownPasses( po, pd );
                var ydp = YardsPassing( po, pd );
                gm.TDp = tdp;
                gm.YDp = ydp;

                //  Part 2 - Adjust for protection
                var pp = teamRatings.Substring( 2, 1 );
                var pr = oppRatings.Substring( 3, 1 );
                var ppr = ProtectionAdjustment( pp, pr );

                tdp += ppr;
                if ( tdp < 0 ) tdp = 0;

                //  Part 3 - Calculate Tdr
                var ro = teamRatings.Substring( 1, 1 );
                var rd = oppRatings.Substring( 4, 1 );
                var tdr = TouchdownRuns( ro, rd );
                var ydr = YardsRushing( ro, rd );
                gm.TDp = tdp;
                gm.TDr = tdr;
                gm.YDr = ydr;

                var tdd = DefensiveScores(game.IsDivisionalGame(), isHome);

                var tds = SpecialTeamScores(game.IsMondayNight(), isHome);

                gm.TDd = tdd;
                gm.TDs = tds;
                gm.FG = fg;

                //TODO:  Short week adjustment
                //TODO:  Opponent had Route last game adjustment
                //TODO:  Revenge adjustment

                // Total up all the parts of a score
                score = ( tdp + tdr + tdd + tds )*7 + (fg * 3);

                DumpCalculations( isHome, game, tdr, pr, pp, ro, tds, tdd, rd, oppRatings,
                    teamRatings, ppr, tdp, score, pd, po, fg);

                if ( isHome )
                {
                    _homeTDp = tdp;
                    _homeTDr = tdr;
                    _homeFg = fg;
                    _homeTDd = tdd;
                    _homeTDs = tds;
                    _homeYDr = ydr;
                    _homeYDp = ydp;
                }
                else
                {
                    _awayTDp = tdp;
                    _awayTDr = tdr;
                    _awayFg = fg;
                    _awayTDd = tdd;
                    _awayTDs = tds;
                    _awayYDr = ydr;
                    _awayYDp = ydp;
                }
            }
            gm.Score = score;
            return gm;
        }