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

using System.ComponentModel;
namespace OpenCVStudio_v0
{
    public sealed class ClaheBlockProperties
    {
        private readonly ProjectManager projectManager; private readonly ProjectBlock projectBlock;
        private double clipLimit; private int tileGridWidth; private int tileGridHeight;
        public ClaheBlockProperties(ProjectManager projectManager, ProjectBlock projectBlock)
        {
            this.projectManager = projectManager ?? throw new ArgumentNullException(nameof(projectManager));
            this.projectBlock = projectBlock ?? throw new ArgumentNullException(nameof(projectBlock));
            clipLimit = projectManager.GetBlockParameter(projectBlock.Id, "ClipLimit", 2.0);
            tileGridWidth = projectManager.GetBlockParameter(projectBlock.Id, "TileGridWidth", 8);
            tileGridHeight = projectManager.GetBlockParameter(projectBlock.Id, "TileGridHeight", 8);
        }
        [Category("Контраст")]
        [DisplayName("Ограничение контраста")]
        [Description("Ограничивает усиление локального контраста. Обычные значения: от 1,0 до 5,0.")]
        public double ClipLimit
        {
            get => clipLimit;
            set
            {
                ValidateClipLimit(value);
                if (Math.Abs(clipLimit - value) < double.Epsilon) return;
                clipLimit = value;
                projectManager.SetBlockParameter(projectBlock.Id, "ClipLimit", value);
            }
        }
        [Category("Локальные области")]
        [DisplayName("Областей по ширине")]
        [Description("Количество локальных областей по ширине изображения.")]
        public int TileGridWidth
        {
            get => tileGridWidth;
            set
            {
                ValidateTileGridSize(value, "Количество областей по ширине");
                if (tileGridWidth == value) return;
                tileGridWidth = value;
                projectManager.SetBlockParameter(projectBlock.Id, "TileGridWidth", value);
            }
        }
        [Category("Локальные области")]
        [DisplayName("Областей по высоте")]
        [Description("Количество локальных областей по высоте изображения.")]
        public int TileGridHeight
        {
            get => tileGridHeight;
            set
            {
                ValidateTileGridSize(value, "Количество областей по высоте");
                if (tileGridHeight == value) return;
                tileGridHeight = value;
                projectManager.SetBlockParameter(projectBlock.Id, "TileGridHeight", 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 ValidateClipLimit(double value)
        {
            if (double.IsNaN(value) || double.IsInfinity(value) || value <= 0 || value > 100)
                throw new ArgumentOutOfRangeException(nameof(value), value, "Ограничение контраста должно быть больше 0 и не больше 100.");
        }
        private static void ValidateTileGridSize(int value, string parameterName)
        {
            if (value < 1 || value > 100) throw new ArgumentOutOfRangeException(nameof(value), value, $"{parameterName} должно быть от 1 до 100.");
        }
    }
}