using System;
using System.ComponentModel;

namespace OpenCVStudio_v0
{
    /// <summary>
    /// Параметры блока обмена каналами
    /// между двумя изображениями.
    /// </summary>
    public sealed class SwapChannelsBlockProperties
    {
        private readonly ProjectManager projectManager;
        private readonly ProjectBlock projectBlock;
        private bool swapChannel0;
        private bool swapChannel1;
        private bool swapChannel2;

        public SwapChannelsBlockProperties(ProjectManager projectManager, ProjectBlock projectBlock)
        {
            this.projectManager = projectManager ?? throw new ArgumentNullException(nameof(projectManager));
            this.projectBlock = projectBlock ?? throw new ArgumentNullException(nameof(projectBlock));
            swapChannel0 = projectManager.GetBlockParameter(projectBlock.Id, "SwapChannel0", false);
            swapChannel1 = projectManager.GetBlockParameter(projectBlock.Id, "SwapChannel1", false);
            swapChannel2 = projectManager.GetBlockParameter(projectBlock.Id, "SwapChannel2", false);
        }

        [Category("Обмен каналами")]
        [DisplayName("Обменять канал 0")]
        [Description("Меняет местами канал 0 основного и второго изображений. Для изображения BGR это синий канал Blue.")]
        public bool SwapChannel0
        {
            get => swapChannel0;
            set
            {
                if (swapChannel0 == value)
                {
                    return;
                }
                swapChannel0 = value;
                projectManager.SetBlockParameter(projectBlock.Id, "SwapChannel0", value);
            }
        }

        [Category("Обмен каналами")]
        [DisplayName("Обменять канал 1")]
        [Description("Меняет местами канал 1 основного и второго изображений. Для изображения BGR это зелёный канал Green.")]
        public bool SwapChannel1
        {
            get => swapChannel1;
            set
            {
                if (swapChannel1 == value)
                {
                    return;
                }
                swapChannel1 = value;
                projectManager.SetBlockParameter(projectBlock.Id, "SwapChannel1", value);
            }
        }

        [Category("Обмен каналами")]
        [DisplayName("Обменять канал 2")]
        [Description("Меняет местами канал 2 основного и второго изображений. Для изображения BGR это красный канал Red.")]
        public bool SwapChannel2
        {
            get => swapChannel2;
            set
            {
                if (swapChannel2 == value)
                {
                    return;
                }
                swapChannel2 = value;
                projectManager.SetBlockParameter(projectBlock.Id, "SwapChannel2", value);
            }
        }

        [Category("Информация")]
        [DisplayName("Функция")]
        [ReadOnly(true)]
        public string FunctionName => "Cv2.Split + Cv2.Merge";

        [Category("Информация")]
        [DisplayName("Описание")]
        [ReadOnly(true)]
        public string Description => "Обменивает выбранные каналы между основным и вторым изображениями.";

        [Category("Информация")]
        [DisplayName("Вход")]
        [ReadOnly(true)]
        public string InputDescription => "Два трёхканальных изображения: Image и SecondImage.";

        [Category("Информация")]
        [DisplayName("Выход")]
        [ReadOnly(true)]
        public string OutputDescription => "Два трёхканальных изображения после обмена выбранными каналами.";

        [Category("Информация")]
        [DisplayName("Требования")]
        [ReadOnly(true)]
        public string Requirements => "Оба изображения должны иметь одинаковый размер, глубину и по 3 канала.";

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