// =========================================================================
        // Constructor
        // =========================================================================
        public FrmMeasurement()
        {
            InitializeComponent();
            _ci = CultureInfo.InvariantCulture;
            _frmGlobespotter = null;
            SetOpenClose(false);
            _entityId          = 0;
            _pointId           = 0;
            _measurementPoint  = null;
            _imageIdColor      = new Dictionary <string, Color>();
            _bitmapImageId     = new List <string>();
            _idBitmap          = new List <Bitmap>();
            _commandItem       = null;
            _measurementPointS = null;
            _lastPointIdUpd    = null;
            _config            = Config.Instance;
            _goToClicked       = false;

            Font font = SystemFonts.MenuFont;

            lvObservations.Font       = (Font)font.Clone();
            plButtons.Font            = (Font)font.Clone();
            plMeasurementDetails.Font = (Font)font.Clone();
            txtPosition.Font          = (Font)font.Clone();
            txtPositionStd.Font       = (Font)font.Clone();
            txtNumber.Font            = (Font)font.Clone();
        }
        private void OpenNewPoint(MeasurementPointS pointS)
        {
            Measurement measurement = Measurement.Get(_entityId);

            if ((measurement != null) && (pointS != null))
            {
                measurement.OpenPoint(pointS.PointId);
            }
        }
        private void ClearForm(bool values)
        {
            foreach (var idBitmap in _idBitmap)
            {
                idBitmap.Dispose();
            }

            lvObservations.Items.Clear();
            _bitmapImageId.Clear();
            _idBitmap.Clear();

            if (values)
            {
                _entityId          = 0;
                _pointId           = 0;
                _measurementPoint  = null;
                _measurementPointS = null;
                SetOpenClose(false);
            }
        }
        private void RemovePoint(int entityId, int pointId)
        {
            if ((entityId == _entityId) && (_pointId == pointId))
            {
                ClearForm(false);
                DrawObservations();
                txtNumber.Text      = string.Empty;
                txtPosition.Text    = string.Empty;
                txtPositionStd.Text = string.Empty;
                RelO.Image          = null;
                Measurement measurement = Measurement.Get(entityId);

                if (measurement.Count >= 1)
                {
                    MeasurementPointS pointS = measurement.GetPointByNr(measurement.Count - 1);
                    pointId = pointS.PointId;
                    List <MeasurementObservation> observations = _frmGlobespotter.GetObservationPoints(entityId, pointId);
                    MeasurementPoint measurementPoint          = _frmGlobespotter.GetMeasurementData(entityId, pointId);

                    foreach (var measurementObservation in observations)
                    {
                        if (measurementObservation != null)
                        {
                            AddObs(null, _frmGlobespotter, entityId, pointId, measurementObservation);
                        }
                    }

                    if (measurementPoint != null)
                    {
                        UpdatePoint(_frmGlobespotter, measurementPoint, entityId, pointId, true);
                    }
                }
                else
                {
                    ClearForm(true);
                }
            }
        }
        private void UpdatePoint(FrmGlobespotter frmGlobespotter, MeasurementPoint point, int entityId, int pointId, bool alwaysOpen)
        {
            if (_entityId != entityId)
            {
                _lastPointIdUpd = null;
            }

            if (_lastPointIdUpd == null)
            {
                _lastPointIdUpd = pointId;
            }
            else if (pointId > _lastPointIdUpd)
            {
                _lastPointIdUpd = pointId;
            }

            if ((pointId == _lastPointIdUpd) || (_entityId != entityId) || alwaysOpen)
            {
                _frmGlobespotter = frmGlobespotter;
                bool smartClick = _config.SmartClickEnabled;

                if (!smartClick)
                {
                    AddObservations(entityId, pointId);
                }

                if ((entityId != _entityId) || _goToClicked ||
                    (((pointId != _pointId) && (!smartClick)) || ((_lastPointIdUpd > _pointId) && smartClick)))
                {
                    ClearForm(false);
                    _entityId = entityId;
                    _pointId  = pointId;
                    DrawObservations();
                }

                _measurementPoint =
                    ((double.IsNaN(point.x)) && (double.IsNaN(point.y)) && (double.IsNaN(point.z))) ? null : point;
                Measurement measurement = Measurement.Get(_entityId);
                _measurementPointS = measurement[_pointId];
                var circle = new Bitmap(18, 18);

                using (var ga = Graphics.FromImage(circle))
                {
                    ga.Clear(Color.Transparent);
                    Brush color = point.reliableEstimate
                          ? Brushes.Green
                          : ((lvObservations.Items.Count == 0) ? Brushes.Gray : Brushes.Red);
                    ga.DrawEllipse(new Pen(color, 1), 2, 2, 14, 14);
                    ga.FillEllipse(color, 2, 2, 14, 14);
                }

                txtNumber.Text = _measurementPointS.M.ToString(_ci);
                string x = (double.IsNaN(point.x)) ? "---" : point.x.ToString("#0.00", _ci);
                string y = (double.IsNaN(point.y)) ? "---" : point.y.ToString("#0.00", _ci);
                string z = (double.IsNaN(point.z)) ? "---" : point.z.ToString("#0.00", _ci);
                txtPosition.Text = string.Format(_ci, "{0}, {1}, {2}", x, y, z);
                string stdx = (double.IsNaN(point.Std_x)) ? "---" : point.Std_x.ToString("#0.00", _ci);
                string stdy = (double.IsNaN(point.Std_y)) ? "---" : point.Std_y.ToString("#0.00", _ci);
                string stdz = (double.IsNaN(point.Std_z)) ? "---" : point.Std_z.ToString("#0.00", _ci);
                txtPositionStd.Text = string.Format(_ci, "{0}, {1}, {2}", stdx, stdy, stdz);
                RelO.Image          = circle;
                SetOpenClose(_opened);
            }
        }
        // =========================================================================
        // Private Functions
        // =========================================================================
        private void AddObs(Bitmap bitmap, FrmGlobespotter frmGlobespotter, int entityId, int pointId,
                            MeasurementObservation observation)
        {
            if (_entityId != entityId)
            {
                _lastPointIdUpd = null;
            }

            string               imageId      = observation.imageId;
            GsExtension          extension    = GsExtension.GetExtension();
            CycloMediaGroupLayer groupLayer   = extension.CycloMediaGroupLayer;
            IMappedFeature       locationInfo = groupLayer.GetLocationInfo(imageId);
            var    recordingInfo = locationInfo as Recording;
            double stdX          = (recordingInfo == null) ? 0 : (recordingInfo.LongitudePrecision ?? 0);
            double stdY          = (recordingInfo == null) ? 0 : (recordingInfo.LatitudePrecision ?? 0);
            double stdZ          = (recordingInfo == null) ? 0 : (recordingInfo.HeightPrecision ?? 0);
            string std           = string.Format("{0:0.00} {1:0.00} {2:0.00}", stdX, stdY, stdZ);

            if ((_entityId != entityId) || (_pointId != pointId))
            {
                ClearForm(false);
                _entityId           = entityId;
                _pointId            = pointId;
                _measurementPoint   = null;
                _measurementPointS  = null;
                txtNumber.Text      = string.Empty;
                txtPosition.Text    = string.Empty;
                txtPositionStd.Text = string.Empty;
                RelO.Image          = null;
                SetOpenClose(false);
            }

            Measurement measurement = Measurement.Get(_entityId);

            if (measurement != null)
            {
                _measurementPointS = measurement[_pointId];
                _measurementPointS.UpdateObservation(imageId, observation.x, observation.y, observation.z);
                txtNumber.Text = _measurementPointS.M.ToString(_ci);

                if (measurement.IsPointMeasurement)
                {
                    SetOpenClose(true);

                    if (_commandItem == null)
                    {
                        _commandItem = ArcMap.Application.CurrentTool;
                        ArcUtils.SetToolActiveInToolBar("esriEditor.EditTool");
                    }
                }
            }

            if (bitmap != null)
            {
                _bitmapImageId.Add(imageId);
                _idBitmap.Add(bitmap);
            }

            bool add = true;

            foreach (ListViewItem item in lvObservations.Items)
            {
                var obs = item.Tag as MeasurementObservation;

                if (obs != null)
                {
                    if (obs.imageId == imageId)
                    {
                        add = false;
                    }
                }
            }

            if (add)
            {
                _frmGlobespotter = frmGlobespotter;
                var items        = new[] { imageId, std, "X" };
                var listViewItem = new ListViewItem(items)
                {
                    Tag = observation
                };
                lvObservations.Items.Add(listViewItem);
                DrawObservations();
                RedrawObservationList();
            }
        }
        private static void OnCurrentTaskChanged()
        {
            try
            {
                IEditor3 editor = ArcUtils.Editor;
                LogClient.Info("On CurrentTask Changed");
                _doSelection = true;

                if (editor != null)
                {
                    var sketch     = editor as IEditSketch3;
                    var editLayers = editor as IEditLayers;

                    if ((sketch != null) && (editLayers != null))
                    {
                        IEditTask   task         = editor.CurrentTask;
                        ILayer      currentLayer = editLayers.CurrentLayer;
                        VectorLayer vectorLayer  = (EditFeatures.Count != 1)
              ? ((currentLayer == null) ? null : GetLayer(currentLayer))
              : GetLayer(EditFeatures[0]);

                        if ((task != null) && ((vectorLayer != null) && (vectorLayer.IsVisibleInGlobespotter)))
                        {
                            var taskName = task as IEditTaskName;

                            if (taskName != null)
                            {
                                IGeometry geometry = sketch.Geometry;
                                string    name     = taskName.UniqueName;

                                if (name == "GarciaUI_ModifyFeatureTask")
                                {
                                    Measurement measurement = Measurement.Get(geometry, false);

                                    if (measurement != null)
                                    {
                                        int nrPoints;
                                        var ptColl = measurement.ToPointCollection(geometry, out nrPoints);

                                        if (ptColl != null)
                                        {
                                            ISketchOperation2 sketchOp = new SketchOperationClass();
                                            sketchOp.Start(editor);

                                            for (int j = 0; j < nrPoints; j++)
                                            {
                                                IPoint           point  = ptColl.Point[j];
                                                MeasurementPoint mpoint = measurement.IsPointMeasurement
                          ? measurement.GetPoint(point, false)
                          : measurement.GetPoint(point);

                                                double m      = (mpoint == null) ? double.NaN : mpoint.M;
                                                double z      = (mpoint == null) ? double.NaN : mpoint.Z;
                                                IPoint point2 = new PointClass {
                                                    X = point.X, Y = point.Y, Z = z, M = m, ZAware = sketch.ZAware
                                                };
                                                ptColl.UpdatePoint(j, point2);

                                                if (measurement.IsPointMeasurement)
                                                {
                                                    sketch.Geometry = point2;
                                                }
                                            }

                                            if (!measurement.IsPointMeasurement)
                                            {
                                                sketch.Geometry = ptColl as IGeometry;
                                            }

                                            geometry = sketch.Geometry;

                                            if (geometry != null)
                                            {
                                                sketchOp.Finish(geometry.Envelope, esriSketchOperationType.esriSketchOperationGeneral, geometry);
                                            }
                                        }

                                        measurement.SetSketch();
                                        measurement.OpenMeasurement();
                                        measurement.DisableMeasurementSeries();
                                    }
                                }
                                else
                                {
                                    Measurement measurement = Measurement.Get(geometry, false);

                                    if (measurement != null)
                                    {
                                        measurement.EnableMeasurementSeries();
                                    }

                                    OnSelectionChanged();
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                LogClient.Error("VectorLayer.OnCurrentTaskChanged", ex.Message, ex);
                Trace.WriteLine(ex.Message, "VectorLayer.OnCurrentTaskChanged");
            }
        }