#' Generate a dose-finding decision table
#' @description Generate a two- or three-stage dose-finding decision table.
#' @details An alpha-spending method is available for two- and three-stage
#'   designs. \code{dec.table} uses the Hwang-Shih-DeCani spending function.
#' @param alpha.l Left-side overall type I error. This controls the upper bound
#'   for dose escalation.
#' @param alpha.r Right-side overall type I error. This controls the lower bound
#'   for dose de-escalation.
#' @param alpha.u Right-side overall type I error used to determine the lower
#'   bound for \code{"DU"}.
#' @param pt A numeric vector of target toxicities. It should have length 1, or
#'   length 2 when the target is an interval.
#' @param n A vector of sample sizes at each stage. \code{sum(n)} is the total
#'   sample size. For A+B designs, \code{n} has length 2; for A+B+C designs,
#'   \code{n} has length 3.
#' @param sf.param A single real value specifying the gamma parameter for the
#'   Hwang-Shih-DeCani spending function. The allowable range is [-40, 40].
#'   Larger values spend more error early and leave less for later stages.
#'   Defaults to 4.
#' @param pe.par Alternative hypothesis offset used to calculate power and the
#'   type II error. The alternative is defined as \code{pe = pt + pe.par}.
#'   Defaults to 0.25.
#' @param ... Unused arguments.
#' @return An object of class \code{"dec.table"}, returned as a list
#'   containing:
#'   \item{table}{The generated decision table.}
#'   \item{alpha.two}{A vector of true type I errors for the two-sided test.}
#'   \item{alpha.one}{A vector of true type I errors for the right-sided test.}
#'   \item{beta}{The true type II error, which depends on the alternative
#'   hypothesis.}
#'   \item{E}{A vector of \code{"E"} boundaries.}
#'   \item{D}{A vector of \code{"D"} boundaries.}
#'   \item{DU}{A vector of \code{"DU"} boundaries.}
#'   \item{pt}{The input target toxicity vector.}
#'   \item{n}{The input stage-wise sample sizes.}
#'   \item{sf.param}{The input alpha-spending parameter.}
#' @author Wenchuan Guo <wguo1017@gmail.com>
#' @import stats
#' @export
#' @examples
#' alpha.l <- 0.6
#' alpha.r <- 0.4
#' alpha.u <- 0.1
#' pt <- 0.3
#' # Print the decision table for a 3+3+3 design
#' n <- rep(3, 3)
#' dec.table(alpha.l, alpha.r, alpha.u, pt, n)$table
#' # 3+3 design
#' n <- rep(3, 2)
#' dec.table(alpha.l, alpha.r, alpha.u, pt, n)$table

dec.table <- function(alpha.l, alpha.r, alpha.u, pt, n, sf.param  = 4, pe.par = 0.25, ...) {
  # check
  err <- c(alpha.l, alpha.r, alpha.u)
  k <- length(n)
  if(sum(err < 0 | err > 1) != 0) {
    stop("'alpha' should between 0 and 1.")
  }
  if(length(pt) > 2) {
    stop("'pt''s length should less than 2 (two-tailed test).")
  }
  if(length(pt) == 1) {
    pt <- rep(pt, 2)
  }
  if(k != 3 & k != 2) {
    stop("This function only find two-stage/three-stage optimal design")
  }
  if(k == 3) {
    out.two <- three.opt(alpha.l, alpha.r, pt, n, sf.param, pe.par)
    out.one <- right.three.opt(alpha.u, pt[2], n, sf.param)
  } else {
    out.two <- two.opt(alpha.l, alpha.r, pt, n, sf.param, pe.par)
    out.one <- right.two.opt(alpha.u, pt[2], n, sf.param)
  }
  des <- list(E = out.two$bdry[1:k], D = out.two$bdry[(k+1):(2*k)], DU = out.one$bdry,  n = n, pt = pt, sf.param = sf.param, alpha.two = out.two$error, alpha.one = out.one$error, beta = out.two$beta)
  r <- des$E
  s <- des$D
  su <- des$DU
  ns <- length(n)
  nt <- sum(n)
  nc <- cumsum(n)
  ans <- matrix(0, nt+1, ns)
  rownames(ans) <- 0:nt
  colnames(ans) <- nc
  for(j in 1:length(r)){
    ans[ ,j][1:(r[j]+1)] <- "E"
    ans[ ,j][(s[j]+2):(nc[j]+1)] <- "D"
    ans[ ,j][(su[j]+2):(nc[j]+1)] <- "DU"
    ans[ ,j][which(ans[, j] ==0)] <- "S"
    ind.s <- (1:(nc[k]+1)) > nc[j]+1
    ans[ , ][ind.s] <- rep("0", sum(ind.s))
  }
  out <- c(des, list(table=as.table(ans)))
  class(out) <- "dec.table"
  return(out)
}
