package mx.trackermap.TrackerMap.android.map import android.os.Bundle import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.core.text.HtmlCompat import androidx.fragment.app.Fragment import androidx.fragment.app.commit import mx.trackermap.TrackerMap.android.R import mx.trackermap.TrackerMap.android.databinding.FragmentMapWrapperBinding import mx.trackermap.TrackerMap.android.shared.MarkerTransformations import mx.trackermap.TrackerMap.android.shared.Utils import mx.trackermap.TrackerMap.client.models.* class MapWrapperFragment: Fragment() { private var _binding: FragmentMapWrapperBinding? = null private val binding get() = _binding!! private val mapFragment = MapFragment() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View { _binding = FragmentMapWrapperBinding.inflate(inflater, container, false) return binding.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setupEvents() setupViews() } override fun onResume() { super.onResume() initializeMap() } override fun onPause() { super.onPause() removeMap() } override fun onDestroy() { super.onDestroy() _binding = null } private fun initializeMap() { Log.d("MapWrapperFragment", "initializeMap()") childFragmentManager.commit { replace(R.id.mapContainer, mapFragment) } val layer = MapLayer.defaultLayer binding.attributionText.text = HtmlCompat.fromHtml(layer.attribution, 0) if (mapFragment.hasStarted) { binding.mapLoading.root.visibility = View.GONE } else { binding.mapLoading.root.visibility = View.VISIBLE mapFragment.setupCallbacks.add { binding.mapLoading.root.visibility = View.GONE } } } private fun removeMap() { Log.d("MapWrapperFragment", "removeMap()") childFragmentManager.commit { remove(mapFragment) } } private fun setupEvents() { binding.zoomInButton.setOnClickListener { if (mapFragment.hasStarted) { mapFragment.zoomIn() } else { mapFragment.setupCallbacks.add { binding.zoomInButton.performClick() } } } binding.zoomOutButton.setOnClickListener { if (mapFragment.hasStarted) { mapFragment.zoomOut() } else { mapFragment.setupCallbacks.add { binding.zoomOutButton.performClick() } } } binding.mapLayerToggle.setOnClickListener { context?.let { context -> if (mapFragment.hasStarted) { Utils.showLayersPopUp(context, it) { type -> mapFragment.updateLayer(type) MapLayer.layers[type]?.attribution?.let { attribution -> binding.attributionText.text = HtmlCompat.fromHtml(attribution, 0) } } } else { binding.mapLayerToggle.performClick() } } } } private fun setupViews() { val overlayMarginTop = arguments?.getInt(OVERLAY_MARGIN_TOP_ARG) val showLayerToggle = arguments?.getBoolean(SHOW_LAYER_TOGGLE_ARG) overlayMarginTop?.let { top -> binding.overlay.setPadding(0, top, 0, 0) } showLayerToggle?.let { show -> binding.mapLayerToggle.visibility = if (show) View.VISIBLE else View.GONE } } fun setMarkerCallback(callback: MarkerCallback) { mapFragment.markerCallback = callback } fun focusOn( latitude: Double, longitude: Double, height: Double = 0.0000264, animated: Boolean = true ) { Log.d("MapWrapperFragment", "Focusing on $latitude, $longitude") if (mapFragment.hasStarted) { mapFragment.focusOn(latitude, longitude, height, animated) } else { mapFragment.setupCallbacks.add { focusOn(latitude, longitude, height, animated) } } } fun display(positions: Array, isReport: Boolean, center: Boolean) { if (mapFragment.hasStarted) { Log.d("MapWrapperFragment", "Displaying positions: $positions") mapFragment.display( positions.mapNotNull(MarkerTransformations::positionToMarker).toTypedArray(), isReport = isReport, center = center ) } else { mapFragment.setupCallbacks.add { display(positions, isReport, center) } } } fun display(units: Array, isReport: Boolean, center: Boolean) { if (mapFragment.hasStarted) { Log.d("MapWrapperFragment", "Displaying units: $units") mapFragment.display( units.mapNotNull(MarkerTransformations::unitToMarker).toTypedArray(), isReport = isReport, center = center ) } else { mapFragment.setupCallbacks.add { display(units, isReport, center) } } } fun display(stops: Array) { if (mapFragment.hasStarted) { Log.d("MapWrapperFragment", "Displaying stops: $stops") mapFragment.display( stops.mapNotNull(MarkerTransformations::stopToMarker).toTypedArray(), isReport = true ) } else { mapFragment.setupCallbacks.add { display(stops) } } } fun display(geofences: Array) { if (mapFragment.hasStarted) { Log.d("MapWrapperFragment", "Displaying geofences: $geofences") mapFragment.displayGeofences(geofences) } else { mapFragment.setupCallbacks.add { display(geofences) } } } fun updateLayer(layer: MapLayer.Type) { if (mapFragment.hasStarted) { mapFragment.updateLayer(layer) MapLayer.layers[layer]?.attribution?.let { attribution -> binding.attributionText.text = HtmlCompat.fromHtml(attribution, 0) } } else { mapFragment.setupCallbacks.add { updateLayer(layer) } } } companion object { const val SHOW_LAYER_TOGGLE_ARG = "show_layer_toggle" const val OVERLAY_MARGIN_TOP_ARG = "overlay_margin_top" fun newInstance( showLayerToggle: Boolean = false, overlayMarginTop: Int = 0 ): MapWrapperFragment { val args = Bundle() args.putBoolean(SHOW_LAYER_TOGGLE_ARG, showLayerToggle) args.putInt(OVERLAY_MARGIN_TOP_ARG, overlayMarginTop) val fragment = MapWrapperFragment() fragment.arguments = args return fragment } } }