
  # -------------------------------------------------------------------------------------------------------------------------  #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  #                                                                                                                            #
  #           File Name              :  orderch.R                                                                              #
  #           Last Updated Funclist  :  08 Feb 2015,  5:12 AM (Sunday)                                                         #
  #                                                                                                                            #
  #           Author Name            :  Rick Saporta                                                                           #
  #           Author Email           :  RickSaporta@gmail.com                                                                  #
  #           Author URL             :  www.github.com/rsaporta                                                                #
  #                                                                                                                            #
  #           Packages Called        :  NA                                                                                     #
  #           Packages Used via NS   :  NA                                                                                     #
  #                                                                                                                            #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  #                                                                                                                            #
  #   orderch            ( x, decreasing=TRUE, e=parent.frame(), verbose=FALSE, showWarnings=TRUE, skipCheck=FALSE )           #
  #   FUNC               ( ... )                                                                                               #
  #                                                                                                                            #
  #                                                                                                                            #
  #                                                     <END FUNCS>                                                            #
  #  -----------------------------------------------------------------------------------------------------------------------   #
  # -------------------------------------------------------------------------------------------------------------------------  #

# DT[,  {e2 <- environment(); orderch(sortOn, decreasing=sortDec, verbose=TRUE)}]
# DT[,  order(end_reason, decreasing=sortDec)]


orderch <- function(x, decreasing=TRUE, e=parent.frame(), verbose=FALSE, showWarnings=TRUE, skipCheck=FALSE) {
# like order, but x is a vector of the NAMES of the variables. 
# eg:  instead of  order(v1, v2, v3)
#                 myVars <- c("v1", "v2", "v3")
#                 orderch(myVars)
#      this is useful in DT, when we already have a vector of column names
#      which we wish to order by

  if (!skipCheck) {
    # ------------------------- #
    #      CHECK INPUT          #
    # ------------------------- #

    # Zero Length
    if (!length(x)) {
      if (showWarnings)
        warning("x has zero length. Nothing to `order`, thus returning NULL.")
      return(invisible(NULL))
    }

    # Conflicting Names
    if ("decreasing" %in% names(x))
     stop("\n\t`x` has a value named \"decreasing\".\n\nThis will conflict with the `decreasing` argument in `order(..., decreasing=<T/F>)`\nTo resolve this, use `unname(x)`")

    # Not Character
    if (!is.character(x))
      stop("x must be a string vector")

    # List instead of vector
    if (is.list(x) && all(sapply(x, is.character)))
      x <- unlist(x, use.names=FALSE)
    # ------------------------- #
  }

  FUNC <- function(...) order(..., decreasing=decreasing)

  if (verbose)
    cat("Sorting in ", ifelse(decreasing, "Descending", "Ascending"), " order.\n   ",
        paste(x, collapse=",  "), "\n" )

  force(e)
  do.call(FUNC, lapply(x, function(x_i) {get(x_i, envir=e)}))
}


if (FALSE)  {
  #  BELOW ARE TESTS: 

  ## TESTING IF HAVING `decreasing` as a column name is a conflict
  DT <- data.table(id=rep(LETTERS[1:5], each=2), value=10*c(1:5, 1:5), decreasing=rep(c("First", "Second"), each=5), ROW=1:10)
  DT[orderChar(c("decreasing", "value", "id"), decreasing=FALSE)]
  DT[orderChar(c("decreasing", "value", "id"), decreasing=TRUE)]
  DT[orderChar(c(decreasing="decreasing", "value", "id"), decreasing=TRUE)]

  DT[order(decreasing, value, id, decreasing=TRUE)]

  DT <- data.table(id=rep(LETTERS[1:5], each=2), value=10*c(1:5, 1:5), TEMP=rep(c("First", "Second"), each=5), ROW=1:10)
  DT[orderChar(c("value", "id"), decreasing=FALSE)]
  DT[orderChar(c("value", "id"), decreasing=TRUE)]
  DT[, order(value, id, decreasing=TRUE)]


  identical(DT[orderChar(c("decreasing", "id"), decreasing=TRUE)], DT[orderChar(c("decreasing", "id"), decreasing=FALSE)])

  for (i in 1:10)
    cat(i, ": ", !isErr(get("value")), "\t")

  v1 <- c(1:10)
  v2 <- c(1:5, 1:5)
  v3 <- rep(1:2, each=5)
  order(v2, v3, v1, decreasing=TRUE)
  #order(v2[order(v1, decreasing=TRUE)], decreasing=TRUE)

  cat("",
    pasteR(15)
    , "\n",
    orderChar(c("v2", "v3", "v1"), decreasing=FALSE),  "   [ ACTUAL ]"
    , "\n",
    order(v2, v3, v1, decreasing=FALSE),  "   [ EXPECTED ]"
    , "\n",
    pasteR(15)
    , "\n",
    orderChar(c("v2", "v3", "v1"), decreasing=TRUE),  "   [ ACTUAL ]"
    , "\n",
    order(v2, v3, v1, decreasing=TRUE),  "   [ EXPECTED ]"
    , "\n",
    pasteR(15)
    , "\n"
  )

}
