/// <summary>
        /// Selects the first polygon point.
        /// </summary>
        public void SelectFirstPolygonPoint()
        {
            Logger.Instance.Log(LogPriority.DEBUG, this, "[NOTICE]\t[INTERACTION]\t[NAVIGATION]\t" + "first poly point");

            if (LastSelectedShapePolygonPoints == null && LastSelectedShape != null)
            {
                var pObs = LastSelectedShape.GetPolygonPointsObserver();
                if (pObs != null)
                {
                    LastSelectedShapePolygonPoints = pObs;
                }
            }

            if (LastSelectedShapePolygonPoints != null)
            {
                PolyPointDescriptor point;
                if (LastSelectedShapePolygonPoints.HasPoints())
                {
                    point = LastSelectedShapePolygonPoints.First();
                }
                else
                {
                    point = new PolyPointDescriptor();
                }

                SpeakPolygonPoint(LastSelectedShapePolygonPoints);
                fire_PolygonPointSelected(LastSelectedShapePolygonPoints, point);
            }
            else
            {
                fire_PolygonPointSelected_Reset();
            }
        }
        /// <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>
        virtual 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>
 /// 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>
 virtual 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);
 }
        /// <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>
        virtual 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>
        /// Selects the previous polygon point.
        /// </summary>
        public void SelectPreviousPolygonPoint(bool ignoreLastDuplicate = true)
        {
            Logger.Instance.Log(LogPriority.DEBUG, this, "[NOTICE]\t[INTERACTION]\t[NAVIGATION]\t" + "previous poly point");

            if (LastSelectedShapePolygonPoints == null && LastSelectedShape != null)
            {
                var pObs = LastSelectedShape.GetPolygonPointsObserver();
                if (pObs != null)
                {
                    LastSelectedShapePolygonPoints = pObs;
                }
            }

            if (LastSelectedShapePolygonPoints != null)
            {
                PolyPointDescriptor point;
                if (LastSelectedShapePolygonPoints.HasPoints())
                {
                    if (LastSelectedShapePolygonPoints.HasPrevious())
                    {
                        point = LastSelectedShapePolygonPoints.Previous();
                    }
                    else
                    {
                        point = LastSelectedShapePolygonPoints.Last();
                        if (ignoreLastDuplicate && LastSelectedShapePolygonPoints.HasPrevious())
                        {
                            point = LastSelectedShapePolygonPoints.Previous();
                        }
                    }
                }
                else
                {
                    point = new PolyPointDescriptor();
                }

                SpeakPolygonPoint(LastSelectedShapePolygonPoints);
                fire_PolygonPointSelected(LastSelectedShapePolygonPoints, point);
            }
            else
            {
                fire_PolygonPointSelected_Reset();
            }
        }
        /// <summary>
        /// Selects the next following polygon point.
        /// </summary>
        /// <param name="ignoreLastDuplicate">if set to <c>true</c> to ignore the last point of an closed bezier,
        /// because it's the same as the first point..</param>
        public void SelectNextPolygonPoint(bool ignoreLastDuplicate = true)
        {
            // check if the shape is closed or not


            Logger.Instance.Log(LogPriority.DEBUG, this, "[NOTICE]\t[INTERACTION]\t[NAVIGATION]\t" + "next poly point");

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

                SpeakPolygonPoint(LastSelectedShapePolygonPoints);
                fire_PolygonPointSelected(LastSelectedShapePolygonPoints, point);
            }
            else
            {
                fire_PolygonPointSelected_Reset();
            }
        }
        /// <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>
        virtual 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>
 /// Transforms a point, which is in document coordinates, into pixel coordinates on screen,
 /// taking into account the current zoom level of the drawing application.
 /// </summary>
 /// <param name="polyPointDescriptor">The polygon point to transform.</param>
 /// <returns>
 /// The estimated pixel position of the point on the screen.
 /// </returns>
 public Point TransformPointCoordinatesIntoScreenCoordinates(PolyPointDescriptor polyPointDescriptor)
 {
     return(TransformPointCoordinatesIntoScreenCoordinates(polyPointDescriptor.X, polyPointDescriptor.Y));
 }