package org.tasks.location import android.annotation.SuppressLint import android.content.Context import androidx.appcompat.app.AppCompatActivity import com.google.android.gms.maps.CameraUpdateFactory import com.google.android.gms.maps.GoogleMap import com.google.android.gms.maps.OnMapReadyCallback import com.google.android.gms.maps.SupportMapFragment import com.google.android.gms.maps.model.* import dagger.hilt.android.qualifiers.ApplicationContext import org.tasks.R import org.tasks.data.Place import org.tasks.location.MapFragment.MapFragmentCallback import javax.inject.Inject class GoogleMapFragment @Inject constructor( @ApplicationContext private val context: Context ) : MapFragment, OnMapReadyCallback, GoogleMap.OnMarkerClickListener { private val markers: MutableList = ArrayList() private lateinit var callback: MapFragmentCallback private var dark = false private var map: GoogleMap? = null private var circle: Circle? = null override fun init(activity: AppCompatActivity, callback: MapFragmentCallback, dark: Boolean) { this.callback = callback this.dark = dark val fragmentManager = activity.supportFragmentManager var mapFragment = fragmentManager.findFragmentByTag(FRAG_TAG_MAP) as SupportMapFragment? if (mapFragment == null) { mapFragment = SupportMapFragment() fragmentManager.beginTransaction().replace(R.id.map, mapFragment).commit() } mapFragment.getMapAsync(this) } override val mapPosition: MapPosition? get() = map?.cameraPosition?.let { val target = it.target return MapPosition(target.latitude, target.longitude, it.zoom) } override fun movePosition(mapPosition: MapPosition, animate: Boolean) { val cameraUpdate = CameraUpdateFactory.newCameraPosition( CameraPosition.builder() .target(LatLng(mapPosition.latitude, mapPosition.longitude)) .zoom(mapPosition.zoom) .build()) if (animate) { map!!.animateCamera(cameraUpdate) } else { map!!.moveCamera(cameraUpdate) } } override fun setMarkers(places: List) { if (map == null) { return } markers .onEach { it.remove() } .clear() places .mapNotNull { map?.addMarker(it) } .let { markers.addAll(it) } } override fun disableGestures() { map?.uiSettings?.setAllGesturesEnabled(false) } @SuppressLint("MissingPermission") override fun showMyLocation() { map?.isMyLocationEnabled = true } override fun showCircle(radius: Double, latitude: Double, longitude: Double) { circle?.remove() circle = map?.addCircle( CircleOptions() .radius(radius) .center(LatLng(latitude, longitude)) .strokeColor(context.getColor(R.color.map_circle_stroke)) .fillColor(context.getColor(R.color.map_circle_fill)) ) } override fun onMapReady(googleMap: GoogleMap) { map = googleMap if (dark) { map!!.setMapStyle(MapStyleOptions.loadRawResourceStyle(context, R.raw.mapstyle_night)) } val uiSettings = map!!.uiSettings uiSettings.isMyLocationButtonEnabled = false uiSettings.isRotateGesturesEnabled = false map!!.setOnMarkerClickListener(this) callback.onMapReady(this) } override fun onPause() {} override fun onResume() {} override fun onDestroy() {} override fun onMarkerClick(marker: Marker): Boolean { callback.onPlaceSelected(marker.tag as Place) return true } companion object { private const val FRAG_TAG_MAP = "frag_tag_map" private fun GoogleMap.addMarker(place: Place) = addMarker(MarkerOptions().position(LatLng(place.latitude, place.longitude)))?.apply { tag = place } } }