using System;
using System.ComponentModel;
using OpenCvSharp;

namespace OpenCVStudio_v0
{
    /// <summary>
    /// Свойства блока вычисления совмещения
    /// двух изображений методом ECC.
    /// </summary>
    public sealed class FindTransformECCProperties
    {
        private readonly ProjectManager projectManager;
        private readonly ProjectBlock block;

        public FindTransformECCProperties(ProjectManager projectManager, ProjectBlock block)
        {
            this.projectManager = projectManager ?? throw new ArgumentNullException(nameof(projectManager));
            this.block = block ?? throw new ArgumentNullException(nameof(block));
        }

        [Category("Информация")]
        [DisplayName("Название блока")]
        [ReadOnly(true)]
        public string Name => block.Name;

        [Category("Информация")]
        [DisplayName("Тип блока")]
        [ReadOnly(true)]
        public string BlockType => block.BlockType;

        [Category("Параметры ECC")]
        [DisplayName("Тип преобразования")]
        [Description("Translation - только смещение; Euclidean - смещение и поворот; Affine - смещение, поворот и масштаб.")]
        public MotionTypes MotionType
        {
            get => projectManager.GetBlockParameter(block.Id, "MotionType", MotionTypes.Affine);
            set => projectManager.SetBlockParameter(block.Id, "MotionType", value);
        }

        [Category("Параметры ECC")]
        [DisplayName("Количество итераций")]
        [Description("Максимальное число циклов оптимизации.")]
        public int Iterations
        {
            get => projectManager.GetBlockParameter(block.Id, "Iterations", 500);
            set
            {
                if (value < 1) value = 1;
                projectManager.SetBlockParameter(block.Id, "Iterations", value);
            }
        }

        [Category("Параметры ECC")]
        [DisplayName("Точность")]
        [Description("Чем меньше значение, тем точнее, но дольше расчёт.")]
        public double Epsilon
        {
            get => projectManager.GetBlockParameter(block.Id, "Epsilon", 0.000001);
            set
            {
                if (value <= 0) value = 0.000001;
                projectManager.SetBlockParameter(block.Id, "Epsilon", value);
            }
        }

        [Category("Отображение")]
        [DisplayName("Выводить результат")]
        public bool ShowResult
        {
            get => projectManager.GetBlockParameter(block.Id, "ShowResult", true);
            set => projectManager.SetBlockParameter(block.Id, "ShowResult", value);
        }
    }
}