using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using bbiwarg.Detectors.Touch;
using bbiwarg.Utility;

namespace bbiwarg.Graphics
{
    class TouchEventVisualizer
    {
        public OutputImage OutputImage { get; private set; }

        private List<Kalman2DPositionFilter> kalmanFilters;
        private List<List<Vector2D>> touchPositions;
        private int lastUpdated = -1;
        private int width, height;

        public TouchEventVisualizer(int width, int height)
        {
            OutputImage = new Graphics.OutputImage(width, height);
            touchPositions = new List<List<Vector2D>>();
            kalmanFilters = new List<Kalman2DPositionFilter>();
            this.width = width;
            this.height = height;
        }

        public void addPalmTouchEvent(PalmTouchEvent e, int currentFrame)
        {
            List<Vector2D> currentList;
            Kalman2DPositionFilter currentFilter;

            bool addList = false;
            if (lastUpdated == -1 || (currentFrame - lastUpdated) > 5)
            {
                currentList = new List<Vector2D>();
                currentFilter = new Kalman2DPositionFilter(e.RelativePalmPosition);
                addList = true;
            }
            else
            {
                currentList = touchPositions.Last<List<Vector2D>>();
                currentFilter = kalmanFilters.Last<Kalman2DPositionFilter>();
            }

            Vector2D pos;
            if (currentFilter == null)
            {
                currentFilter = new Kalman2DPositionFilter(e.RelativePalmPosition);
                pos = e.RelativePalmPosition;
            }
            else 
            {
                pos = currentFilter.getCorrectedPosition(e.RelativePalmPosition);
            }

            currentList.Add(new Vector2D((int)(pos.X * width), (int)(height - pos.Y * height)));
            if (addList)
            {
                touchPositions.Add(currentList);
                kalmanFilters.Add(currentFilter);
            }

            lastUpdated = currentFrame;
        }

        public void updateImage()
        {
            OutputImage = new OutputImage(width, height);
            
            foreach (List<Vector2D> positions in touchPositions)
            {
                for (int i = 1; i < positions.Count; ++i)
                {
                    OutputImage.drawLineSegment(new LineSegment2D(positions[i - 1], positions[i]), Color.White);
                }

                if (touchPositions.Count != 0)
                    OutputImage.fillCircle(positions.Last<Vector2D>().IntX, positions.Last<Vector2D>().IntY, 3, Color.Red);
            }
        }

        public void Reset()
        {
            touchPositions.Clear();
            OutputImage = new OutputImage(width, height);
            lastUpdated = -1;
        }
    }
}