private void selectNextPolygonPoint()
        {
            if (LastSelectedShapePolygonPoints == null && LastSelectedShape != null)
            {
                LastSelectedShapePolygonPoints = LastSelectedShape.GetPolygonPointsObserver();
                UpdateLastSelectedPolygonPoints();
            }
            if (LastSelectedShapePolygonPoints != null)
            {
                PolyPointDescriptor point;
                if (LastSelectedShapePolygonPoints.HasPoints())
                {
                    if (!LastSelectedShapePolygonPoints.HasNext())
                    {
                        LastSelectedShapePolygonPoints.ResetIterator();
                    }
                    point = LastSelectedShapePolygonPoints.Next();
                }
                else
                {
                    point = new PolyPointDescriptor();
                }

                SpeakPolygonPoint(LastSelectedShapePolygonPoints);
                fire_PolygonPointSelected(LastSelectedShapePolygonPoints, point);
            }
            else
            {
                fire_PolygonPointSelected_Reset();
            }
        }
        private void selectPreviousePolygonPoint()
        {
            if (LastSelectedShapePolygonPoints != null)
            {
                PolyPointDescriptor point;
                if (LastSelectedShapePolygonPoints.HasPoints())
                {
                    if (LastSelectedShapePolygonPoints.HasPrevious())
                    {
                        point = LastSelectedShapePolygonPoints.Previous();
                    }
                    else
                    {
                        point = LastSelectedShapePolygonPoints.Last();
                    }
                }
                else
                {
                    point = new PolyPointDescriptor();
                }

                SpeakPolygonPoint(LastSelectedShapePolygonPoints);
                fire_PolygonPointSelected(LastSelectedShapePolygonPoints, point);
            }
            else
            {
                fire_PolygonPointSelected_Reset();
            }
        }
 public Point TransformPointCoordinatesIntoScreenCoordinates(PolyPointDescriptor polyPointDescriptor)
 {
     return TransformPointCoordinatesIntoScreenCoordinates(polyPointDescriptor.X, polyPointDescriptor.Y);
 }
 /// <summary>
 /// Adds or updates a poly point descriptor. Point will be updated if it already exist; otherwise it will be added.
 /// </summary>
 /// <param name="ppd">The descriptor for a poly polygon point.</param>
 /// <param name="index">The one-dimensional index of the poly point to add to. A index &lt;= 0 will add the point as fist; an index &gt;= the length of the list will add it as last. Default is <c>Int32.MaxValue</c></param>
 /// <param name="updateDirectly">if set to <c>true</c> the point lists will be updated in the shape properties directly;
 /// otherwise you have to call <see cref="WritePointsToPolygon" /> manually.
 /// NOTICE: disable this if you manipulate a whole bunch of points. Updating all changed point at once is much faster!
 /// ATTENTION: your changes could bee overwritten by calling the <see cref="Update" />function.
 /// Default is <c>true</c></param>
 /// <param name="geometry">if set to <c>true</c> the 'Geometry' property is used (these are the untransformed coordinates of the polygon). Default is <c>false</c></param>
 /// <returns>
 ///   <c>true</c> if the point could be added
 /// </returns>
 public bool AddOrUpdatePolyPointDescriptor(PolyPointDescriptor ppd, int index = Int32.MaxValue, bool updateDirectly = true, bool geometry = false)
 {
     int i, pi;
     Transform1DindexTo2DpolyPolygonIndex(index, out i, out pi);
     return AddOrUpdatePolyPointDescriptor(ppd, i, pi, updateDirectly, geometry);
 }
        /// <summary>
        /// Adds or updates a poly point descriptor. Point will be updated if it already exist; otherwise it will be added.
        /// </summary>
        /// <param name="ppd">The descriptor for a poly polygon point.</param>
        /// <param name="index">The index of the poly point to add to. A index &lt;= 0 will add the point as fist; an index &gt;= the length of the list will add it as last. Default is <c>Int32.MaxValue</c></param>
        /// <param name="polygonIndex">Index of the polygon if this is a poly polygon. Default is 0</param>
        /// <param name="updateDirectly">if set to <c>true</c> the point lists will be updated in the shape properties directly;
        /// otherwise you have to call <see cref="WritePointsToPolygon" /> manually.
        /// NOTICE: disable this if you manipulate a whole bunch of points. Updating all changed point at once is much faster!
        /// ATTENTION: your changes could bee overwritten by calling the <see cref="Update" />function.
        /// Default is <c>true</c></param>
        /// <param name="geometry">if set to <c>true</c> the 'Geometry' property is used (these are the untransformed coordinates of the polygon). Default is <c>false</c></param>
        /// <returns>
        ///   <c>true</c> if the point could be added
        /// </returns>
        public bool AddOrUpdatePolyPointDescriptor(PolyPointDescriptor ppd, int index, int polygonIndex, bool updateDirectly = true, bool geometry = false)
        {
            if (IsValid())
            {
                try
                {
                    _updating = true;
                    if (CachedPolyPointList != null && CachedPolyPointList.Count > polygonIndex)
                    {
                        if (CachedPolyPointList[polygonIndex] != null && CachedPolyPointList[polygonIndex].Count > index)
                        {
                            return UpdatePolyPointDescriptor(ppd, index, polygonIndex, updateDirectly, geometry);
                        }
                        else
                        {
                            return AddPolyPointDescriptor(ppd, index, polygonIndex, updateDirectly, geometry);
                        }
                    }
                }
                finally { _updating = false; }
            }

            return false;
        }
        /// <summary>
        /// Adds a poly point descriptor.
        /// </summary>
        /// <param name="ppd">The descriptor for a poly polygon point.</param>
        /// <param name="index">The index of the poly point to add to. A index &lt;= 0 will add the point as fist; an index &gt; the length of the list will add it as last. Default is <c>Int32.MaxValue</c></param>
        /// <param name="polygonIndex">Index of the polygon if this is a poly polygon.  Default is 0</param>
        /// <param name="updateDirectly">if set to <c>true</c> the point lists will be updated in the shape properties directly;
        /// otherwise you have to call <see cref="WritePointsToPolygon" /> manually.
        /// NOTICE: disable this if you manipulate a whole bunch of points. Updating all changed point at once is much faster!
        /// ATTENTION: your changes could bee overwritten by calling the <see cref="Update" />function.
        /// Default is <c>true</c></param>
        /// <param name="geometry">if set to <c>true</c> the 'Geometry' property is used (these are the untransformed coordinates of the polygon). Default is <c>false</c></param>
        /// <returns>
        ///   <c>true</c> if the point could be added
        /// </returns>
        public bool AddPolyPointDescriptor(PolyPointDescriptor ppd, int index = Int32.MaxValue, int polygonIndex = 0, bool updateDirectly = true, bool geometry = false)
        {
            if (IsValid())
            {
                if (CachedPolyPointList != null)
                {
                    try
                    {
                        _updating = true;
                        if (CachedPolyPointList.Count > polygonIndex)
                        {
                            if (CachedPolyPointList[polygonIndex] == null) CachedPolyPointList[polygonIndex] = new List<PolyPointDescriptor>();
                            if (index < CachedPolyPointList[polygonIndex].Count) { CachedPolyPointList[polygonIndex].Insert(Math.Max(index, 0), ppd); }
                            else { CachedPolyPointList[polygonIndex].Add(ppd); }
                        }
                        else
                        {
                            CachedPolyPointList.Add(
                                new List<PolyPointDescriptor>(){
                                ppd
                            }
                            );
                        }

                        if (updateDirectly) { return WritePointsToPolygon(geometry); }
                        else { return true; }
                    }
                    finally { _updating = false; }
                }

            }
            return false;
        }
 /// <summary>
 /// Updates a poly point descriptor.
 /// </summary>
 /// <param name="ppd">The descriptor for a poly polygon point.</param>
 /// <param name="index">The index of the poly point to update.</param>
 /// <param name="polygonIndex">Index of the polygon if this is a poly polygon. Default is 0</param>
 /// <param name="updateDirectly">if set to <c>true</c> the point lists will be updated in the shape properties directly; 
 /// otherwise you have to call <see cref="WritePointsToPolygon"/> manually.
 /// NOTICE: disable this if you manipulate a whole bunch of points. Updating all changed point at once is much faster!
 /// ATTENTION: your changes could bee overwritten by calling the <see cref="Update"/>function.
 /// Default is <c>true</c></param>
 /// <param name="geometry">if set to <c>true</c> the 'Geometry' property is used (these are the untransformed coordinates of the polygon). Default is <c>false</c></param>
 /// <returns><c>true</c> if the point could be updated</returns>
 public bool UpdatePolyPointDescriptor(PolyPointDescriptor ppd, int index, int polygonIndex, bool updateDirectly = true, bool geometry = false)
 {
     if (IsValid())
     {
         try
         {
             _updating = true;
             if (CachedPolyPointList != null && CachedPolyPointList.Count > polygonIndex)
             {
                 if (CachedPolyPointList[polygonIndex] == null) CachedPolyPointList[polygonIndex] = new List<PolyPointDescriptor>();
                 if (CachedPolyPointList[polygonIndex].Count > index)
                 {
                     CachedPolyPointList[polygonIndex][index] = ppd;
                     if (updateDirectly) { return WritePointsToPolygon(geometry); }
                     else { return true; }
                 }
             }
         }
         finally { _updating = false; }
     }
     return false;
 }