using Microscopic_Traffic_Simulator___Model.GeometricObjects.Lanes;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media;

namespace Microscopic_Traffic_Simulator.Renderers
{
    class GeneratorPossibleLocationsRenderer : VisualCanvasRenderer
    {
        private const double PenThickness = 1.0;
        private const double BoldPenThickness = 2.0;
        private const double CircleRadius = 4.0;
        private const double CircleRadiusSquared = CircleRadius * CircleRadius;

        private Pen pen = new Pen(Brushes.Blue, PenThickness);
        private Pen boldPen = new Pen(Brushes.Blue, BoldPenThickness);        

        private ReadOnlyCollection<Lane> lanes;
        internal ReadOnlyCollection<Lane> Lanes { set { lanes = value; } }

        private Lane laneWithNearestStartPointToCursor = null;

        internal GeneratorPossibleLocationsRenderer(DrawingVisual visual)
            : base(visual)
        {            
            pen.Freeze();
        }        

        protected override void Render(Point currentMouseLocation)
        {
            RenderPossibleLocations(currentMouseLocation);
        }

        internal void MouseMove(Point currentMouseLocation)
        {
            Render(currentMouseLocation);
        }

        internal Lane MouseLeftButtonUp()
        {
            if (laneWithNearestStartPointToCursor == null)
            {
                return null;                
            }
            else
            {
                Lane laneWithNearestStartPointToCursorToReturn = laneWithNearestStartPointToCursor;                                
                return laneWithNearestStartPointToCursorToReturn;
            }            
        }

        internal void Clear()
        {
            laneWithNearestStartPointToCursor = null;
            using (DrawingContext dc = visual.RenderOpen())
            {

            }
        }

        internal void RenderPossibleLocations(Point? currentMouseLocation = null)
        {
            using (DrawingContext dc = visual.RenderOpen())
            {
                dynamic laneWithNearestStartPointToCursor = null;
                foreach (Lane lane in lanes)
                {
                    if (!lane.StartNode.ContainsGenerator)
                    {
                        Point startPointOnCanvas = TransformRealWorldPoint(lane.StartNode.Location);
                        dc.DrawEllipse(null, pen, startPointOnCanvas, CircleRadius, CircleRadius);

                        if (currentMouseLocation.HasValue)
                        {
                            double distanceFromStartPointToCursorSquared =
                                (startPointOnCanvas - currentMouseLocation.Value).LengthSquared;

                            if (distanceFromStartPointToCursorSquared < CircleRadiusSquared &&
                                (laneWithNearestStartPointToCursor == null ||
                                distanceFromStartPointToCursorSquared <
                                laneWithNearestStartPointToCursor.DistanceToStartPointSquared))
                            {
                                laneWithNearestStartPointToCursor = new
                                {
                                    Lane = lane,
                                    DistanceToStartPointSquared = distanceFromStartPointToCursorSquared
                                };
                            }
                        }
                    }
                }
                if (laneWithNearestStartPointToCursor != null)
                {
                    dc.DrawEllipse(null, boldPen,
                        TransformRealWorldPoint(laneWithNearestStartPointToCursor.Lane.StartNode.Location),
                        CircleRadius, CircleRadius);
                    this.laneWithNearestStartPointToCursor = laneWithNearestStartPointToCursor.Lane;
                }
            }
        }
    }
}
