using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
namespace OpenCVStudio_v0
{
    public sealed class ResizeBlockProperties
    {
        private readonly ProjectManager projectManager; private readonly ProjectBlock projectBlock;
        private ResizeMode mode; private int width; private int height; private double scalePercent; private bool keepAspectRatio; private ResizeInterpolation interpolation;
        public ResizeBlockProperties(ProjectManager projectManager, ProjectBlock projectBlock)
        {
            this.projectManager = projectManager ?? throw new ArgumentNullException(nameof(projectManager));
            this.projectBlock = projectBlock ?? throw new ArgumentNullException(nameof(projectBlock));
            mode = projectManager.GetBlockParameter(projectBlock.Id, "Mode", ResizeMode.ScalePercent);
            width = projectManager.GetBlockParameter(projectBlock.Id, "Width", 640);
            height = projectManager.GetBlockParameter(projectBlock.Id, "Height", 480);
            scalePercent = projectManager.GetBlockParameter(projectBlock.Id, "ScalePercent", 100.0);
            keepAspectRatio = projectManager.GetBlockParameter(projectBlock.Id, "KeepAspectRatio", true);
            interpolation = projectManager.GetBlockParameter(projectBlock.Id, "Interpolation", ResizeInterpolation.Area);
        }
        [Category("Размер")]
        [DisplayName("Режим")]
        [Description("ExactSize задаёт точную ширину и высоту. ScalePercent изменяет размер в процентах.")]
        public ResizeMode Mode
        {
            get => mode;
            set
            {
                if (mode == value) return;
                mode = value;
                projectManager.SetBlockParameter(projectBlock.Id, "Mode", value);
            }
        }
        [Category("Размер")]
        [DisplayName("Ширина")]
        [Description("Целевая ширина изображения в пикселях. Используется в режиме ExactSize.")]
        public int Width
        {
            get => width;
            set
            {
                ValidateDimension(value, "Ширина");
                if (width == value) return;
                width = value;
                projectManager.SetBlockParameter(projectBlock.Id, "Width", value);
            }
        }
        [Category("Размер")]
        [DisplayName("Высота")]
        [Description("Целевая высота изображения в пикселях. Используется в режиме ExactSize.")]
        public int Height
        {
            get => height;
            set
            {
                ValidateDimension(value, "Высота");
                if (height == value) return;
                height = value;
                projectManager.SetBlockParameter(projectBlock.Id, "Height", value);
            }
        }
        [Category("Размер")]
        [DisplayName("Масштаб, %")]
        [Description("Размер результата относительно исходного изображения. 100 — исходный размер, 50 — уменьшение в два раза.")]
        public double ScalePercent
        {
            get => scalePercent;
            set
            {
                ValidateScalePercent(value);
                if (Math.Abs(scalePercent - value) < double.Epsilon) return;
                scalePercent = value;
                projectManager.SetBlockParameter(projectBlock.Id, "ScalePercent", value);
            }
        }
        [Category("Размер")]
        [DisplayName("Сохранять пропорции")]
        [Description("При включении ширина считается основной, а высота вычисляется автоматически.")]
        public bool KeepAspectRatio
        {
            get => keepAspectRatio;
            set
            {
                if (keepAspectRatio == value) return;
                keepAspectRatio = value;
                projectManager.SetBlockParameter(projectBlock.Id, "KeepAspectRatio", value);
            }
        }
        [Category("Качество")]
        [DisplayName("Интерполяция")]
        [Description("Способ вычисления новых пикселей. Area рекомендуется для уменьшения, Linear или Cubic — для увеличения.")]
        public ResizeInterpolation Interpolation
        {
            get => interpolation;
            set
            {
                if (interpolation == value) return;
                interpolation = value;
                projectManager.SetBlockParameter(projectBlock.Id, "Interpolation", 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 ValidateDimension(int value, string parameterName)
        {
            if (value < 1 || value > 32768) throw new ArgumentOutOfRangeException(nameof(value), value, $"{parameterName} должна быть от 1 до 32768 пикселей.");
        }
        private static void ValidateScalePercent(double value)
        {
            if (double.IsNaN(value) || double.IsInfinity(value) || value < 0.1 || value > 1000.0)
                throw new ArgumentOutOfRangeException(nameof(value), value, "Масштаб должен быть от 0,1 до 1000 процентов.");
        }
    }
}