using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using NUnit.Framework;
using StarEngine.Core;

namespace StarEngine.Tests.Core
{
    [TestFixture]
    public class AffineMatrixTest
    {
        [Test]
        public void TestMethods()
        {
            AffineMatrix m = new AffineMatrix(1, 2, 3, 4, 5, 6);
            Assert.AreEqual(1, m.A);
            Assert.AreEqual(2, m.B);
            Assert.AreEqual(3, m.C);
            Assert.AreEqual(4, m.D);
            Assert.AreEqual(5, m.TX);
            Assert.AreEqual(6, m.TY);
            Assert.AreEqual(new AffineMatrix(1, 2, 3, 4, 5, 6).GetHashCode(), m.GetHashCode());
        }

        [Test]
        public void TestOperators()
        {
            AffineMatrix m1 = new AffineMatrix(1, 2, 3, 4, 5, 6);
            AffineMatrix m2 = new AffineMatrix(7, 8, 9, 10, 11, 12);
            Assert.IsTrue(new AffineMatrix(1, 2, 3, 4, 5, 6) == m1);
            Assert.IsTrue(new AffineMatrix(7, 8, 9, 10, 11, 12) == m2);
            Assert.IsTrue(m1 != m2);
        }

        [Test]
        public void TestO()
        {
            AffineMatrix o = AffineMatrix.O;
            Assert.AreEqual(0, o.A);
            Assert.AreEqual(0, o.B);
            Assert.AreEqual(0, o.C);
            Assert.AreEqual(0, o.D);
            Assert.AreEqual(0, o.TX);
            Assert.AreEqual(0, o.TY);
        }

        [Test]
        public void TestI()
        {
            AffineMatrix i = AffineMatrix.I;
            Assert.AreEqual(1, i.A);
            Assert.AreEqual(0, i.B);
            Assert.AreEqual(0, i.C);
            Assert.AreEqual(1, i.D);
            Assert.AreEqual(0, i.TX);
            Assert.AreEqual(0, i.TY);
        }

        [Test]
        public void TestIsRegular()
        {
            AffineMatrix m1 = new AffineMatrix(1, 2, 3, 4, 5, 6);
            Assert.AreEqual(true, m1.IsRegular);
            AffineMatrix m2 = new AffineMatrix(7, 8, 9, 10, 11, 12);
            Assert.AreEqual(true, m2.IsRegular);
            AffineMatrix m3 = new AffineMatrix(0, 0, 0, 0, 13, 14);
            Assert.AreEqual(false, m3.IsRegular);
            AffineMatrix m4 = new AffineMatrix(1, 0, 1, 0, 15, 16);
            Assert.AreEqual(false, m4.IsRegular);
        }

        [Test]
        public void TestConcat()
        {
            AffineMatrix m1 = new AffineMatrix(1, 2, 3, 4, 5, 6);
            AffineMatrix m2 = new AffineMatrix(7, 8, 9, 10, 11, 12);
            Assert.AreEqual(new AffineMatrix(25, 28, 57, 64, 40, 87), m2.Concat(m1));
        }

        [Test]
        public void TestInvert()
        {
            AffineMatrix m1 = new AffineMatrix(1, 2, 3, 4, 5, 6);
            Assert.AreEqual(new AffineMatrix(-2, 1, 1.5, -0.5, 4, -4.5), m1.Invert());

            AffineMatrix m2 = new AffineMatrix(7, 8, 9, 10, 11, 12);
            m2.Invert();
            double delta = 0.00001;
            Assert.AreEqual(-5, m2.A, delta);
            Assert.AreEqual(4, m2.B, delta);
            Assert.AreEqual(4.5, m2.C, delta);
            Assert.AreEqual(-3.5, m2.D, delta);
            Assert.AreEqual(7, m2.TX, delta);
            Assert.AreEqual(-7.5, m2.TY, delta);
        }

        [Test]
        public void TestTransform()
        {
            AffineMatrix m = new AffineMatrix(1, 2, 3, 4, 5, 6);
            PointF p1 = new PointF(7, 8);
            Assert.AreEqual(28, m.Transform(p1).X, 0.0001);
            Assert.AreEqual(59, m.Transform(p1).Y, 0.0001);

            PointF p2 = new PointF(-9, 10);
            Assert.AreEqual(16, m.Transform(p2).X, 0.0001);
            Assert.AreEqual(19, m.Transform(p2).Y, 0.0001);
        }
        
    }
}
