# ..............................................................
# reference: https://github.com/trafficonese/leaflet.extras
#
# "leaflet.extras" was archived at 2026-02-19 and is no
#  longer available on CRAN, thus I had to include the
#  required code snippets (I used previously) in this package
# ..............................................................

drawDependencies <- function(drag = TRUE) {
  if (drag) {
    list(
      html_dep_prod("lfx-draw", "1.0.4", has_style = TRUE, has_binding = TRUE),
      html_dep_prod("lfx-draw-drag", "0.4.8")
    )
  } else {
    list(
      html_dep_prod("lfx-draw", "1.0.4", has_style = TRUE, has_binding = TRUE)
    )
  }
}

#' Adds a Toolbar to draw shapes/points on the map.
#' @param map The map widget.
#' @param targetLayerId An optional layerId of a GeoJSON/TopoJSON layer whose features need to be editable.
#'  Used for adding  a GeoJSON/TopoJSON layer and then editing the features using the draw plugin.
#' @param targetGroup An optional group name of a Feature Group whose features need to be editable.
#'  Used for adding shapes(markers, lines, polygons) and then editing them using the draw plugin.
#'  You can either set layerId or group or none but not both.
#' @param position The position where the toolbar should appear.
#' @param polylineOptions Set to FALSE to disable polyline drawing.
#' @param polygonOptions Set to FALSE to disable polygon drawing.
#' @param circleOptions Set to FALSE to disable circle drawing.
#' @param rectangleOptions Set to FALSE to disable rectangle drawing.
#' @param markerOptions Set to FALSE to disable marker drawing.
#' @param circleMarkerOptions Set to FALSE to disable circle marker drawing.
#' @param editOptions By default editing is disable.
#' @param singleFeature When set to TRUE, only one feature can be drawn at a time, the previous ones being removed.
#' @param toolbar Set to \code{NULL} to take Leaflets default values.
#' @param handlers Set to \code{NULL} to take Leaflets default values.
#' @param edittoolbar Set to \code{NULL} to take Leaflets default values.
#' @param edithandlers Set to \code{NULL} to take Leaflets default values.
#' @param drag When set to \code{TRUE}, the drawn features will be draggable during editing, utilizing
#'    the \code{Leaflet.Draw.Drag} plugin. Otherwise, this library will not be included.
#' @importFrom leaflet invokeMethod getMapData filterNULL
#' @noRd
addDrawToolbar <- function(
    map, targetLayerId = NULL, targetGroup = NULL,
    position = c("topleft", "topright", "bottomleft", "bottomright"),
    polylineOptions = drawPolylineOptions(),
    polygonOptions = drawPolygonOptions(),
    circleOptions = drawCircleOptions(),
    rectangleOptions = drawRectangleOptions(),
    markerOptions = drawMarkerOptions(),
    circleMarkerOptions = drawCircleMarkerOptions(),
    editOptions = FALSE,
    singleFeature = FALSE,
    toolbar = NULL,
    handlers = NULL,
    edittoolbar = NULL,
    edithandlers = NULL,
    drag = TRUE) {
  if (!is.null(targetGroup) && !is.null(targetLayerId)) {
    stop("To edit existing features either specify a targetGroup or a targetLayerId, but not both")
  }

  if (!inherits(toolbar, "list")) toolbar <- NULL
  if (!inherits(handlers, "list")) handlers <- NULL
  if (!inherits(edittoolbar, "list")) edittoolbar <- NULL
  if (!inherits(edithandlers, "list")) edithandlers <- NULL

  map$dependencies <- c(map$dependencies, drawDependencies(drag))

  markerIconFunction <- NULL
  if (inherits(markerOptions, "list") && !is.null(markerOptions$markerIcon)) {
    if (inherits(markerOptions$markerIcon, "leaflet_icon")) {
      markerIconFunction <- defIconFunction
    } else if (inherits(markerOptions$markerIcon, "leaflet_awesome_icon")) {
      map <- addAwesomeMarkersDependencies(
        map, markerOptions$markerIcon$library
      )
      markerIconFunction <- awesomeIconFunction
    } else {
      stop("markerIcon should be created using either leaflet::makeIcon() or leaflet::makeAwesomeIcon()")
    }
    markerOptions$markerIconFunction <- markerIconFunction
  }

  position <- match.arg(position)

  options <- list(
    position = position,
    draw = leaflet::filterNULL(list(
      polyline = polylineOptions,
      polygon = polygonOptions,
      circle = circleOptions,
      rectangle = rectangleOptions,
      marker = markerOptions,
      circlemarker = circleMarkerOptions,
      singleFeature = singleFeature
    )),
    edit = editOptions,
    toolbar = toolbar,
    handlers = handlers,
    edittoolbar = edittoolbar,
    edithandlers = edithandlers
  )

  leaflet::invokeMethod(
    map, leaflet::getMapData(map), "addDrawToolbar",
    targetLayerId, targetGroup, options
  )
}

#' Removes the draw toolbar
#' @param clearFeatures whether to clear the map of drawn features.
#' @importFrom leaflet invokeMethod getMapData
#' @noRd
removeDrawToolbar <- function(map, clearFeatures = FALSE) {
  leaflet::invokeMethod(map, leaflet::getMapData(map), "removeDrawToolbar", clearFeatures)
}
