using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

namespace Elfisa.UI.Helpers
{
    internal static class GraphicsExtensions
    {
        public static GraphicsPath CreateRoundedRectangle(Rectangle bounds, int radius)
        {
            var path = new GraphicsPath();
            if (radius <= 0 || bounds.Width <= 0 || bounds.Height <= 0)
            {
                path.AddRectangle(bounds);
                return path;
            }

            var diameter = radius * 2;
            var arc = new Rectangle(bounds.Location, new Size(diameter, diameter));

            path.AddArc(arc, 180, 90);
            arc.X = bounds.Right - diameter;
            path.AddArc(arc, 270, 90);
            arc.Y = bounds.Bottom - diameter;
            path.AddArc(arc, 0, 90);
            arc.X = bounds.Left;
            path.AddArc(arc, 90, 90);
            path.CloseFigure();
            return path;
        }

        public static GraphicsPath CreateTopRoundedRectangle(Rectangle bounds, int radius)
        {
            var path = new GraphicsPath();
            if (radius <= 0 || bounds.Width <= 0 || bounds.Height <= 0)
            {
                path.AddRectangle(bounds);
                return path;
            }

            var diameter = radius * 2;
            var arc = new Rectangle(bounds.X, bounds.Y, diameter, diameter);
            path.AddArc(arc, 180, 90);
            arc.X = bounds.Right - diameter;
            path.AddArc(arc, 270, 90);
            path.AddLine(bounds.Right, bounds.Y + radius, bounds.Right, bounds.Bottom);
            path.AddLine(bounds.Right, bounds.Bottom, bounds.Left, bounds.Bottom);
            path.AddLine(bounds.Left, bounds.Bottom, bounds.Left, bounds.Y + radius);
            path.CloseFigure();
            return path;
        }

        public static void FillTopRoundedRectangle(Graphics graphics, Brush brush, Rectangle bounds, int radius)
        {
            using (var path = CreateTopRoundedRectangle(bounds, radius))
            {
                graphics.FillPath(brush, path);
            }
        }

        public static void DrawTopRoundedRectangle(Graphics graphics, Pen pen, Rectangle bounds, int radius)
        {
            using (var path = CreateTopRoundedRectangle(bounds, radius))
            {
                graphics.DrawPath(pen, path);
            }
        }

        public static void DrawAttachedTabOutline(Graphics graphics, Pen pen, Rectangle bounds, int radius)
        {
            if (bounds.Width <= 0 || bounds.Height <= 0)
            {
                return;
            }

            if (radius <= 0)
            {
                graphics.DrawLine(pen, bounds.Left, bounds.Top, bounds.Right, bounds.Top);
                graphics.DrawLine(pen, bounds.Left, bounds.Top, bounds.Left, bounds.Bottom);
                graphics.DrawLine(pen, bounds.Right - 1, bounds.Top, bounds.Right - 1, bounds.Bottom);
                return;
            }

            using (var path = new GraphicsPath())
            {
                var diameter = radius * 2;
                var arc = new Rectangle(bounds.X, bounds.Y, diameter, diameter);
                path.AddArc(arc, 180, 90);
                arc.X = bounds.Right - diameter;
                path.AddArc(arc, 270, 90);
                path.AddLine(bounds.Right, bounds.Y + radius, bounds.Right, bounds.Bottom);
                graphics.DrawPath(pen, path);
            }

            graphics.DrawLine(pen, bounds.Left, bounds.Y + radius, bounds.Left, bounds.Bottom);
        }

        public static void FillRoundedRectangle(Graphics graphics, Brush brush, Rectangle bounds, int radius)
        {
            using (var path = CreateRoundedRectangle(bounds, radius))
            {
                graphics.FillPath(brush, path);
            }
        }

        public static void DrawRoundedRectangle(Graphics graphics, Pen pen, Rectangle bounds, int radius)
        {
            using (var path = CreateRoundedRectangle(bounds, radius))
            {
                graphics.DrawPath(pen, path);
            }
        }

        public static Color Blend(Color baseColor, Color overlay, float amount)
        {
            amount = amount < 0f ? 0f : amount > 1f ? 1f : amount;
            var inv = 1f - amount;
            return Color.FromArgb(
                (int)(baseColor.A * inv + overlay.A * amount),
                (int)(baseColor.R * inv + overlay.R * amount),
                (int)(baseColor.G * inv + overlay.G * amount),
                (int)(baseColor.B * inv + overlay.B * amount));
        }

        public static Color LerpColor(Color from, Color to, float t)
        {
            return Blend(from, to, t);
        }
    }
}
