using System.Windows.Markup;
using OpenCvSharp;
using Size = OpenCvSharp.Size;

namespace Hawkeye.VisionBuilder.Workflow.ColorStudioClasses.Filters;

public class RangeFilterItem : IFilter
{
    public IFilterParent Parent { get; set; }

    public RangeFilterItem(CategoryItem parent)
    {
        Parent = parent;
    }

    public RangeFilterItem()
    {
    }

    public int HMin { get; set; } = 0;
    public int HMax { get; set; } = 100;
    public int SMin { get; set; } = 0;
    public int SMax { get; set; } = 255;
    public int VMin { get; set; } = 0;
    public int VMax { get; set; } = 255;
    public int Dilation { get; set; } = 0;
    public int Closing { get; set; } = 0;


    public override string ToString()
    {
        return $"H: {HMin}-{HMax}, S: {SMin}-{SMax}, V: {VMin}-{VMax}";
    }

    public void Transform(ref Mat hsv, ref Mat res)
    {
        var lower = new Scalar(HMin, SMin, VMin);
        var upper = new Scalar(HMax, SMax, VMax);
        var mask = hsv.InRange(lower, upper);

        if (Dilation > 0)
        {
            // generate circular kernel
            var kernel = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(Dilation, Dilation));
            mask = mask.Dilate(kernel);
            kernel.Dispose();
        }

        if (Closing > 0)
        {
            // generate circular kernel
            var kernel = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(Closing, Closing));
            mask = mask.MorphologyEx(MorphTypes.Close, kernel);
            kernel.Dispose();
        }

        res+=mask;

        mask.Dispose();
    }

    public void Save(BinaryWriter writer)
    {
        writer.Write(HMin);
        writer.Write(HMax);
        writer.Write(SMin);
        writer.Write(SMax);
        writer.Write(VMin);
        writer.Write(VMax);
        writer.Write(Dilation);
        writer.Write(Closing);
    }

    public void Load(BinaryReader reader)
    {
        HMin = reader.ReadInt32();
        HMax = reader.ReadInt32();
        SMin = reader.ReadInt32();
        SMax = reader.ReadInt32();
        VMin = reader.ReadInt32();
        VMax = reader.ReadInt32();
        Dilation = reader.ReadInt32();
        Closing = reader.ReadInt32();
    }

    public bool IsSelected { get; set; }

    public static RangeFilterItem Load(BinaryReader reader, CategoryItem parent)
    {
        var filter = new RangeFilterItem(parent);
        filter.HMin = reader.ReadInt32();
        filter.HMax = reader.ReadInt32();
        filter.SMin = reader.ReadInt32();
        filter.SMax = reader.ReadInt32();
        filter.VMin = reader.ReadInt32();
        filter.VMax = reader.ReadInt32();
        filter.Dilation = reader.ReadInt32();
        filter.Closing = reader.ReadInt32();
        return filter;
    }
}