using System;
using System.Collections.Generic;
using System.Linq;
using CrossCutting;
using OpenCvSharp;
using Tesseract;

namespace InterpreterLibrary.Models.Transform
{
    internal static class RigidTransformer
    {
        public static Pix Transform(Pix image, IReadOnlyList<Tuple<PointF, PointF>> pointPairs)
        {
            var xScale = pointPairs.Select(pair => pair.Item1.X / pair.Item2.X).Max();
            var yScale = pointPairs.Select(pair => pair.Item1.Y / pair.Item2.Y).Max();
            var newSize = new Size(image.Width * xScale, image.Height * yScale);

            var q = InputArray.Create(from pair in pointPairs select new Point2d(pair.Item1.X, pair.Item1.Y));
            var p = InputArray.Create(from pair in pointPairs select new Point2d(pair.Item2.X, pair.Item2.Y));
            var rigidTransform = Cv2.EstimateRigidTransform(p, q, true);


            var mat = Mat.FromImageData(image.SaveToMemory(ImageFormat.Bmp));
            var transformedMat = new Mat();
            Cv2.WarpAffine(mat, transformedMat, rigidTransform, newSize, InterpolationFlags.Nearest, BorderTypes.Constant, Scalar.White);
            var bytes = transformedMat.ToBytes();
            return Pix.LoadFromMemory(bytes);
        }

        public static Mat TransformMat(Mat image, IReadOnlyList<Tuple<PointF, PointF>> pointPairs)
        {
            var xScale = pointPairs.Select(pair => pair.Item1.X / pair.Item2.X).Max();
            var yScale = pointPairs.Select(pair => pair.Item1.Y / pair.Item2.Y).Max();
            var newSize = new Size(image.Width * xScale, image.Height * yScale);

            var q = InputArray.Create(from pair in pointPairs select new Point2d(pair.Item1.X, pair.Item1.Y));
            var p = InputArray.Create(from pair in pointPairs select new Point2d(pair.Item2.X, pair.Item2.Y));
            var rigid = Cv2.EstimateRigidTransform(p, q, true);
            var transformedMat = new Mat();
            Cv2.WarpAffine(image, transformedMat, rigid, newSize, InterpolationFlags.Nearest, BorderTypes.Constant, Scalar.White);
            return transformedMat;
        }

    }
}

