// Draws a report picture for each Match Player
        public byte[] DrawPlayerReport(DotaMatch match, MatchPlayers player)
        {
            var playerTeam = (player.team == 0) ? "Radiant" : "Dire";
            var winState   = ((playerTeam == match.winner) ? "Winner" : "Loser");

            byte[] playerReportData = null;
            // 306:234 is split pane point
            using (var playerReport = Image.Load(this.assembly.GetManifestResourceStream($"OpenDotaApi.ref.assets.{playerTeam}.png")))
            {
                playerReport.Mutate
                (
                    (imgContext) =>
                {
                    // Background Color
                    // imgContext.Fill(Rgba32.Black);
                    Image <Rgba32> boxBorder;

                    // Drawing Pointers
                    var x = 0;
                    var y = 0;

                    // Draw Player Text
                    x = 20;
                    y = 20;
                    imgContext.DrawText(
                        leftText,
                        ((player.playerName != null) ? (player.playerName) : ""),
                        verdanaTinyBold,
                        Rgba32.White,
                        new PointF(x, y)
                        );
                    x = 286;
                    imgContext.DrawText(
                        rightText,
                        $"{playerTeam} ({winState})",
                        verdanaTiny,
                        Rgba32.LightGray,
                        new PointF(x, y)
                        );

                    // Draw Hero Image
                    x         = 24;
                    y         = 56;
                    boxBorder = new Image <Rgba32>(270, 154);
                    boxBorder.Mutate(img => img.Fill(Rgba32.DarkSlateGray));
                    imgContext.DrawImage(
                        boxBorder,
                        1,
                        new Point((int)x - 2, (int)y - 2)
                        );
                    Image <Rgba32> heroImage = null;
                    var heroImagePath        = $@"./imgcache/heroes/{player.hero.id}.png";
                    if (File.Exists(heroImagePath))
                    {
                        heroImage = Image.Load(heroImagePath);
                        heroImage.Mutate(img => img.Resize(266, 150));
                    }
                    else
                    {
                        heroImage = new Image <Rgba32>(266, 150);
                        heroImage.Mutate(img => img.Fill(new Rgba32(32, 32, 32)));
                    }
                    imgContext.DrawImage(
                        heroImage,
                        1,
                        new Point(x, y)
                        );

                    // Draw Player Hero Name
                    x = 153;
                    y = 226;
                    imgContext.DrawText(
                        centerText,
                        $"{player.hero.name}",
                        verdana,
                        Rgba32.White,
                        new PointF(x, y)
                        );

                    // Draw Player Stats
                    y = 262;
                    imgContext.DrawText(
                        centerText,
                        player.netWorth.ToString(),
                        verdanaBigBold,
                        Rgba32.White,
                        new PointF(x, y)
                        );
                    y = 306;
                    imgContext.DrawText(
                        centerText,
                        $@"KDA {player.kills} / {player.deaths} / {player.assists}",
                        verdana,
                        Rgba32.White,
                        new PointF(x, y)
                        );

                    // Draw Player Items
                    x         = 20;
                    y         = 346;
                    boxBorder = new Image <Rgba32>(266, 136);
                    boxBorder.Mutate(img => img.Fill(new Rgba32(64, 64, 64)));
                    imgContext.DrawImage(
                        boxBorder,
                        1,
                        new Point((int)x, (int)y)
                        );
                    for (var j = 0; j < 6; j++)
                    {
                        var item = player.items[j];
                        Image <Rgba32> itemImage = null;
                        string itemImagePath;
                        if (item != null)
                        {
                            itemImagePath = $@"./imgcache/items/{item.id}.png";
                            if (!File.Exists(itemImagePath))
                            {
                                itemImage = new Image <Rgba32>(86, 65);
                                itemImage.Mutate(img => img.Fill(Rgba32.DarkSlateGray));
                            }
                            else
                            {
                                itemImage = Image.Load(itemImagePath);
                                itemImage.Mutate(img => img.Resize(86, 65));
                            }
                        }
                        else
                        {
                            itemImage = new Image <Rgba32>(86, 65);
                            itemImage.Mutate(img => img.Fill(new Rgba32(32, 32, 32)));
                        }
                        imgContext.DrawImage(
                            itemImage,
                            1,
                            new Point((int)x + 2 + 88 * (j % 3), (int)y + 2 + 67 * (j / 3))
                            );
                    }
                    // Draw Backpack Items
                    x         = 53;
                    y         = 480;
                    boxBorder = new Image <Rgba32>(194, 49);
                    boxBorder.Mutate(img => img.Fill(new Rgba32(48, 48, 48)));
                    imgContext.DrawImage(
                        boxBorder,
                        1,
                        new Point((int)x, (int)y + 2)
                        );
                    for (var j = 0; j < 3; j++)
                    {
                        var item = player.items[j + 6];
                        Image <Rgba32> itemImage = null;
                        string itemImagePath;
                        if (item != null)
                        {
                            itemImagePath = $@"./imgcache/items/{item.id}.png";
                            if (!File.Exists(itemImagePath))
                            {
                                itemImage = new Image <Rgba32>(62, 47);
                                itemImage.Mutate(img => img.Fill(new Rgba32(20, 20, 20)));
                            }
                            else
                            {
                                itemImage = Image.Load(itemImagePath);
                                itemImage.Mutate(img => img.Resize(62, 47));
                            }
                        }
                        else
                        {
                            itemImage = new Image <Rgba32>(62, 47);
                            itemImage.Mutate(img => img.Fill(new Rgba32(20, 20, 20)));
                        }
                        imgContext.DrawImage(
                            itemImage,
                            1,
                            new Point((int)x + 2 + 64 * (j % 3), (int)y + 2)
                            );
                    }

                    // Draw Permanent Buffs
                    x = 153;
                    y = 551;
                    imgContext.DrawText(
                        centerText,
                        "PERMANENT BUFFS",
                        verdanaTinyBold,
                        Rgba32.LightGray,
                        new PointF(x, y)
                        );
                    if (player.permanentBuffs != null)
                    {
                        x = 20;
                        y = 580;
                        for (var j = 0; j < player.permanentBuffs.Length; j++)
                        {
                            var buff = player.permanentBuffs[j];
                            Image <Rgba32> buffImage = null;
                            string buffImagePath;
                            if (buff.buff.orgin == "Item")
                            {
                                buffImagePath = $@"./imgcache/items/{buff.buff.originId}.png";
                            }
                            else
                            {
                                buffImagePath = $@"./imgcache/abilities/{buff.buff.originId}.png";
                            }
                            if (!File.Exists(buffImagePath))
                            {
                                buffImage = new Image <Rgba32>(42, 42);
                                buffImage.Mutate(img => img.Fill(new Rgba32(32, 32, 32)));
                            }
                            else
                            {
                                buffImage = Image.Load(buffImagePath);
                                buffImage.Mutate(img => img.Crop(buffImage.Height, buffImage.Height).Resize(42, 42).Fill(new Rgba32(255, 255, 255, 64)));
                            }
                            var imgx  = x + 3 + 44 * (j % 6);
                            boxBorder = new Image <Rgba32>(44, 44);
                            boxBorder.Mutate(img => img.Fill(Rgba32.Gold));
                            imgContext.DrawImage(
                                boxBorder,
                                1,
                                new Point((int)imgx - 1, (int)y - 1)
                                );
                            imgContext.DrawImage(
                                buffImage,
                                1,
                                new Point((int)imgx, (int)y)
                                );
                            imgContext.DrawText(
                                centerMiddleText,
                                buff.value.ToString(),
                                verdanaTinyBold,
                                Rgba32.Black,
                                new Point((int)imgx + 21, (int)y + 21)
                                );
                        }
                    }
                    else
                    {
                        y = 580;
                        imgContext.DrawText(
                            centerMiddleText,
                            "---",
                            verdanaTinyBold,
                            Rgba32.White,
                            new Point((int)x, (int)y)
                            );
                    }

                    // Draw a Line through the Middle
                    x = 306;
                    imgContext.DrawLines(Rgba32.LightGray, 0.5f, new PointF[] { new PointF(x, 20), new PointF(x, 624) });

                    // Draw More Player Stats
                    x      = 326;
                    var x2 = 520;
                    y      = 34;
                    imgContext.DrawText(
                        leftMiddleText,
                        "LEVEL",
                        verdanaTinyBold,
                        Rgba32.LightGray,
                        new PointF(x, y)
                        );
                    imgContext.DrawText(
                        rightMiddleText,
                        $"{player.level}",
                        verdanaTinyBold,
                        Rgba32.White,
                        new PointF(x2, y)
                        );
                    y = 60;
                    imgContext.DrawLines(Rgba32.LightGray, 0.5f, new PointF[] { new PointF(x, y), new PointF(x2, y) });
                    y = 80;
                    imgContext.DrawText(
                        leftMiddleText,
                        "LAST HITS",
                        verdanaTinyBold,
                        Rgba32.LightGray,
                        new PointF(x, y)
                        );
                    imgContext.DrawText(
                        rightMiddleText,
                        $"{player.lastHits}",
                        verdanaTinyBold,
                        Rgba32.White,
                        new PointF(x2, y)
                        );
                    y = 108;
                    imgContext.DrawText(
                        leftMiddleText,
                        "DENIES",
                        verdanaTinyBold,
                        Rgba32.LightGray,
                        new PointF(x, y)
                        );
                    imgContext.DrawText(
                        rightMiddleText,
                        $"{player.denies}",
                        verdanaTinyBold,
                        Rgba32.White,
                        new PointF(x2, y)
                        );
                    y = 134;
                    imgContext.DrawLines(Rgba32.LightGray, 0.5f, new PointF[] { new PointF(x, y), new PointF(x2, y) });
                    y = 154;
                    imgContext.DrawText(
                        leftMiddleText,
                        "GOLD PER MINUTE",
                        verdanaTinyBold,
                        Rgba32.LightGray,
                        new PointF(x, y)
                        );
                    imgContext.DrawText(
                        rightMiddleText,
                        $"{player.goldPerMinute}\n",
                        verdanaTinyBold,
                        Rgba32.White,
                        new PointF(x2, y)
                        );
                    y = 182;
                    imgContext.DrawText(
                        leftMiddleText,
                        "XP PER MINUTE",
                        verdanaTinyBold,
                        Rgba32.LightGray,
                        new PointF(x, y)
                        );
                    imgContext.DrawText(
                        rightMiddleText,
                        $"{player.experiencePerMinute}",
                        verdanaTinyBold,
                        Rgba32.White,
                        new PointF(x2, y)
                        );
                    y = 208;
                    imgContext.DrawLines(Rgba32.LightGray, 0.5f, new PointF[] { new PointF(x, y), new PointF(x2, y) });
                    y = 228;
                    imgContext.DrawText(
                        leftMiddleText,
                        "HERO DAMAGE",
                        verdanaTinyBold,
                        Rgba32.LightGray,
                        new PointF(x, y)
                        );
                    imgContext.DrawText(
                        rightMiddleText,
                        $"{player.heroDamage}",
                        verdanaTinyBold,
                        Rgba32.White,
                        new PointF(x2, y)
                        );
                    y = 256;
                    imgContext.DrawText(
                        leftMiddleText,
                        "TOWER DAMAGE",
                        verdanaTinyBold,
                        Rgba32.LightGray,
                        new PointF(x, y)
                        );
                    imgContext.DrawText(
                        rightMiddleText,
                        $"{player.towerDamage}",
                        verdanaTinyBold,
                        Rgba32.White,
                        new PointF(x2, y)
                        );
                    y = 284;
                    imgContext.DrawText(
                        leftMiddleText,
                        "HERO HEAL",
                        verdanaTinyBold,
                        Rgba32.LightGray,
                        new PointF(x, y)
                        );
                    imgContext.DrawText(
                        rightMiddleText,
                        $"{player.heroHealing}",
                        verdanaTinyBold,
                        Rgba32.White,
                        new PointF(x2, y)
                        );

                    // Draw Skill Build
                    y = 310;
                    imgContext.DrawLines(Rgba32.LightGray, 0.5f, new PointF[] { new PointF(x, y), new PointF(x2, y) });
                    x = 423;
                    y = 332;
                    imgContext.DrawText(
                        centerMiddleText,
                        "SKILL BUILD",
                        verdanaTinyBold,
                        Rgba32.LightGray,
                        new PointF(x, y)
                        );
                    x = 326;
                    y = 360;
                    var skillLevel   = 0;
                    var talentNumber = 0;
                    for (var j = 0; j < player.skillBuild.Length; j++)
                    {
                        var skill = player.skillBuild[j];
                        var imgx  = x + 2 + 32 * (j % 6);
                        var imgy  = y + 2 + 64 * (j / 6);
                        boxBorder = new Image <Rgba32>(34, 34);
                        boxBorder.Mutate(img => img.Fill(new Rgba32(48, 48, 48)));
                        imgContext.DrawImage(
                            boxBorder,
                            1,
                            new Point((int)imgx - 2, (int)imgy - 2)
                            );
                        Image <Rgba32> skillImage = null;
                        if (skill.codeName == "talent")
                        {
                            if (skillLevel < (9 + talentNumber * 5))
                            {
                                skillLevel = 9 + talentNumber * 5;
                            }
                            skillImage = Image.Load(this.assembly.GetManifestResourceStream($"OpenDotaApi.ref.assets.Talent.png"));
                            skillImage.Mutate(img => img.Resize(30, 30));
                            talentNumber++;
                        }
                        else
                        {
                            string skillImagePath = $@"./imgcache/abilities/{skill.id}.png";
                            if (!File.Exists(skillImagePath))
                            {
                                skillImage = new Image <Rgba32>(30, 30);
                                skillImage.Mutate(img => img.Fill(new Rgba32(20, 20, 20)));
                            }
                            else
                            {
                                skillImage = Image.Load(skillImagePath);
                                skillImage.Mutate(img => img.Resize(30, 30));
                            }
                        }
                        imgContext.DrawImage(
                            skillImage,
                            1,
                            new Point((int)imgx, (int)imgy)
                            );
                        imgContext.DrawText(
                            centerText,
                            (skillLevel + 1).ToString(),
                            verdanaTinyBold,
                            Rgba32.White,
                            new Point((int)imgx + 16, (int)imgy + 34)
                            );
                        if (skillLevel < 25)
                        {
                            skillLevel++;
                        }
                    }
                    using (MemoryStream memoryStream = new MemoryStream())
                    {
                        playerReport.SaveAsPng(memoryStream);
                        playerReportData = memoryStream.ToArray();
                    }
                }
                );
            }
            return(playerReportData);
        }
 public byte[] DrawPlayerReport(DotaMatch match, MatchPlayers player)
 {
     return(this.drawer.DrawPlayerReport(match, player));
 }