using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Azimuth;
using Annulus;

namespace Annulus.UnitTests
{
    public class PolygonVertexTests : UnitTestSharp.TestFixture
    {
        static SimplePolygon box = new SimplePolygon(new Vector[]
        {
            new Vector(-1,-1),
            new Vector(-1,1),
            new Vector(1,1),
            new Vector(1,-1),
        });

        public class GetNextEdge : UnitTestSharp.TestFixture
        {
            public void Basic()
            {
                var vertex = box.GetVertex(0);
                var next = vertex.NextEdge;

                CheckEqual(box.GetEdge(0), next);
            }
        }

        public class GetPrevEdge : UnitTestSharp.TestFixture
        {
            public void Basic()
            {
                var vertex = box.GetVertex(1);
                var prev = vertex.PrevEdge;

                CheckEqual(box.GetEdge(0), prev);
            }

            public void Wraps()
            {
                var vertex = box.GetVertex(0);
                var prev = vertex.PrevEdge;

                CheckEqual(box.GetEdge(3), prev);
            }
        }

        public class GetPrevVertex : UnitTestSharp.TestFixture
        {
            public void Basic()
            {
                var vertex = box.GetVertex(1);
                var next = vertex.PrevVertex;

                CheckEqual(box.GetVertex(0), next);
            }

            public void Wraps()
            {
                var vertex = box.GetVertex(0);
                var next = vertex.PrevVertex;

                CheckEqual(box.GetVertex(3), next);
            }
        }

        public class GetNextVertex : UnitTestSharp.TestFixture
        {
            public void Basic()
            {
                var vertex = box.GetVertex(0);
                var next = vertex.NextVertex;

                CheckEqual(box.GetVertex(1), next);
            }

            public void Wraps()
            {
                var vertex = box.GetVertex(3);
                var next = vertex.NextVertex;

                CheckEqual(box.GetVertex(0), next);
            }
        }

        public class PointTests : UnitTestSharp.TestFixture
        {
            public void Basic()
            {
                var vertex = box.GetVertex(0);

                CheckEqual(new Vector(-1, -1), vertex.Position);
            }
        }

        public class Equality : UnitTestSharp.TestFixture
        {
            public void Basic()
            {
                var v1 = box.GetVertex(0);
                var v2 = (object)box.GetVertex(0);

                CheckEqual(v1, v2);
            }
        }

        public class BisectorTests : UnitTestSharp.TestFixture
        {
            public void Basic_PositiveWinding()
            {
                var vertex = box.GetVertex(0);
                var dir = new Vector(1, 1);

                var bisector = vertex.GetBisector(1);

                CheckEqual(0, dir.CrossProduct(bisector));
                CheckTrue(dir.DotProduct(bisector) > 0);
            }

            public void Basic_NegativeWinding()
            {
                var vertex = box.GetVertex(0);
                var dir = new Vector(-1, -1);

                var bisector = vertex.GetBisector(-1);

                CheckEqual(0, dir.CrossProduct(bisector));
                CheckTrue(dir.DotProduct(bisector) > 0);
            }

            public void Parallel_PositiveWinding()
            {
                var box = new Polygon(new Vector[]
                {
                    new Vector(-1,0),
                    new Vector(0,0),
                    new Vector(1,0),
                });

                var bisector = box.GetVertex(1).GetBisector(1);

                CheckEqual(new Vector(0, 1), bisector);
            }

            public void Parallel_NegativeWinding()
            {
                var box = new Polygon(new Vector[]
                {
                    new Vector(-1,0),
                    new Vector(0,0),
                    new Vector(1,0),
                });

                var bisector = box.GetVertex(1).GetBisector(-1);

                CheckEqual(new Vector(0, -1), bisector);
            }

            public void AntiParallel_PositiveWinding()
            {
                var box = new Polygon(new Vector[]
                {
                    new Vector(-1,0),
                    new Vector(0,0),
                    new Vector(-1,0),
                });

                var bisector = box.GetVertex(1).GetBisector(1);

                CheckEqual(new Vector(-1, 0), bisector);
            }

            public void AntiParallel_NegativeWinding()
            {
                var box = new Polygon(new Vector[]
                {
                    new Vector(-1,0),
                    new Vector(0,0),
                    new Vector(-1,0),
                });

                var bisector = box.GetVertex(1).GetBisector(-1);

                CheckEqual(new Vector(1, 0), bisector);
            }
        }

        public class IsReflex : UnitTestSharp.TestFixture
        {
            public void Basic_False()
            {
                CheckFalse(box.GetVertex(0).IsReflex(box.SignedArea));
                CheckFalse(box.GetVertex(1).IsReflex(box.SignedArea));
                CheckFalse(box.GetVertex(2).IsReflex(box.SignedArea));
                CheckFalse(box.GetVertex(3).IsReflex(box.SignedArea));
            }

            public void Basic_Mixed()
            {
                SimplePolygon concave = new SimplePolygon(new Vector[]
                {
                    new Vector(-1,-1),
                    new Vector(-1,1),
                    new Vector(1,1),
                    new Vector(0,0),
                    new Vector(1,-1),
                });

                CheckFalse(concave.GetVertex(0).IsReflex(box.SignedArea));
                CheckFalse(concave.GetVertex(1).IsReflex(box.SignedArea));
                CheckFalse(concave.GetVertex(2).IsReflex(box.SignedArea));
                Check(concave.GetVertex(3).IsReflex(box.SignedArea));
                CheckFalse(concave.GetVertex(4).IsReflex(box.SignedArea));
            }
        }
    }
}