using System;
using System.Collections.Generic;
using OpenCvSharp;

namespace squirrowse.web.Data
{
    public class Filters
    {
        public Filters(bool face, bool lowerBody, bool upperBody)
        {
            Face = face;
            LowerBody = lowerBody;
            UpperBody = upperBody;
        }

        public bool Face { get; set; }
        public bool LowerBody { get; set; }
        public bool UpperBody { get; set; }
    }

    public class Detection : IDetection
    {
        private readonly CascadeClassifier CascadeFace = new CascadeClassifier(
            @".\StaticFiles\haarcascade_frontalface_alt.xml");

        private readonly CascadeClassifier CascadeLowerBody = new CascadeClassifier(
            @".\StaticFiles\haarcascade_lowerbody.xml");

        private readonly CascadeClassifier CascadeUpperBody = new CascadeClassifier(
            @".\StaticFiles\haarcascade_upperbody.xml");

        public Mat DetectTypes(Mat frame, Filters filter)
        {
            if (frame == null || frame.IsDisposed || frame.Empty()) return new Mat();
            var grayImage = new Mat();
            Cv2.CvtColor(frame, grayImage, ColorConversionCodes.BGRA2GRAY);
            Cv2.EqualizeHist(grayImage, grayImage);
            var listtodraw = new List<Rect>();
            var rnd = new Random();
            var color = Scalar.FromRgb(rnd.Next(200, 255), rnd.Next(200, 255), rnd.Next(200, 255));
            if (filter.Face) listtodraw.AddRange(FaceDetection(frame));
            if (filter.LowerBody) listtodraw.AddRange(LowerBodyDetect(frame));
            if (filter.UpperBody) listtodraw.AddRange(UpperBodyDetect(frame));
            foreach (var faceRect in listtodraw)
            {
                var detectedFaceImage = new Mat(frame, faceRect);

                //yield return faceRect;

                Cv2.Rectangle(frame, faceRect, color, 3);


                var detectedFaceGrayImage = new Mat();
                Cv2.CvtColor(detectedFaceImage, detectedFaceGrayImage, ColorConversionCodes.BGRA2GRAY);
            }

            return frame;
        }

        public IEnumerable<Rect> FaceDetection(Mat frame)
        {
            var faces = CascadeFace.DetectMultiScale(
                frame,
                1.1,
                2,
                HaarDetectionType.DoRoughSearch | HaarDetectionType.ScaleImage,
                new Size(30, 30)
            );
            foreach (var faceRect in faces) yield return faceRect;
        }

        public IEnumerable<Rect> UpperBodyDetect(Mat frame)
        {
            var faces = CascadeUpperBody.DetectMultiScale(
                frame,
                1.1,
                3,
                HaarDetectionType.DoRoughSearch | HaarDetectionType.ScaleImage,
                new Size(30, 30));

            foreach (var faceRect in faces) yield return faceRect;
        }

        public IEnumerable<Rect> LowerBodyDetect(Mat frame)
        {
            var faces = CascadeLowerBody.DetectMultiScale(
                frame,
                1.1,
                3,
                HaarDetectionType.DoRoughSearch | HaarDetectionType.ScaleImage,
                new Size(30, 30));

            foreach (var faceRect in faces) yield return faceRect;
        }
    }
}