#' Zhong's 2- or 3-stage Phase II design
#' @description Calculate the optimal 2- or 3-stage design proposed by Bob
#'   Zhong.
#' @details In the two-stage design, \code{n1} patients are treated in the
#'   first stage. At the end of stage 1, the trial either continues to stage 2
#'   or stops early for inefficacy, depending on the number of observed
#'   responses. If the trial continues, an additional \code{n2} patients are
#'   treated. The three-stage design extends the two-stage design by adding one
#'   interim stage between stages 1 and 2. The left-side rejection region is
#'   defined by \code{response <= r_i} for \code{i = 1, 2, 3}, and the
#'   right-side rejection region is defined by \code{response > s}. An
#'   alpha-spending method is available for both two- and three-stage designs.
#'   \code{opt.design} uses the Hwang-Shih-DeCani spending function; you can
#'   change the definition of \code{HSD} to use a different spending function.
#' @param alpha1 Left-side overall type I error.
#' @param alpha2 right-side overall type I error.
#' @param beta Type II error.
#' @param pc A numeric vector of response rates. It should have length 1 or 2.
#' @param pe Alternative hypothesis response rate.
#' @param stage Either 2 or 3. Defaults to 2.
#' @param stop.eff Logical; if \code{TRUE}, the trial may stop early for
#'   efficacy at an interim analysis.
#' @param frac_n1 Proportion range for \code{n1}. For a two-stage design, the
#'   default is \code{c(0.3, 0.6)}. For a three-stage design, the default is
#'   \code{c(0.2, 0.3)}.
#' @param frac_n2 Proportion range for \code{n2}. Used only for three-stage
#'   designs. Defaults to \code{c(0.2, 0.4)}.
#' @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. For
#'   two-stage designs, the default is \code{NULL} (no alpha-spending). For
#'   three-stage designs, the default is 4.
#' @param show Logical; if \code{TRUE}, the current total sample size is printed
#'   during the search.
#' @param nmax Maximum sample size. Defaults to 100.
#' @param n.choice Stopping criterion for the search over feasible designs. The
#'   search stops once the number of designs exceeds \code{n.choice}.
#' @param ... Unused arguments.
#' @return An object of class \code{"opt.design"}, returned as a list
#'   containing:
#'   \item{bdry}{The rejection boundaries.}
#'   \item{error}{The true type I and type II errors.}
#'   \item{n}{The sample size at each stage.}
#'   \item{complete}{The complete list of feasible designs.}
#'   \item{alpha1}{The input left-side type I error.}
#'   \item{alpha2}{The input right-side type I error.}
#'   \item{beta}{The input type II error.}
#'   \item{pc}{The input response-rate vector.}
#'   \item{pe}{The input alternative response rate.}
#'   \item{sf.param}{The input alpha-spending parameter.}
#'   \item{stage}{The number of stages in the selected design.}
#' @author Wenchuan Guo <wguo1017@gmail.com>, Jianan Hui <jiananhuistat@gmail.com>
#' @references
#' Zhong. (2012) Single-arm Phase IIA clinical trials with go/no-go decisions. \emph{Contemporary Clinical Trials}, \bold{33}, 1272--1279.
#' @import stats
#' @export
#' @examples 
#'  alpha1 <- 0.15
#'  alpha2 <- 0.10
#'  beta <- 0.15
#'  pc <- 0.25
#'  pe <- pc + 0.20
#'  # calculate optimal two-stage design without using alpha-spending
#'  opt.design(alpha1, alpha2, beta, pc, pe, stage=2)
#'  
#'  # calculate optimal two-stage design with Pocock-like spending function 
#'  opt.design(alpha1, alpha2, beta, pc, pe, stage = 2, sf.param = 1)
#'  
#'  # calculate optimal three-stage design with an O'Brien-Fleming-like spending function
#'  opt.design(alpha1, alpha2, beta, pc, pe, stage = 3, sf.param = -4)

opt.design <- function(alpha1, alpha2, beta, pc, pe, stage = 2, stop.eff = FALSE, frac_n1 = NULL, frac_n2 = NULL, sf.param = NULL, show = FALSE, nmax = 100, n.choice = 1, ...) {
  if(stage !=2 & stage !=3){
    stop("only support two and three stage designs")
  }
  if(alpha1 > 1 | alpha1 < 0){
    stop("'alpha1' should between 0 and 1")
  }
  if(alpha2 > 1 | alpha2 < 0){
    stop("'alpha2' should between 0 and 1")
  }
  if(beta > 1 | beta < 0){
    stop("'beta' should between 0 and 1")
  }
  if(stage == 2) {
    if(is.null(frac_n1)) frac_n1 <- c(0.3, 0.6)
    out <- zhong.two(alpha1, alpha2, beta, pc, pe, stop.eff, sf.param, show, nmax, n.choice, frac_n1)
  } 
  if(stage == 3) {
    if(is.null(sf.param)) sf.param <- 4
    if(is.null(frac_n1)) frac_n1 <- c(0.2, 0.3)
    if(is.null(frac_n2)) frac_n2 <- c(0.2, 0.4)
    out <- zhong.three(alpha1, alpha2, beta, pc, pe, frac_n1, frac_n2, sf.param, stop.eff, show, nmax)
  }
  input <- list(alpha1 = alpha1, alpha2 = alpha2, beta = beta, pc = pc, pe = pe, sf.param = sf.param, stage = stage, frac_n1 = frac_n1, frac_n2 = frac_n2)
  out <- c(out, input)
  class(out) <- "opt.design"
  return(out)
}

