using System;
using OpenCvSharp;

namespace OpenCVStudio_v0
{
    public sealed class BilateralFilterExecutor : IImageBlockExecutor
    {
        public string BlockType => "BilateralFilter";

        public Mat Execute(Mat input, ProjectBlock block, ProjectManager projectManager)
        {
            ArgumentNullException.ThrowIfNull(input);
            ArgumentNullException.ThrowIfNull(block);
            ArgumentNullException.ThrowIfNull(projectManager);

            if (input.Empty())
                throw new ArgumentException("Передано пустое изображение.", nameof(input));

            int diameter = projectManager.GetBlockParameter(block.Id, "Diameter", 9);
            double sigmaColor = projectManager.GetBlockParameter(block.Id, "SigmaColor", 75.0);
            double sigmaSpace = projectManager.GetBlockParameter(block.Id, "SigmaSpace", 75.0);
            RotateBorderMode borderMode = projectManager.GetBlockParameter(block.Id, "BorderMode", RotateBorderMode.Reflect101);

            Mat output = new Mat();

            try
            {
                Cv2.BilateralFilter(input, output, diameter, sigmaColor, sigmaSpace, ConvertBorderMode(borderMode));

                return output;
            }
            catch
            {
                output.Dispose();
                throw;
            }
        }

        private static BorderTypes ConvertBorderMode(RotateBorderMode mode)
        {
            return mode switch
            {
                RotateBorderMode.Constant => BorderTypes.Constant,
                RotateBorderMode.Replicate => BorderTypes.Replicate,
                RotateBorderMode.Reflect => BorderTypes.Reflect,
                RotateBorderMode.Reflect101 => BorderTypes.Reflect101,
                _ => BorderTypes.Default
            };
        }
    }
}