using System;
using System.ComponentModel;

namespace OpenCVStudio_v0
{
    public sealed class BilateralFilterBlockProperties
    {
        private readonly ProjectManager projectManager;
        private readonly ProjectBlock projectBlock;

        private int diameter;
        private double sigmaColor;
        private double sigmaSpace;
        private RotateBorderMode borderMode;

        public BilateralFilterBlockProperties(ProjectManager projectManager, ProjectBlock projectBlock)
        {
            this.projectManager = projectManager ?? throw new ArgumentNullException(nameof(projectManager));
            this.projectBlock = projectBlock ?? throw new ArgumentNullException(nameof(projectBlock));

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

        [Category("Фильтр")]
        [DisplayName("Диаметр")]
        [Description("Размер области фильтра.")]
        public int Diameter
        {
            get => diameter;
            set
            {
                if (value < 1 || value > 255)
                    throw new ArgumentOutOfRangeException(nameof(value));

                diameter = value;

                projectManager.SetBlockParameter(projectBlock.Id, "Diameter", value);
            }
        }

        [Category("Фильтр")]
        [DisplayName("Sigma Color")]
        [Description("Степень сглаживания по цвету.")]
        public double SigmaColor
        {
            get => sigmaColor;
            set
            {
                if (value < 0)
                    throw new ArgumentOutOfRangeException(nameof(value));

                sigmaColor = value;

                projectManager.SetBlockParameter(projectBlock.Id, "SigmaColor", value);
            }
        }

        [Category("Фильтр")]
        [DisplayName("Sigma Space")]
        [Description("Степень сглаживания по расстоянию.")]
        public double SigmaSpace
        {
            get => sigmaSpace;
            set
            {
                if (value < 0)
                    throw new ArgumentOutOfRangeException(nameof(value));

                sigmaSpace = value;

                projectManager.SetBlockParameter(projectBlock.Id, "SigmaSpace", value);
            }
        }

        [Category("Границы")]
        [DisplayName("Обработка границ")]
        public RotateBorderMode BorderMode
        {
            get => borderMode;
            set
            {
                borderMode = value;

                projectManager.SetBlockParameter(projectBlock.Id, "BorderMode", 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;
    }
}