internal void ToggleInfoWindow(MapboxMap mapboxMap, Marker marker)
 {
     if (marker.IsInfoWindowShown)
     {
         mapboxMap.DeselectMarker(marker);
     }
     else
     {
         mapboxMap.SelectMarker(marker);
     }
 }
        public void SetupFunctions()
        {
            Element.TakeSnapshotFunc           += TakeMapSnapshot;
            Element.GetFeaturesAroundPointFunc += GetFeaturesAroundPoint;
            Element.ResetPositionAction         = () =>
            {
                //TODO handle reset position call
                //map.ResetNorth();
                //map.AnimateCamera(CameraUpdateFactory.ZoomTo(Element.ZoomLevel));
            };
            Element.UpdateLayerFunc = (string layerId, bool isVisible, bool IsCustom) =>
            {
                if (!string.IsNullOrEmpty(layerId))
                {
                    string layerIdStr = IsCustom ? layerId.Prefix() : layerId;
                    var    layer      = map.GetLayer(layerIdStr);
                    if (layer != null)
                    {
                        layer.SetProperties(layer.Visibility,
                                            isVisible ? Sdk.Style.Layers.PropertyFactory.Visibility(Sdk.Style.Layers.Property.Visible)
                                            : Sdk.Style.Layers.PropertyFactory.Visibility(Sdk.Style.Layers.Property.None));

                        if (IsCustom && Element.MapStyle.CustomLayers != null)
                        {
                            var count = Element.MapStyle.CustomLayers.Count();
                            for (var i = 0; i < count; i++)
                            {
                                if (Element.MapStyle.CustomLayers.ElementAt(i).Id == layerId)
                                {
                                    Element.MapStyle.CustomLayers.ElementAt(i).IsVisible = isVisible;
                                    break;
                                }
                            }
                        }
                        return(true);
                    }
                }
                return(false);
            };

            Element.UpdateShapeOfSourceFunc = (Annotation annotation, string sourceId) =>
            {
                if (annotation != null && !string.IsNullOrEmpty(sourceId))
                {
                    var shape  = annotation.ToFeatureCollection();
                    var source = map.GetSource(sourceId.Prefix()) as Sdk.Style.Sources.GeoJsonSource;
                    if (source != null)
                    {
                        Device.BeginInvokeOnMainThread(() =>
                        {
                            source.SetGeoJson(shape);
                        });
                        if (Element.MapStyle.CustomSources?.FirstOrDefault((arg) => arg.Id == sourceId) is ShapeSource shapeSource)
                        {
                            shapeSource.Shape = annotation;
                        }
                        return(true);
                    }
                }
                return(false);
            };

            Element.ReloadStyleAction = () =>
            {
                //https://github.com/mapbox/mapbox-gl-native/issues/9511
                map.SetStyleUrl(map.StyleUrl, null);
            };

            Element.UpdateViewPortAction = (Position centerLocation, double?zoomLevel, double?bearing, bool animated, Action completionHandler) =>
            {
                var newPosition = new CameraPosition.Builder()
                                  .Bearing(bearing ?? map.CameraPosition.Bearing)
                                  .Target(centerLocation?.ToLatLng() ?? map.CameraPosition.Target)
                                  .Zoom(zoomLevel ?? map.CameraPosition.Zoom)
                                  .Build();
                var callback = completionHandler == null ? null : new CancelableCallback()
                {
                    FinishHandler = completionHandler,
                    CancelHandler = completionHandler
                };
                var update = CameraUpdateFactory.NewCameraPosition(newPosition);
                if (animated)
                {
                    map.AnimateCamera(update, callback);
                }
                else
                {
                    map.MoveCamera(update, callback);
                }
            };

            Element.GetStyleImageFunc += GetStyleImage;

            Element.GetStyleLayerFunc = GetStyleLayer;

            Element.SelectAnnotationAction = (Tuple <string, bool> obj) =>
            {
                if (obj == null || map == null || map.Annotations == null)
                {
                    return;
                }
                foreach (var item in map.Annotations)
                {
                    if (item is Marker marker && marker.Id.ToString() == obj.Item1)
                    {
                        map.SelectMarker(marker);
                    }
                }
            };

            Element.DeselectAnnotationAction = (Tuple <string, bool> obj) =>
            {
                if (obj == null || map == null || map.Annotations == null)
                {
                    return;
                }
                foreach (var item in map.Annotations)
                {
                    if (item is Marker marker && marker.Id.ToString() == obj.Item1)
                    {
                        map.DeselectMarker(marker);
                    }
                }
            };

            Element.ApplyOfflinePackFunc = (offlinePack) =>
            {
                //var region = offlinePack.Region;
                //OfflineTilePyramidRegionDefinition definition = new OfflineTilePyramidRegionDefinition(
                //    region.StyleURL,
                //    LatLngBounds.From(offlinePack.Region.Bounds.NorthEast.Lat, offlinePack.Region.Bounds.NorthEast.Long, offlinePack.Region.Bounds.SouthWest.Lat, offlinePack.Region.Bounds.SouthWest.Long),
                //    region.MinimumZoomLevel,
                //    region.MaximumZoomLevel,
                //    Android.App.Application.Context.Resources.DisplayMetrics.Density);
                //var xxx = new OfflineTilePyramidRegionDefinition(null);
                LatLngBounds   bounds         = LatLngBounds.From(offlinePack.Region.Bounds.NorthEast.Lat, offlinePack.Region.Bounds.NorthEast.Long, offlinePack.Region.Bounds.SouthWest.Lat, offlinePack.Region.Bounds.SouthWest.Long);
                double         regionZoom     = offlinePack.Region.MaximumZoomLevel;
                CameraPosition cameraPosition = new CameraPosition.Builder()
                                                .Target(bounds.Center)
                                                .Zoom(regionZoom)
                                                .Build();
                map.MoveCamera(CameraUpdateFactory.NewCameraPosition(cameraPosition));
                return(true);
            };
        }