using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using bbiwarg.Images;
using bbiwarg.Graphics;

namespace bbiwarg.Detectors.Fingers
{
    class FingerTracker
    {
        private OutputImage outputImage;
        private List<Finger>[] detectedFingers;
        private int framesUntilTracked;
        public List<Finger> TrackedFingers { get; private set; }

        public FingerTracker()
        {
            framesUntilTracked = 3;
            detectedFingers = new List<Finger>[framesUntilTracked];
            TrackedFingers = new List<Finger>();

            for (int i = 0; i < framesUntilTracked; i++)
            {
                detectedFingers[i] = new List<Finger>();
            }
        }

        public void setDetectedTouchEventsThisFrame(List<Finger> detectedFingersThisFrame, OutputImage outputImage)
        {
            this.outputImage = outputImage;

            for (int i = (framesUntilTracked - 1); i > 0; i--)
            {
                detectedFingers[i] = detectedFingers[i - 1];
            }
            detectedFingers[0] = detectedFingersThisFrame;


            findTrackedFingers();
        }

        private void findTrackedFingers()
        {
            float minSimilarity = 0.75f;
            TrackedFingers = new List<Finger>();

            foreach (Finger finger in detectedFingers[0])
            {
                bool tracked = true;
                Finger mostSimilarLastFrame = finger;
                for (int i = 1; i < framesUntilTracked; i++)
                {
                    Finger mostSimilarThisFrame = getMostSimilarFingerInFrame(mostSimilarLastFrame, i);
                    if (mostSimilarThisFrame == null || mostSimilarLastFrame.getSimilarity(mostSimilarThisFrame) < minSimilarity)
                    {
                        tracked = false;
                        break;

                    }
                }
                if (tracked)
                {
                    outputImage.drawLineSegment(finger.LineSegment, Constants.FingerTrackedColor);
                    TrackedFingers.Add(finger);
                }
            }
        }

        private Finger getMostSimilarFingerInFrame(Finger finger, int frame)
        {
            Finger mostSimilarFinger = null;
            float maxSimilarity = 0;
            foreach (Finger f in detectedFingers[frame])
            {
                float similarity = finger.getSimilarity(f);
                if (similarity > maxSimilarity)
                {
                    mostSimilarFinger = f;
                    maxSimilarity = similarity;
                }
            }
            return mostSimilarFinger;
        }
    }
}
