/// <summary>
 /// Scans for an option at the specified point.
 /// </summary>
 /// <param name="slot">The slot to scan at.</param>
 /// <param name="flags">The flags for scanning.</param>
 /// <param name="saveMarkupsToFolder">The location to save the markup of the scanned options. Set to null to ignore.</param>
 /// <param name="markup">The markup to scan for. Set to null to ignore.</param>
 /// <returns><para>Returns a bool determining if the option is found if <paramref name="markup"/> is not null and <paramref name="flags"/> has the <see cref="OptionScanFlags.ReturnFound"/> flag.</para>
 /// <para>Returns the location of the option if <paramref name="markup"/> is not null and <paramref name="flags"/> has the <see cref="OptionScanFlags.ReturnLocation"/> flag.</para></returns>
 public object MenuOptionScan(int slot, OptionScanFlags flags, string saveMarkupsToFolder, DirectBitmap markup)
 {
     return(MenuOptionScan(FindSlotLocation(slot), flags, saveMarkupsToFolder, markup));
 }
        /// <summary>
        /// Scans for an option at the specified point.
        /// </summary>
        /// <param name="scanLocation">The location to scan at.</param>
        /// <param name="flags">The flags for scanning.</param>
        /// <param name="saveMarkupsToFolder">The location to save the markup of the scanned options. Set to null to ignore.</param>
        /// <param name="markup">The markup to scan for. Set to null to ignore.</param>
        /// <returns><para>Returns a bool determining if the option is found if <paramref name="markup"/> is not null and <paramref name="flags"/> has the <see cref="OptionScanFlags.ReturnFound"/> flag.</para>
        /// <para>Returns the location of the option if <paramref name="markup"/> is not null and <paramref name="flags"/> has the <see cref="OptionScanFlags.ReturnLocation"/> flag.</para></returns>
        public object MenuOptionScan(Point scanLocation, OptionScanFlags flags, string saveMarkupsToFolder, DirectBitmap markup)
        {
            if (saveMarkupsToFolder != null)
            {
                saveMarkupsToFolder = System.IO.Path.GetDirectoryName(saveMarkupsToFolder) + System.IO.Path.DirectorySeparatorChar;
            }

            using (cg.LockHandler.SemiInteractive)
            {
                if (scanLocation == Point.Empty)
                {
                    if (flags.HasFlag(OptionScanFlags.ReturnFound))
                    {
                        return(false);
                    }
                    else if (flags.HasFlag(OptionScanFlags.ReturnLocation))
                    {
                        return(Point.Empty);
                    }
                    else
                    {
                        return(null);
                    }
                }

                if (flags.HasFlag(OptionScanFlags.OpenMenu))
                {
                    cg.RightClick(scanLocation);
                }

                int xStart       = scanLocation.X + 14, // X position to start scanning.
                    yStart       = 0,                   // Y position to start scanning.
                    optionWidth  = 79,                  // The width of the option.
                    optionHeight = 6,                   // The height of the option.
                    yIncrement   = 1;                   // Pixel distance between options.
                int[] textcolor  = new int[] { 169, 169, 169 };
                int   fade       = 80;

                bool menuPointsDown = MenuPointsDown(scanLocation);

                if (menuPointsDown) // The menu points down.
                {
                    yStart = scanLocation.Y + 12;
                }
                else // The menu points up.
                {
                    yStart     = scanLocation.Y - 18;
                    yIncrement = -yIncrement;
                }

                cg.UpdateScreen();
                var options = new List <Tuple <Point, int> >();

                int optionIndex = 0;
                for (int y = yStart; optionHeight < y && y < cg.Capture.Height - optionHeight; y += yIncrement)
                {
                    bool oob = false;
                    while (!(oob = optionHeight > y || y > cg.Capture.Height - optionHeight) && !Capture.CompareColor(xStart, y + (menuPointsDown ? 1 : -optionHeight), textcolor, fade + 20))
                    {
                        y += yIncrement;
                    }

                    // If the y is out of range of the bitmap, stop scanning the options.
                    if (oob || !Capture.CompareColor(xStart - 8, y, new int[] { 67, 67, 68 }, 30))
                    {
                        break;
                    }

                    int percent = 0;
                    if (markup != null)
                    {
                        int success = 0;
                        int total   = 0;

                        for (int xi = 0; xi < markup.Width; xi++)
                        {
                            for (int yi = 0; yi < markup.Height; yi++)
                            {
                                total++;

                                bool bmpPixelIsBlack    = Capture.CompareColor(xStart + xi, y + yi, new int[] { 170, 170, 170 }, 80);
                                bool markupPixelIsBlack = markup.GetPixel(xi, yi) == Color.FromArgb(0, 0, 0);

                                if (bmpPixelIsBlack == markupPixelIsBlack)
                                {
                                    success++;
                                }
                            }
                        }
                        percent = (int)(Convert.ToDouble(success) / Convert.ToDouble(total) * 100);
                    }

                    // Get bitmap of option
                    if (saveMarkupsToFolder != null)
                    {
                        DirectBitmap work = Capture.Clone(xStart, y, optionWidth, optionHeight);

                        for (int xi = 0; xi < work.Width; xi++)
                        {
                            for (int yi = 0; yi < work.Height; yi++)
                            {
                                if (work.CompareColor(xi, yi, textcolor, fade))
                                {
                                    work.SetPixel(xi, yi, Color.Black);
                                }
                                else
                                {
                                    work.SetPixel(xi, yi, Color.White);
                                }
                            }
                        }

                        work.Save($@"{saveMarkupsToFolder}Option Markup-{optionIndex}.png");
                        work.Dispose();
                    }

#if DEBUG
                    if (cg.DebugMenu != null)
                    {
                        Console.WriteLine($"{optionIndex} - {percent}%");
                    }
#endif

                    options.Add(new Tuple <Point, int>(new Point(xStart, y), percent));
                    optionIndex++;
                }

                Point optionLocation = Point.Empty;

                if (markup != null && options.Count > 0)
                {
                    optionLocation = options.Where(o => o.Item2 > 75).OrderByDescending(o => o.Item2).FirstOrDefault()?.Item1 ?? Point.Empty;
                }

                if (flags.HasFlag(OptionScanFlags.Click))
                {
                    SelectMenuOption(optionLocation);
                }

                // Close the menu.
                if (flags.HasFlag(OptionScanFlags.CloseMenu) || (flags.HasFlag(OptionScanFlags.CloseIfNotFound) && optionLocation == Point.Empty))
                {
                    CloseOptionMenu();
                }

                if (flags.HasFlag(OptionScanFlags.ReturnFound))
                {
                    return(optionLocation != Point.Empty);
                }
                else if (flags.HasFlag(OptionScanFlags.ReturnLocation))
                {
                    return(optionLocation);
                }
                return(null);
            }
        }