using System;
using System.ComponentModel;

namespace OpenCVStudio_v0
{
    /// <summary>
    /// Параметры блока морфологического расширения.
    /// </summary>
    public sealed class DilateBlockProperties
    {
        private readonly ProjectManager projectManager;
        private readonly ProjectBlock projectBlock;
        private int kernelWidth;
        private int kernelHeight;
        private int iterations;
        private MorphologyKernelShape kernelShape;

        public DilateBlockProperties(ProjectManager projectManager, ProjectBlock projectBlock)
        {
            this.projectManager = projectManager ?? throw new ArgumentNullException(nameof(projectManager));
            this.projectBlock = projectBlock ?? throw new ArgumentNullException(nameof(projectBlock));
            kernelWidth = projectManager.GetBlockParameter(projectBlock.Id, "KernelWidth", 3);
            kernelHeight = projectManager.GetBlockParameter(projectBlock.Id, "KernelHeight", 3);
            iterations = projectManager.GetBlockParameter(projectBlock.Id, "Iterations", 1);
            kernelShape = projectManager.GetBlockParameter(projectBlock.Id, "KernelShape", MorphologyKernelShape.Rectangle);
        }

        [Category("Ядро")]
        [DisplayName("Ширина")]
        [Description("Ширина структурного элемента. Чем больше значение, тем сильнее расширяются светлые области.")]
        [DefaultValue(3)]
        public int KernelWidth
        {
            get => kernelWidth;
            set
            {
                int correctedValue = Math.Clamp(value, 1, 999);
                if (kernelWidth == correctedValue)
                {
                    return;
                }
                kernelWidth = correctedValue;
                projectManager.SetBlockParameter(projectBlock.Id, "KernelWidth", correctedValue);
            }
        }

        [Category("Ядро")]
        [DisplayName("Высота")]
        [Description("Высота структурного элемента. Чем больше значение, тем сильнее расширяются светлые области.")]
        [DefaultValue(3)]
        public int KernelHeight
        {
            get => kernelHeight;
            set
            {
                int correctedValue = Math.Clamp(value, 1, 999);
                if (kernelHeight == correctedValue)
                {
                    return;
                }
                kernelHeight = correctedValue;
                projectManager.SetBlockParameter(projectBlock.Id, "KernelHeight", correctedValue);
            }
        }

        [Category("Ядро")]
        [DisplayName("Форма")]
        [Description("Форма структурного элемента: прямоугольник, эллипс или крест.")]
        [DefaultValue(MorphologyKernelShape.Rectangle)]
        public MorphologyKernelShape KernelShape
        {
            get => kernelShape;
            set
            {
                if (kernelShape == value)
                {
                    return;
                }
                kernelShape = value;
                projectManager.SetBlockParameter(projectBlock.Id, "KernelShape", value);
            }
        }

        [Category("Параметры")]
        [DisplayName("Итерации")]
        [Description("Количество последовательных выполнений расширения. Чем больше значение, тем сильнее увеличиваются светлые области.")]
        [DefaultValue(1)]
        public int Iterations
        {
            get => iterations;
            set
            {
                int correctedValue = Math.Clamp(value, 1, 100);
                if (iterations == correctedValue)
                {
                    return;
                }
                iterations = correctedValue;
                projectManager.SetBlockParameter(projectBlock.Id, "Iterations", correctedValue);
            }
        }

        [Category("Подсказка")]
        [DisplayName("Результат")]
        [ReadOnly(true)]
        public string ResultHint => "Увеличивает светлые области изображения";

        [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;
    }
}