// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

namespace System.Drawing.Drawing2D.Tests;

public class AdjustableArrowCapTests
{
    public static IEnumerable<object[]> Ctor_Float_Float_TestData()
    {
        yield return new object[] { 1f, 1f };
        yield return new object[] { 50f, 50f };
        yield return new object[] { float.MaxValue, float.MaxValue };
        // Nonsensical values -- but still permitted.
        yield return new object[] { -1f, 1f };
        yield return new object[] { float.PositiveInfinity, 1f };
        yield return new object[] { float.NegativeInfinity, 1f };
        yield return new object[] { float.NaN, 1f };
        yield return new object[] { 0f, 1f };
        yield return new object[] { 0f, 0f };
        yield return new object[] { 1f, -1f };
    }

    [Theory]
    [MemberData(nameof(Ctor_Float_Float_TestData))]
    public void Ctor_Float_Float(float width, float height)
    {
        using AdjustableArrowCap arrowCap = new(width, height);
        Assert.Equal(width, arrowCap.Width);
        Assert.Equal(height, arrowCap.Height);
        Assert.True(arrowCap.Filled);
    }

    public static IEnumerable<object[]> Ctor_Float_Float_Bool_TestData()
    {
        foreach (object[] data in Ctor_Float_Float_TestData())
        {
            yield return new object[] { data[0], data[1], true };
            yield return new object[] { data[0], data[1], false };
        }
    }

    [Theory]
    [MemberData(nameof(Ctor_Float_Float_Bool_TestData))]
    public void Ctor_Float_Float_Bool(float width, float height, bool filled)
    {
        using AdjustableArrowCap arrowCap = new(width, height, filled);
        Assert.Equal(width, arrowCap.Width);
        Assert.Equal(height, arrowCap.Height);
        Assert.Equal(filled, arrowCap.Filled);
    }

    public static IEnumerable<object[]> Properties_TestData()
    {
        yield return new object[] { -1 };
        yield return new object[] { 0 };
        yield return new object[] { 10 };
        yield return new object[] { 5000 };
        yield return new object[] { float.MaxValue };
        yield return new object[] { float.PositiveInfinity };
        yield return new object[] { float.NegativeInfinity };
        yield return new object[] { float.NaN };
    }

    [Theory]
    [MemberData(nameof(Properties_TestData))]
    public void Width_Set_GetReturnsExpected(float width)
    {
        using AdjustableArrowCap arrowCap = new(1, 1);
        arrowCap.Width = width;
        Assert.Equal(width, arrowCap.Width);
    }

    [Theory]
    [MemberData(nameof(Properties_TestData))]
    public void Height_Set_GetReturnsExpected(float height)
    {
        using AdjustableArrowCap arrowCap = new(1, 1);
        arrowCap.Height = height;
        Assert.Equal(height, arrowCap.Height);
    }

    [Theory]
    [MemberData(nameof(Properties_TestData))]
    public void MiddleInset_Set_GetReturnsExpected(float middleInset)
    {
        using AdjustableArrowCap arrowCap = new(1, 1);
        arrowCap.MiddleInset = middleInset;
        Assert.Equal(middleInset, arrowCap.MiddleInset);
    }

    [Theory]
    [InlineData(true)]
    [InlineData(false)]
    public void Filled_Set_GetReturnsExpected(bool filled)
    {
        using AdjustableArrowCap arrowCap = new(1, 1);
        arrowCap.Filled = filled;
        Assert.Equal(filled, arrowCap.Filled);
    }

    [Fact]
    public void Clone_Success()
    {
        using AdjustableArrowCap arrowCap = new(1, 1);
        using AdjustableArrowCap clone = Assert.IsType<AdjustableArrowCap>(arrowCap.Clone());
        Assert.NotSame(clone, arrowCap);
        Assert.Equal(clone.Width, arrowCap.Width);
        Assert.Equal(clone.Height, arrowCap.Height);
        Assert.Equal(clone.MiddleInset, arrowCap.MiddleInset);
        Assert.Equal(clone.Filled, arrowCap.Filled);
    }

    [Fact]
    public void BaseCap_ReturnsTriangle()
    {
        using AdjustableArrowCap arrowCap = new(1, 1);
        Assert.Equal(LineCap.Triangle, arrowCap.BaseCap);
    }
}
