# Check if the lat and lon inputs abide the regulation.
#
# (x) ←|-------------|-------------|-------------|-------------|-------------| →(x)
#    -360          -180            0            180           360           540
#      |___________________________|___________________________|
#                 [0, 360]                    [0, 360]
#
#                    |___________________________|___________________________|
#                             [-180, 180]                 [-180, 180]
# Premise: lonmin < lonmax 
# [Case 1: lonmin >= 0]
# 1-0: lonmax <360 →[0, 360]
# 1-1:lonmin >= 180 & lonmax > 360 →[-180, 180]
# 1-2:lonmin < 180 & lonmax > 360 →[0, 360] + warning*
#
# [Case 2: lonmax < 0]
# 2-0: lonmin >= -180 & lonmax < 180 →[-180, 180]
# 2-1: lonmin < -180 & lonmax < 0 →[0, 360]
# 2-2: lonmin < -180 & lonmax > 0 →[-180, 180] + warning*
# 2-3 lonmax > 180 →[-180, 180] + warning*
#
# *warning: The region is not one integrated box.

check_latlon <- function(latmin, latmax, lonmin, lonmax) {

  if (any(!sapply(c(latmin, latmax, lonmin, lonmax), is.numeric)) |
      any(sapply(c(latmin, latmax, lonmin, lonmax), length) != 1))
    stop("latmin, latmax, lonmin, and lonmax must be a number.")
  # lat
  if (any(c(latmin, latmax) < -90) | any(c(latmin, latmax) > 90))
    stop("latmin must be within [-90, 90].")
  # lon
  if (lonmin > lonmax)
    stop("lonmax must not be smaller than lonmin.")
  # Adjust lon if it is way out of scope
  while (lonmin > 360 & lonmax > 360) {
    lonmin <- lonmin - 360
    lonmax <- lonmax - 360
  }
  while (lonmin < -180 & lonmax < -180) {
    lonmin <- lonmin + 360
    lonmax <- lonmax + 360
  }

  warning_discrete_lon <- FALSE
  warning_unconsidered_case <- FALSE
  ## case 1
  if (lonmin >= 0) {
    if (lonmax < 360) {  ## 1-0
      circularsort <- CircularSort(0, 360)
    } else if (lonmin >= 180 & lonmax > 360) { ## 1-1
      circularsort <- CircularSort(-180, 180)
      if (lonmax >= 540) 
        warning_discrete_lon <- TRUE
    } else if (lonmin < 180 & lonmax > 360) { ## 1-2
      circularsort <- CircularSort(0, 360)
      warning_discrete_lon <- TRUE
    } else {
      circularsort <- CircularSort(0, 360)
      warning_unconsidered_case <- TRUE
    }

  } 
  ## case 2
    else {
    if (lonmin >= -180 & lonmax < 180) {  ## 2-0
      circularsort <- CircularSort(-180, 180)
    } else if (lonmin < -180 & lonmax < 0) {  ## 2-1
      circularsort <- CircularSort(0, 360)
      if (lonmin < -360)
        warning_discrete_lon <- TRUE
    } else if (lonmin < -180 & lonmax > 0) {  ## 2-2
      circularsort <- CircularSort(-180, 180)
      warning_discrete_lon <- TRUE
    } else if (lonmax > 180) { ## 2-3
      circularsort <- CircularSort(-180, 180)
      warning_discrete_lon <- TRUE
    } else {
      circularsort <- CircularSort(-180, 180)
      warning_unconsidered_case <- TRUE
    }
  }

  if (warning_discrete_lon)
    warning("The longitude of returned data won't be continuous. Check the metadata to see the longitude range.")
  if (warning_unconsidered_case)
    warning("The longitude case is not being considered yet. Please report this case to maintainers and check the longitude of returned data.")

  return(circularsort)
}
