/// <summary>
        /// Adds a polygon that will be drawn on the next Draw() call.
        /// A polygon is a filled shape.
        /// </summary>
        /// <param name="pl">The polyline that defines the polygon's border. Must be closed</param>
        /// <param name="color">The filling color</param>
        public void AddCompletePolygon(Polyline pl, Color color)
        {
            List<Adjacency> pointList = new List<Adjacency>();
            List<Line> lineList = pl.lineList;

            if (lineList.Count > 2)
            {
                Adjacency prevAdjacency = new Adjacency();
                Adjacency newAdjacency;
                prevAdjacency.point = lineList[0].p1;
                //lineList.RemoveAt(0);
                foreach (Line l in lineList.GetRange(1, lineList.Count-1))
                {
                    newAdjacency = new Adjacency();
                    prevAdjacency.adj2 = newAdjacency;
                    pointList.Add(prevAdjacency);
                    newAdjacency.adj1 = prevAdjacency;
                    newAdjacency.point = l.p1;
                    prevAdjacency = newAdjacency;
                }
                // linking last point to first point
                prevAdjacency.adj2 = pointList[0];
                pointList.Add(prevAdjacency);
                pointList[0].adj1 = prevAdjacency;

                pointList.Sort(Adjacency.CompareX);

                AddPolygon(pointList, color);
            }
        }
        public Wall(Polyline _polyline, float thickness)
        {
            List<Model.Point> points = new List<Model.Point>();
            Vector2 perpendicularVector = new Vector2(_polyline.lineList[0].p2.y - _polyline.lineList[0].p1.y,
                -(_polyline.lineList[0].p2.x - _polyline.lineList[0].p1.x));
            perpendicularVector.Normalize();
            perpendicularVector *= thickness/2;
            // point translation
            Model.Point p11 = new Point(_polyline.lineList[0].p1.x + perpendicularVector.X, _polyline.lineList[0].p1.y + perpendicularVector.Y);
            Model.Point p12 = new Point(_polyline.lineList[0].p1.x - perpendicularVector.X, _polyline.lineList[0].p1.y - perpendicularVector.Y);
            Model.Point p21 = new Point(_polyline.lineList[0].p2.x + perpendicularVector.X, _polyline.lineList[0].p2.y + perpendicularVector.Y);
            Model.Point p22 = new Point(_polyline.lineList[0].p2.x - perpendicularVector.X, _polyline.lineList[0].p2.y - perpendicularVector.Y);

            // adding two first points
            points.Add(p11);
            points.Add(p12);
            Line line11 = new Line(p11, p21);
            Line line12 = new Line(p12, p22);
            ///Vector2 line12 = new Vector2(p12.x - p22.x, p21.y - p22.y);
            foreach (Line l in _polyline.lineList.GetRange(1, _polyline.lineList.Count-1))
            {
                perpendicularVector = new Vector2(l.p2.y - l.p1.y, -(l.p2.x - l.p1.x));
                perpendicularVector.Normalize();
                perpendicularVector *= thickness/2;
                // point translation
                p11 = new Point(l.p1.x + perpendicularVector.X, l.p1.y + perpendicularVector.Y);
                p12 = new Point(l.p1.x - perpendicularVector.X, l.p1.y - perpendicularVector.Y);
                p21 = new Point(l.p2.x + perpendicularVector.X, l.p2.y + perpendicularVector.Y);
                p22 = new Point(l.p2.x - perpendicularVector.X, l.p2.y - perpendicularVector.Y);

                Line line21 = new Line(p11, p21);
                Line line22 = new Line(p12, p22);

                // line intersection
                Model.Point? intersect1 = Utils.InfiniteLineIntersect(line11, line21);
                Model.Point? intersect2 = Utils.InfiniteLineIntersect(line12, line22);

                if (intersect1.HasValue)
                {
                    points.Insert(0, intersect1.Value);
                }
                if (intersect2.HasValue)
                {
                    points.Add(intersect2.Value);
                }

                line11 = line21;
                line12 = line22;

            }
            // adding two last points
            points.Insert(0, p21);
            points.Add(p22);
            points.Add(p21);

            polyline = new Polyline(points);
        }
 public Obstacle(Polyline _polyline, float _height)
 {
     height = _height;
     //verify that the obstacle is closed
     if (_polyline.lineList[0].p1.Equals(_polyline.lineList[_polyline.lineList.Count - 1].p2))
     {
         polyline = _polyline;
     }
     else
     {
         Line newLine = new Line(_polyline.lineList[_polyline.lineList.Count - 1].p2, _polyline.lineList[0].p1);
         _polyline.lineList.Add(newLine);
         polyline = _polyline;
     }
 }
 public Wall(Polyline _polyline)
 {
     polyline = _polyline;
 }
 // TODO : used for testing purpose, remove or rework
 public Obstacle(Polyline _polyline)
 {
     polyline = _polyline;
     height = -1;
 }
        /// <summary>
        /// Constructor and parser
        /// </summary>
        /// <param name="map">Path for the xml map</param>
        public XMLReader(string map)
        {
            XElement mapDocument = XElement.Load(map);
            IEnumerable<XElement> mapElements = mapDocument.Elements();
            foreach (var mapElement in mapElements)
            {
                //Initial loop
                if (mapElement.Name == "frame")
                {
                    IEnumerable<XElement> frameElements = mapElement.Elements();

                    foreach (var frameElement in frameElements)
                    {
                        //loop to define the frame
                        float x = (float)frameElement.Attribute("x");
                        float y = (float)frameElement.Attribute("y");

                        if (frameElement.Name == "upperLeft")
                        {
                            upperLeft = new Point(x, y);
                        }
                        else if (frameElement.Name == "lowerRight")
                        {
                            lowerRight = new Point(x, y);
                        }
                    }
                }

                if (mapElement.Name == "object")
                {
                    IEnumerable<XElement> frameObjects = mapElement.Elements();
                    foreach (var frameObject in frameObjects)
                    {
                        //loop for the different objects (actually, obstacle and walls)
                        if (frameObject.Name == "obstacle")
                        {
                            float height = (float)frameObject.Attribute("height");
                            List<Point> pointList = new List<Point>();
                            IEnumerable<XElement> framePoints = frameObject.Elements();
                            foreach (var framePoint in framePoints)
                            {
                                //loop to get all the points of one obstacle
                                float x = (float)framePoint.Attribute("x");
                                float y = (float)framePoint.Attribute("y");
                                Point point = new Point(x, y);
                                pointList.Add(point);
                            }
                            Polyline polyline = new Polyline(pointList);
                            Obstacle obstacle = new Obstacle(polyline, height);
                            listObstacle.Add(obstacle);

                        }

                        if (frameObject.Name == "wall")
                        {
                            //loop for walls
                            float thickness = (float)frameObject.Attribute("thickness");
                            List<Point> pointListWall = new List<Point>();

                            IEnumerable<XElement> framePoints = frameObject.Elements();
                            foreach (var framePoint in framePoints)
                            {
                                //loop to get all the points of one wall
                                float x = (float)framePoint.Attribute("x");
                                float y = (float)framePoint.Attribute("y");
                                Point point = new Point(x, y);
                                pointListWall.Add(point);
                            }
                            Polyline polyline = new Polyline(pointListWall);
                            Wall wall = new Wall(polyline, thickness);
                            listWall.Add(wall);
                        }
                    }

                }

               /* Console.WriteLine("lower left : " + upperLeft.x);
                Console.WriteLine("lower right : " + upperLeft.x);
                Console.WriteLine("upper left : " + lowerRight.x);
                Console.WriteLine("upper right : " + lowerRight.x);

                Console.WriteLine("obstacle");
                for (int i = 0; i < listObstacle.Count; i++)
                {
                    Console.WriteLine(listObstacle[i].polyline.ToString());
                }

                Console.WriteLine("wall");
                for (int i = 0; i < listWall.Count; i++)
                {
                    Console.WriteLine(listWall[i].ToString());
                }*/

            }
        }
 /// <summary>
 /// adds a polyline to be drawn on the newt Draw() call.
 /// </summary>
 /// <param name="pl">The polyline to draw</param>
 /// <param name="color">The color of the polyline</param>
 public void AddPolyline(Polyline pl, Color color)
 {
     List<VertexPositionColor> vertices = new List<VertexPositionColor>();
     if( pl.lineList.Count != 0 )
     {
         vertices.Add( new VertexPositionColor(ToVector3(pl.lineList[0].p1), color) );
         foreach( Line line in pl.lineList )
         {
             vertices.Add( new VertexPositionColor(ToVector3(line.p2), color) );
         }
     }
     polylines.Add(vertices);
 }