public void ModPoint(GardenPoint gardenPoint, int idx)
        {
            if (idx < 0 || idx > Points.Count)
            {
                throw new IndexOutOfRangeException($"index {idx} is out of range [0, ..., {Points.Count-1}]");
            }

            Points[idx] = gardenPoint;
        }
        public void AddPoint(GardenPoint gardenPoint, int idx)
        {
            if (idx < 0)
            {
                idx = 0;
            }
            if (idx > Points.Count)
            {
                idx = Points.Count;
            }

            Points.Insert(idx, gardenPoint);
        }
        /// <summary>
        /// Checks for point near the given point <paramref name="cp"/> within a distance of <paramref name="range"/>
        /// </summary>
        public GardenPoint GetPointInRange(GardenPoint cp, int range = 10, int xoffset = 0, int yoffset = 0, double zoom = GardenPoint.STD_ZOOM)
        {
            GardenPoint result = null;
            GardenPoint offset = new GardenPoint(xoffset, yoffset);

            foreach (GardenPoint sp in Points)
            {
                GardenPoint zoomed = sp * zoom + offset;
                if (Math.Abs(zoomed.X - cp.X) < range && Math.Abs(zoomed.Y - cp.Y) < range)
                {
                    result = sp;
                    break;
                }
            }
            return(result);
        }
        public bool ContainsPointOnEdge(GardenPoint p, int xoffset = 0, int yoffset = 0, double zoom = GardenPoint.STD_ZOOM)
        {
            if (Points.Count < 2)
            {
                return(false);
            }

            GardenPoint offset = new GardenPoint(xoffset, yoffset);

            bool found = p.Between(Points[Points.Count - 1] * zoom + offset, Points[0] * zoom + offset);

            for (int i = 0; !found && i < Points.Count - 1; i++)
            {
                found = p.Between(Points[i] * zoom + offset, Points[i + 1] * zoom + offset);
            }
            return(found);
        }
        public bool Between(GardenPoint p1, GardenPoint p2)
        {
            GardenPoint vec = p1 - p2;

            //System.Console.WriteLine("p1 is " + p1);
            //System.Console.WriteLine("p2 is " + p2);
            //System.Console.WriteLine("this is " + this);
            //System.Console.WriteLine("vec is " + vec);
            //vec + p2 == p1
            //this == p2 + vec * f where 0 < f < 1
            for (float f = 0; f <= 1; f += 0.1f)
            {
                //System.Console.WriteLine("...checking " + (p2 + (vec * f)));
                if (this.Equals(p2 + (vec * f), 20))
                {
                    return(true);
                }
            }
            return(false);
        }
        public void ModPoint(GardenPoint oldPoint, GardenPoint newPoint, bool multiple = false)
        {
            List <int> mod = new List <int>();

            for (int i = 0; i < Points.Count; i++)
            {
                GardenPoint point = Points[i];
                if (point == oldPoint || point.X == oldPoint.X && point.Y == oldPoint.Y)
                {
                    mod.Add(i);
                    if (!multiple)
                    {
                        break;
                    }
                }
            }

            foreach (int idx in mod)
            {
                ModPoint(newPoint, idx);
            }
        }
        /// <summary>
        /// Returns the point that is the most left of all points and the most top point of those
        /// </summary>
        public GardenPoint GetTopLeftPoint()
        {
            if (Points.Count == 0)
            {
                return(new GardenPoint(0, 0));
            }

            GardenPoint result = Points[0];

            foreach (GardenPoint p in Points)
            {
                if (p.X < result.X)
                {
                    result = p;
                    continue;
                }
                else if (p.X == result.X && p.Y < result.Y)
                {
                    result = p;
                }
            }
            return(result);
        }
 public void AddPoint(GardenPoint gardenPoint) => AddPoint(gardenPoint, Points.Count);
 public void RemovePoint(GardenPoint point) => RemovePoint(point.X, point.Y);