#' Convert levels, starting locations, or ending locations to range matrix
#'
#' @param levels vector of levels.
#' @param start vector of starting location. \cr
#' The last element must be the ending location.
#' @param end vector of ending locations. \cr
#' The last element must be the ending location.
#' @param delim vector of delimiter locations.
#'
#' @details
#' If \code{levels} is given: \cr
#' \code{ range <- cbind(cumsum(levels)-levels+1,cumsum(levels)) } \cr
#'
#' If \code{start} is given: \cr
#'  \code{range <-  cbind(start[-length(start)]} \cr
#'     \code{, c(start[2:(length(start)-1)]-1,start[length(start)]) ) } \cr
#'
#' If \code{end} is given, \cr
#'  \code{range <- cbind(c(1,end[1:(length(end)-1)]+1),end) } \cr
#'
#' If \code{delim} is given, \cr
#'  \code{range <-  cbind(c(1,delim[-length(delim)]+1)} \cr
#'     \code{, c(delim[-length(delim)]-1,delim[length(delim)])) } \cr
#'
#'  Note that \code{start[-length(start)], end} and \code{delim}
#'  must be strictly increasing sequence of numbers.
#'
#'
#' @return range: a \code{length(levels) x 2} matrix, \cr
#' where \code{length(levels) = length(start)-1 = length(end)}.
#'
#' @examples
#' get_range( c(3,4,2) )
#' get_range( start=c(1,4,8,9) )
#' get_range( end=c(3,7,9) )
#' get_range( delim=c(3,7,9) )
#'
#' levels <- c(1,2,3,1)
#' range <- get_range( levels )
#' levels2 <- range[,2]-range[,1]+1
#' identical(levels,levels2)
#'
#' @export
#'

get_range <- function( levels=NULL, start=NULL, end=NULL, delim=NULL ){
 # convert levels to range
 # Shin-ichi Mayekawa
 # 20150815
 # start and end: 20250217,18
 # delim: 20250218,20
 #

 if( is.null(start) && is.null(end) && is.null(delim) ){
  # levels is given
  range=cbind(cumsum(levels)-levels+1,cumsum(levels))
 }
 else if( !is.null(start) ){
  # start is given
  if( length(start) == 2  && start[1]<start[2] ) range=matrix(start,1,2)
  else if( length(start) <= 2 || any(diff(start) < 0) ){
   cat("\nerror1:(get_range) length(start) <= 1 or decreasing. \n")
   stop()
  }
  else
  range=cbind(start[-length(start)]
                , c(start[2:(length(start)-1)]-1,start[length(start)]) )
 }
 else if( !is.null(end) ){
  # end is given
  if( length(end) == 1 || any(diff(end) < 0) ){
   cat("\nerror1:(get_range) length(end) <= 1 or decreasing. \n")
   stop()
  }
  range=cbind(c(1,end[1:(length(end)-1)]+1),end)
 }
 else if( !is.null(delim) ){
  # delim is given
  if( length(delim) == 1 || any(diff(delim) < 0) ){
   cat("\nerror1:(get_range) length(delim) <= 1 or decreasing. \n")
   stop()
  }
  else if( delim[1] == 1 ){
   range=cbind(c(delim[1]+1,delim[-c(1,length(delim))]+1)
             , c(delim[-c(1,length(delim))]-1,delim[length(delim)]))
   }
  else{
   range=cbind(c(1,delim[-length(delim)]+1)
              , c(delim[-length(delim)]-1,delim[length(delim)]))
  }
 }

 colnames(range)=c("from","to")
 return( range)

} # end of get_range


