#' Draws hatching or crosshatching over a mask on a map
#' 
#' Adds hatching or crosshatching lines over grid cells of a map based on a 
#' logical mask. The hatching is applied only to grid cells where the mask is
#' TRUE. A number of graphical options are available to customize the appearance
#' of the hatching, such as line density, angle, line width, and color.
#' Optionally, crosshatching can be drawn using a second set of lines in the
#' opposite direction.
#' The function assumes that the input mask is a 2D array with dimensions
#' corresponding to latitude (rows) and longitude (columns), and it is designed
#' to be used as a layer over existing map plots (e.g., within a call to 
#' \code{VizEquiMap}) and does not initiate a plot by itself.
#'
#'@param mask Array with two named dimensions (latitud x longitude).
#'@param lat Array of latitudes.
#'@param lon Array of longitudes.
#'@param data Array of the data that the hatching will be drawn over. The array 
#'  should have named latidude and longitude dimensions. If the dimension order
#'  is reversed relative to 'mask', the mask is automatically transposed.
#'  Default is NULL.
#'@param dens The density of shading lines, in lines per inch. The default value
#'  of NULL means that no shading lines are drawn. A zero value of density means
#'  no shading nor filling whereas negative values and NA suppress shading (and
#'  so allow color filling). Default is 10.
#'@param ang The slope of shading lines, given as an angle in degrees
#'  (counter-clockwise). Default is 45.
#'@param col_line olor of the hatching lines. Default is \code{"#252525"}.
#'@param lwd_size The line width, a positive number. The interpretation is
#'  device-specific, and some devices do not implement line widths less than
#'  one. Default is 0.5.
#'@param crosshatching A logical value indicating crosshatching. If TRUE, adds a
#'  second set of lines in the opposite angle. Default is FALSE:

Hatching <- function(mask, lat, lon, data = NULL, dens = 10, ang = 45,
                     col_line = '#252525', lwd_size = 0.5,
                     crosshatching = FALSE) {
  
  if (length(dim(mask)) != 2 || is.null(names(dim(var)))) {
    stop("The mask array should have two named latitude and longitude dimensions")
  } 
  if (!(any(names(dim(var)) %in% .KnownLonNames()) &&
        any(names(dim(var)) %in% .KnownLatNames()))) {
    stop("Dimension names of 'var' doesn't correspond to any coordinates names supported by s2dv package.")
  } 
  lon_dim <- names(dim(var))[names(dim(var)) %in% .KnownLonNames()]
  lat_dim <- names(dim(var))[names(dim(var)) %in% .KnownLatNames()]
  if (dim(mask)[[lat_dim]] != length(lat) | dim(mask)[[lon_dim]] != length(lon)) {
    stop("The dimensions of the mask do not match the lengths of 'lat' and 'lon'.")
  }

  # If 'mask' dimensions are reversed respect 'data', transpose the mask
  if (!is.null(data)) {
    if (!is.null(names(dim(data)))) {
      if (names(dim(mask))[1] == names(dim(data))[2] && 
          names(dim(mask))[2] == names(dim(data))[1]) {
        mask <- t(mask)
      }
    }
  }
  
  # Helper function to calculate cell edges (breaks between lat/lon points)
  get_edges <- function(vec) {
    mid <- diff(vec) / 2
    edges <- c(vec[1] - mid[1], vec[-length(vec)] + mid, vec[length(vec)] + mid[length(mid)])
    return(edges)
  }
  # Find lon and lat edges
  x_edges <- get_edges(lon)
  y_edges <- get_edges(lat)
  # Loop through mask
  for (i in seq_len(nrow(mask))) {
    for (j in seq_len(ncol(mask))) {
      if (mask[i, j]) {
        # Calculate cell coordinates
        x_min <- x_edges[i]
        x_max <- x_edges[i + 1]
        y_min <- y_edges[j]
        y_max <- y_edges[j + 1]
        # Draw grid cell
        xs <- c(x_min, x_min, x_max, x_max)
        ys <- c(y_min, y_max, y_max, y_min)
        # Fill with diagonal lines
        polygon(xs, ys, density = dens, angle = ang, border = NA, lwd = lwd_size, col = col_line)
        if (crosshatching) {
          polygon(xs, ys, density = dens, angle = -ang, border = NA, lwd = lwd_size, col = col_line)
        }
      }
    }
  }
}

