using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Azimuth;
using Annulus;
using Slipstream.StokesFlow;
using Slipstream;

namespace Slipstream.Testbed.Demos
{
    public class TranslatingSquareStokeslet : Demo
    {
        public Scalar cycleCount = 0;
        StokesBoundaryBody _body;
        public override void Start(FluidWorld world)
        {
            var square = new SimplePolygon(new Vector[]
            {
                new Vector(-15, -15),
                new Vector(-15, 15),
                new Vector(15, 15),
                new Vector(15, -15),
            });

            _body = new StokesBoundaryBody(square, Vector.Zero, 0.0, 8);

            world.AddBoundary(_body);

            Random rand = new Random(1);
            for (int i = 0; i < 1000; ++i)
            {
                world.AddTracerParticle(new Vector(2 * rand.NextDouble() - 1, 2 * rand.NextDouble() - 1) * 100);
            }
        }

        public override void Update(FluidWorld world)
        {
            cycleCount += 1.0 / 60.0;

            Scalar period = 10;
            Scalar angularVelocity = (1.0 / period) * (2 * Math.PI);

            var newPos = new Vector(100 * Math.Cos(angularVelocity * cycleCount), 0);
            var velocity = new Vector(100 * angularVelocity * -Math.Sin(angularVelocity * cycleCount), 0);

            _body.Position = Vector.Zero;
            _body.LinearVelocity = velocity;
            _body.Orientation = 0;
            _body.AngularVelocity = 0;

            {
                Scalar totalEnergyCount;
                // world.IntegrateVortonMotion(1.0 / 60.0);
                world.EnforceBoundaryConditions();
                world.IntegrateTracerParticles(1.0 / 60.0, out totalEnergyCount);
            }
        }

        public override void Reset(FluidWorld world)
        {
            cycleCount = 0;
        }
    }
}