using System;
using System.Collections.Generic;
using System.Text;

using System.ComponentModel;
namespace OpenCVStudio_v0
{
    public sealed class BlurBlockProperties
    {
        private readonly ProjectManager projectManager; private readonly ProjectBlock projectBlock;
        private BlurTypeMode blurType; private int kernelWidth; private int kernelHeight; private double sigmaX;
        public BlurBlockProperties(ProjectManager projectManager, ProjectBlock projectBlock)
        {
            this.projectManager = projectManager ?? throw new ArgumentNullException(nameof(projectManager));
            this.projectBlock = projectBlock ?? throw new ArgumentNullException(nameof(projectBlock));
            blurType = projectManager.GetBlockParameter(projectBlock.Id, "BlurType", BlurTypeMode.Gaussian);
            kernelWidth = projectManager.GetBlockParameter(projectBlock.Id, "KernelWidth", 5);
            kernelHeight = projectManager.GetBlockParameter(projectBlock.Id, "KernelHeight", 5);
            sigmaX = projectManager.GetBlockParameter(projectBlock.Id, "SigmaX", 0.0);
        }
        [Category("Размытие")]
        [DisplayName("Тип")]
        [Description("Способ размытия изображения.")]
        public BlurTypeMode BlurType
        {
            get => blurType;
            set
            {
                if (blurType == value) return;
                blurType = value;
                projectManager.SetBlockParameter(projectBlock.Id, "BlurType", value);
            }
        }
        [Category("Ядро")]
        [DisplayName("Ширина")]
        [Description("Ширина ядра фильтра.")]
        public int KernelWidth
        {
            get => kernelWidth;
            set
            {
                ValidateKernelValue(value);
                if (kernelWidth == value) return;
                kernelWidth = value;
                projectManager.SetBlockParameter(projectBlock.Id, "KernelWidth", value);
            }
        }
        [Category("Ядро")]
        [DisplayName("Высота")]
        [Description("Высота ядра фильтра.")]
        public int KernelHeight
        {
            get => kernelHeight;
            set
            {
                ValidateKernelValue(value);
                if (kernelHeight == value) return;
                kernelHeight = value;
                projectManager.SetBlockParameter(projectBlock.Id, "KernelHeight", value);
            }
        }
        [Category("Gaussian / Bilateral")]
        [DisplayName("Sigma X")]
        [Description("Параметр сглаживания для Gaussian и Bilateral.")]
        public double SigmaX
        {
            get => sigmaX;
            set
            {
                if (value < 0) throw new ArgumentOutOfRangeException(nameof(value), "Sigma X не может быть отрицательной.");
                if (Math.Abs(sigmaX - value) < double.Epsilon) return;
                sigmaX = value;
                projectManager.SetBlockParameter(projectBlock.Id, "SigmaX", value);
            }
        }
        [Category("Блок")]
        [DisplayName("Название")]
        [ReadOnly(true)]
        public string BlockName => projectBlock.Name;
        [Category("Блок")]
        [DisplayName("Тип")]
        [ReadOnly(true)]
        public string BlockType => projectBlock.BlockType;
        [Category("Блок")]
        [DisplayName("Позиция")]
        [ReadOnly(true)]
        public int Position => projectBlock.Order + 1;
        private static void ValidateKernelValue(int value)
        {
            if (value < 1) throw new ArgumentOutOfRangeException(nameof(value), "Размер ядра должен быть больше нуля.");
            if (value % 2 == 0) throw new ArgumentException("Размер ядра должен быть нечётным.");
        }
    }
}