#'Sort the coordinate variable values in a call to the function startR::Start
#'
#'The reorder function intended for use as parameter \code{<dim_name>_reorder} 
#'in a call to the function \code{Start()}. This function complies with the 
#'input/output interface required by \code{Start()} defined in the documentation 
#'for the parameter \dots of that function.\cr
#'The coordinate applied to \code{Sort()} consists of an increasing or decreasing 
#'sort of the values. It is useful for adjusting the latitude order.\cr 
#'The coordinate applied to \code{CircularSort()} consists of a circular sort of 
#'values, where any values beyond the limits specified in the parameters 
#'\code{start} and \code{end} is applied a modulus to fall in the specified 
#'range. This is useful for circular coordinates such as the Earth longitudes.

#'@param start A numeric indicating the lower bound of the circular range.
#'@param end A numeric indicating the upper bound of the circular range.
#'@param {\dots} Additional parameters to adjust the reorderig (sent internally 
#'  to the function \code{sort()}). 
#'
#'@return 
#'A list of 2 containing:
#'\item{$x}{
#'  The reordered values.
#'}
#'\item{$ix}{
#'  The permutation indices of $x in the original coordinate.
#'}
#'@examples
#' # Used in Start():
#'  data_path <- system.file('sample_data', package = 'startR')
#'  path_obs <- file.path(data_path, 'obs/monthly_mean/$var$/$var$_$sdate$.nc')
#'  sdates <- c('200011', '200012')
#'  data <- Start(dat = path_obs,
#'                var = 'tos',
#'                sdate = sdates,
#'                time = 'all',
#'                latitude = values(list(-60, 60)),
#'                latitude_reorder = Sort(decreasing = TRUE),
#'                longitude = values(list(-120, 120)),
#'                longitude_reorder = CircularSort(-180, 180),
#'                return_vars = list(latitude = 'dat',
#'                                   longitude = 'dat',
#'                                   time = 'sdate'),
#'                retrieve = FALSE)
#'
#'@rdname Sort
#'@export
Sort <- function(...) {
  params <- list(...)
  f <- "function(x) {
    dim_bk <- dim(x)
    x <- do.call(sort, c(list(x, index.return = TRUE),
                         PARAMS))
    dim(x$x) <- dim_bk
    dim(x$ix) <- dim_bk
    x
  }"
  f <- gsub("PARAMS", deparse(params), f)
  r <- eval(parse(text = f))
  attr(r, 'circular') <- FALSE
  r
}

#'@rdname Sort
#'@export
CircularSort <- function(start, end, ...) {
  params <- list(...)
  f <- "function (x) {
    start <- START
    end <- END
    dim_bk <- dim(x)
    x <- do.call(sort, c(list((x - start) %% (end - start) + start, 
                              index.return = TRUE),
                         PARAMS))
    dim(x$x) <- dim_bk
    dim(x$ix) <- dim_bk
    x
  }"
  f <- gsub("START", deparse(start), f)
  f <- gsub("END", deparse(end), f)
  f <- gsub("PARAMS", deparse(params), f)
  r <- eval(parse(text = f))
  attr(r, 'circular') <- TRUE
  r
}
