using System;
using OpenCvSharp;

namespace OpenCVStudio_v0
{
    /// <summary>
    /// Результат выполнения pipeline.
    ///
    /// Владеет итоговым изображением и освобождает его
    /// при вызове Dispose().
    /// </summary>
    public sealed class PipelineExecutionResult : IDisposable
    {
        private bool disposed;
        public ContourData? Contours { get; }
        public string ResultText { get; }

        /// <summary>
        /// Итоговое изображение после выполнения pipeline.
        ///
        /// Владельцем Mat является PipelineExecutionResult.
        /// Не следует освобождать Image отдельно.
        /// </summary>
        public Mat Image { get; }

        /// <summary>
        /// Идентификатор последнего выполненного блока.
        ///
        /// Значение null означает, что ни один блок
        /// не был выполнен.
        /// </summary>
        public Guid? LastExecutedBlockId { get; }

        /// <summary>
        /// Название последнего выполненного блока.
        /// </summary>
        public string LastExecutedBlockName { get; }


        public ContourAreaData? ContourAreas { get; }


        /// <summary>
        /// Длины контуров.
        /// </summary>
        public ArcLengthData? ArcLengths { get; }

        /// <summary>
        /// Ограничивающие прямоугольники контуров.
        /// </summary>
        public BoundingRectData? BoundingRects
        {
            get;
        }

        /// <summary>
        /// Минимальные повёрнутые прямоугольники контуров.
        /// </summary>
        public MinAreaRectData? MinAreaRects
        {
            get;
        }


        /// <summary>
        /// Эллипсы, рассчитанные по контурам.
        /// </summary>
        public FitEllipseData? FitEllipses { get; }

        public PipelineExecutionResult(Mat image, Guid? lastExecutedBlockId, string lastExecutedBlockName, ContourData? contours, ContourAreaData? contourAreas, ArcLengthData? arcLengths, BoundingRectData? boundingRects, MinAreaRectData? minAreaRects, FitEllipseData? fitEllipses,string resultText)
        {
            Image = image ?? throw new ArgumentNullException(nameof(image));
            if (image.Empty())
            {
                throw new ArgumentException("Результирующее изображение пустое.", nameof(image));
            }
            LastExecutedBlockId = lastExecutedBlockId;
            LastExecutedBlockName = lastExecutedBlockName ?? string.Empty;
            Contours = contours;
            ContourAreas = contourAreas;
            ArcLengths = arcLengths;
            BoundingRects = boundingRects;
            MinAreaRects = minAreaRects;
            FitEllipses = fitEllipses;
            ResultText = resultText ?? string.Empty;
        }


        /// <summary>
        /// Освобождает итоговое изображение.
        /// </summary>
        public void Dispose()
        {
            if (disposed)
                return;

            disposed = true;

            Image.Dispose();

            GC.SuppressFinalize(this);
        }
    }
}