static void Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine("Please provide path to data text file");
                return;
            }
            string path = args[0];

            Data.Read(path);
            DrawUtils.Init();
            Output.Write(path);
        }
        public Image CreateImage()
        {
            Graphics graphics;
            int      width, height;
            Image    image;

            if (Impossible)
            {
                Image  icon  = flower1.Icon;
                string text1 = "Impossible to test for";
                string text2 = " with 100% certainty";
                graphics = Graphics.FromImage(icon);
                SizeF size1 = graphics.MeasureString(text1, NotPossibleFont);
                SizeF size2 = graphics.MeasureString(text2, NotPossibleFont);
                graphics.Dispose();
                width  = (int)Math.Max(size1.Width, size2.Width) + 4;
                height = (int)size1.Height + (int)NotPossibleFont.Size / 2 + (int)size2.Height + 4;
                Image textImage = new Bitmap(width, height);
                graphics = Graphics.FromImage(textImage);
                graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
                DrawUtils.DrawStringWithBorder(graphics, text1, NotPossibleFont, NotPossibleBrush, NotPossibleBorderBrush,
                                               2, 2, 2);
                DrawUtils.DrawStringWithBorder(graphics, text2, NotPossibleFont, NotPossibleBrush, NotPossibleBorderBrush,
                                               2, 2 + (int)size1.Height + (int)NotPossibleFont.Size / 2, 2);
                graphics.Dispose();
                width    = Flower.IconSize * 5 / 4 + textImage.Width;
                height   = Flower.IconSize + VerticalSpace;
                image    = new Bitmap(width, height);
                graphics = Graphics.FromImage(image);
                graphics.DrawImage(icon, 0, 0);
                graphics.DrawImage(textImage, Flower.IconSize * 5 / 4, (Flower.IconSize - textImage.Height) / 2);
                graphics.Dispose();
            }
            else
            {
                IEnumerable <Image> testImages = new List <Image>(tests.Select((test) => test.CreateImage()));
                width  = 2 * Flower.IconSize + 2 * DrawUtils.SymbolSize + 3 * HorizontalSpace;
                width += results.Count * (HorizontalSpace + Flower.IconSize);
                height = Flower.IconSize + ChanceSpace + VerticalSpace;
                foreach (Image testImage in testImages)
                {
                    height += testImage.Height + VerticalSpace;
                }

                image    = new Bitmap(width, height);
                graphics = Graphics.FromImage(image);
                graphics.TextRenderingHint = TextRenderingHint.AntiAlias;
                int x = 0;
                graphics.DrawImage(flower1.Icon, x, 0);
                x += Flower.IconSize + HorizontalSpace;
                graphics.DrawImage(DrawUtils.Cross, x, DrawUtils.VerticalOffset);
                x += DrawUtils.SymbolSize + HorizontalSpace;
                graphics.DrawImage(flower2.Icon, x, 0);
                x += Flower.IconSize + HorizontalSpace;
                graphics.DrawImage(DrawUtils.Equals, x, DrawUtils.VerticalOffset);
                x += DrawUtils.SymbolSize + HorizontalSpace;
                foreach (BreedingResult result in results)
                {
                    graphics.DrawImage(result.Flower.Icon, x, 0);
                    string chanceText   = result.Chance + "%";
                    SizeF  size         = graphics.MeasureString(chanceText, ChanceFont);
                    float  chanceOffset = (Flower.IconSize - size.Width) / 2f;
                    graphics.DrawString(chanceText, ChanceFont, ChanceBrush, x + chanceOffset, Flower.IconSize + ChanceTopSpace);
                    x += Flower.IconSize + HorizontalSpace;
                }

                int y = Flower.IconSize + ChanceSpace + VerticalSpace;
                foreach (Image testImage in testImages)
                {
                    graphics.DrawImage(testImage, 0, y);
                    y += testImage.Height + VerticalSpace;
                }

                graphics.Dispose();
            }
            return(image);
        }
        public static void Write(string path)
        {
            string title  = Data.GetName() + " Purebreeding";
            string star   = "Purebreeding";
            string seed   = "Purchased Seeds";
            string ticket = "Hybrid Mystery Island";
            string genes  = "Different Backgrounds = Different Genes";
            List <BreedingPairSection> sections = new List <BreedingPairSection>(Data.GetBreedingPairSections());
            List <Image> sectionPanels          = new List <Image>(sections.Select((section) => section.CreateImage()));

            List <Image>[] columns      = SplitToColumns(sectionPanels);
            int[]          columnWidths = new int[columns.Length];
            int            width        = -PanelMargin;
            int            height       = 0;

            for (int k = 0; k < columns.Length; k++)
            {
                List <Image> column       = columns[k];
                int          columnWidth  = 0;
                int          columnHeight = -PanelMargin;
                foreach (Image panel in column)
                {
                    if (panel.Width > columnWidth)
                    {
                        columnWidth = panel.Width;
                    }
                    columnHeight += panel.Height + PanelMargin;
                }
                columnWidths[k] = columnWidth;
                width          += columnWidth + PanelMargin;
                if (columnHeight > height)
                {
                    height = columnHeight;
                }
            }

            Image    content  = new Bitmap(width, height);
            Graphics graphics = Graphics.FromImage(content);
            int      x        = 0;
            int      y        = 0;
            int      index    = 0;

            for (int k = 0; k < columns.Length; k++)
            {
                List <Image> column      = columns[k];
                int          columnWidth = columnWidths[k];
                y = 0;
                foreach (Image panel in column)
                {
                    if (panel.Width < columnWidth)
                    {
                        graphics.DrawImage(sections[index].CreateImage(columnWidth), x, y);
                    }
                    else
                    {
                        graphics.DrawImage(panel, x, y);
                    }
                    y += panel.Height + PanelMargin;
                    index++;
                }
                x += columnWidth + PanelMargin;
            }

            SizeF titleSize  = graphics.MeasureString(title, TitleFont);
            SizeF starSize   = graphics.MeasureString(star, LegendFont);
            SizeF seedSize   = graphics.MeasureString(seed, LegendFont);
            SizeF ticketSize = graphics.MeasureString(ticket, LegendFont);
            SizeF genesSize  = graphics.MeasureString(genes, LegendFont);

            graphics.Dispose();
            width  = 4 * PanelMargin + Math.Max(content.Width, (int)titleSize.Width);
            height = 9 * PanelMargin + (int)titleSize.Height + (int)starSize.Height
                     + (int)seedSize.Height + (int)ticketSize.Height + (int)genesSize.Height + content.Height;
            Image image = new Bitmap(width, height);

            graphics = Graphics.FromImage(image);
            graphics.Clear(Background);
            Brush brush       = new SolidBrush(TextColor);
            Brush borderBrush = new SolidBrush(Color.White);

            x = (image.Width - (int)titleSize.Width) / 2;
            y = 2 * PanelMargin;
            DrawUtils.DrawStringWithBorder(graphics, title, TitleFont, brush, borderBrush, x, y, 8);
            x  = image.Width / 4;
            y += (int)titleSize.Height + PanelMargin;
            Sprites.DrawSprite(graphics, x - Sprites.SpriteSize - PanelMargin / 2,
                               y + ((int)starSize.Height - Sprites.SpriteSize) / 2, Flower.Star);
            DrawUtils.DrawStringWithBorder(graphics, star, LegendFont, brush, borderBrush, x + PanelMargin / 2, y, 4);
            y += (int)starSize.Height + PanelMargin;
            Sprites.DrawSprite(graphics, x - Sprites.SpriteSize - PanelMargin / 2,
                               y + ((int)seedSize.Height - Sprites.SpriteSize) / 2, Flower.GetSource("seedred"));
            DrawUtils.DrawStringWithBorder(graphics, seed, LegendFont, brush, borderBrush, x + PanelMargin / 2, y, 4);
            y += (int)seedSize.Height + PanelMargin;
            Sprites.DrawSprite(graphics, x - Sprites.SpriteSize - PanelMargin / 2,
                               y + ((int)ticketSize.Height - Sprites.SpriteSize) / 2, Flower.GetSource("island"));
            DrawUtils.DrawStringWithBorder(graphics, ticket, LegendFont, brush, borderBrush, x + PanelMargin / 2, y, 4);
            y += (int)ticketSize.Height + PanelMargin;
            x  = (image.Width - (int)genesSize.Width) / 2;
            DrawUtils.DrawStringWithBorder(graphics, genes, LegendFont, brush, borderBrush, x, y, 4);
            y += (int)genesSize.Height + PanelMargin;
            brush.Dispose();
            borderBrush.Dispose();
            graphics.DrawImage(content, (image.Width - content.Width) / 2, y);
            graphics.Dispose();

            image.Save(path + ".png", ImageFormat.Png);
        }