#' @include ggsurvplot_core.R ggsurvplot_df.R ggsurvplot_list.R ggsurvplot_group_by.R ggsurvplot_add_all.R
NULL
#'Drawing Survival Curves Using ggplot2
#'
#'@description \code{ggsurvplot}() is a generic function to plot survival curves. Wrapper
#'  around the \code{ggsurvplot_xx()} family functions. Plot one or a list of
#'  survfit objects as generated by the
#'  \link[survival]{survfit.formula}() and \link{surv_fit} functions: \itemize{  \item
#'  \link{ggsurvplot_list}() \item \link{ggsurvplot_facet}() \item
#'  \link{ggsurvplot_group_by}() \item \link{ggsurvplot_add_all}() \item
#'  \link{ggsurvplot_combine}() } See the documentation for each function to
#'  learn how to control that aspect of the \link{ggsurvplot}().
#'  \code{ggsurvplot}() accepts further arguments to be passed to the
#'  \code{ggsurvplot_xx()} functions. Has options to: \itemize{ \item
#'  plot a list of survfit objects, \item facet survival curves into multiple
#'  panels, \item group  dataset by one or two grouping variables and to create
#'  the survival curves in each subset, \item combine multiple \code{survfit}
#'  objects into one plot, \item add survival curves of the pooled patients
#'  (null model) onto the main stratified plot, \item plot survival curves from
#'  a data frame containing survival curve summary as returned by
#'  \link{surv_summary}(). }
#'
#' @inheritParams ggsurvplot_arguments
#' @inheritParams surv_pvalue
#'@param fit allowed values include:
#'\itemize{
#'\item a survfit object
#'\item a list of survfit objects. Passed to \code{\link{ggsurvplot_list}()}
#'\item a data frame containing survival curves summary. Passed to \code{\link{ggsurvplot_df}()}.
#'}
#'@param group.by a character vector containing the name of grouping variables. Should be of length <= 2.
#' Alias of the \code{\link{ggsurvplot_group_by}()} function.
#'@param facet.by a character vector containing the name of grouping variables
#'to facet the survival curves into multiple panels. Should be of length <= 2.
#' Alias of the \code{\link{ggsurvplot_facet}()} function.
#'@param add.all a logical value. If TRUE, add the survival curve of pooled patients (null model) onto the main plot.
#'Alias of the \code{\link{ggsurvplot_add_all}()} function.
#'@param combine a logical value. If TRUE, combine a list survfit objects on the same plot.
#'Alias of the \code{\link{ggsurvplot_combine}()} function.
#'
#'@param ... Futher arguments as described hereafter and
#'other arguments to be passed i) to ggplot2 geom_*() functions such
#'  as linetype, size, ii) or to the function \link[ggpubr]{ggpar}() for
#'  customizing the plots. See details section.
#'@details \itemize{  \item
#'  \strong{Color palettes}: The argument \strong{palette} can be used to
#'  specify the color to be used for each group. By default, the first color in
#'  the palette is used to color the first level of the factor variable. This
#'  default behavior can be changed by assigning correctly a named vector. That
#'  is, the names of colors should match the strata names as generated by the
#'  \code{ggsurvplot()} function in the legend.
#'  }
#'
#'@section FURTHER ARGUMENTS:
#'Customize survival plots and tables. See also \link{ggsurvplot_arguments}.
#'
#'@section Plot title and axis labels:
#'\itemize{
#'  \item \strong{title}: main title.
#'  \item \strong{xlab, ylab}: x and y axis labels, respectively.
#'}
#'
#'@section Legend title, labels and position:
#'\itemize{
#'  \item \strong{legend}: character specifying legend position. Allowed values are one of
#'  c("top", "bottom", "left", "right", "none"). Default is "top" side position.
#'  to remove the legend use legend = "none". Legend position can be also
#'  specified using a numeric vector c(x, y). In this case it is
#'  possible to position the legend inside the plotting area. x and y are the
#'  coordinates of the legend box. Their values should be between 0 and 1.
#'  c(0,0) corresponds to the "bottom left" and c(1,1) corresponds to the "top
#'  right" position. For instance use legend = c(0.8, 0.2).
#'  \item \strong{legend.title}: legend title.
#'  \item \strong{legend.labs}: character vector specifying legend labels. Used to replace
#'  the names of the strata from the fit. Should be given in the same order as
#'  those strata.
#'}
#'
#'
#'@section Axis limits, breaks and scales:
#'\itemize{
#' \item \strong{break.time.by}: numeric value controlling time axis breaks. Default value
#'  is NULL.
#'  \item \strong{break.x.by}: alias of break.time.by. Numeric value controlling x axis
#'  breaks. Default value is NULL.
#'  \item \strong{break.y.by}: same as break.x.by but for y axis.
#'  \item \strong{surv.scale}: scale transformation of survival curves. Allowed values are
#'  "default" or "percent".
#'  \item \strong{xscale}: numeric or character value specifying x-axis scale. \itemize{
#'  \item If numeric, the value is used to divide the labels on the x axis. For
#'  example, a value of 365.25 will give labels in years instead of the original
#'  days. \item If character, allowed options include one of - "d_m", "d_y",
#'  "m_d", "m_y", "y_d" and "y_m" -  where \code{d = days}, \code{m = months} and \code{y = years}. For
#'  example, \code{xscale = "d_m"} will transform labels from days to months; \code{xscale =
#'  "m_y"}, will transform labels from months to years.}
#'  \item \strong{xlim,ylim}: x and y axis limits e.g. xlim = c(0, 1000), ylim = c(0, 1).
#'  \item \strong{axes.offset}: logical value. Default is TRUE. If FALSE, set the plot axes to start at the origin.
#'}
#'
#'
#'@section Confidence interval:
#'\itemize{
#'  \item \strong{conf.int.fill}: fill color to be used for confidence interval.
#'  \item \strong{conf.int.style}: confidence interval style. Allowed values include c("ribbon", "step").
#'  \item \strong{conf.int.alpha}: numeric value specifying confidence fill color transparency.
#'  Value should be in [0, 1], where 0 is full transparency and 1 is no transparency.
#'}
#'
#'@section P-value:
#'\itemize{
#'  \item \strong{pval.size}: numeric value specifying the p-value text size. Default is 5.
#'  \item \strong{pval.coord}: numeric vector, of length 2,
#'  specifying the x and y coordinates of the p-value.
#'  Default values are NULL.
#'  \item \strong{pval.method.size}: the same as \code{pval.size} but for displaying
#'  \code{log.rank.weights} name.
#'  \item \strong{pval.method.coord}: the same as \code{pval.coord} but for displaying
#'  \code{log.rank.weights} name.
#'  \item \strong{log.rank.weights}: the name for the type of weights to be used in
#'  computing the p-value for log-rank test. By default \code{survdiff} is used
#'  to calculate regular log-rank test (with weights == 1). A user can specify
#'  \code{"1", "n", "sqrtN", "S1", "S2", "FH"} to use weights specified in
#'  \link[survMisc]{comp}, so that weight correspond to the test as : 1 -
#'  log-rank, n - Gehan-Breslow (generalized Wilcoxon), sqrtN - Tarone-Ware, S1
#'  - Peto-Peto's modified survival estimate, S2 - modified Peto-Peto (by
#'  Andersen), FH - Fleming-Harrington(p=1, q=1).
#'}
#'
#'@section Median survival:
#'\itemize{
#'  \item \strong{surv.median.line}: character vector for drawing a
#'  horizontal/vertical line at median survival.
#'  Allowed values include one of c("none", "hv", "h", "v"). v: vertical, h:horizontal.
#'}
#'
#'
#'@section Censor points:
#'\itemize{
#'  \item \strong{censor}: logical value. If TRUE (default), censors will be drawn.
#'  \item \strong{censor.shape}: character or numeric value specifying the point shape of censors.
#'  Default value is "+" (3), a sensible choice is "|" (124).
#'  \item \strong{censor.size}: numveric value specifying the point size of censors. Default is 4.5.
#'}
#'
#'
#'@section Survival tables:
#'
#'\strong{General parameters for all tables}.
#'  The arguments below, when specified, will be applied to all survival tables at once
#'  (risk, cumulative events and cumulative censoring tables).
#'\itemize{
#'  \item \strong{tables.col}: color to be used for all tables under the main plot. Default
#'  value is "black". If you want to color by strata (i.e. groups), use
#'  tables.col = "strata".
#'  \item \strong{fontsize}: font size to be used for the risk table
#'  and the cumulative events table.
#'  \item \strong{font.family}: character vector specifying text element font family,
#'  e.g.: font.family = "Courier New".
#'  \item \strong{tables.y.text}: logical. Default is TRUE. If FALSE, the y axis tick
#'  labels of tables will be hidden.
#'  \item \strong{tables.y.text.col}: logical. Default value is FALSE. If TRUE, the y
#'  tick labels of tables will be colored by strata.
#' \item \strong{tables.height}: numeric value (in [0 - 1]) specifying the general height
#'  of all tables under the main survival plot.
#'  Increase the value when you have many strata. Default is 0.25.
#'}
#'
#'\strong{Specific to the risk table}
#'\itemize{
#'  \item \strong{risk.table.title}: the title to be used for the risk table.
#'  \item \strong{risk.table.pos}: character vector specifying the risk table position.
#'  Allowed options are one of c("out", "in") indicating 'outside' or 'inside'
#'  the main plot, respectively. Default value is "out".
#'  \item \code{risk.table.col}, \code{risk.table.fontsize}, \code{risk.table.y.text},
#'  \code{risk.table.y.text.col} and \code{risk.table.height}: same as for the general parameters
#'  but applied to the risk table only.
#'}
#'
#'\strong{Specific to the number of cumulative events table (cumevents)}
#'\itemize{
#'  \item \strong{cumevents.title}: the title to be used for the cumulative events table.
#'  \item \code{cumevents.col, cumevents.y.text, cumevents.y.text, cumevents.height}:
#'  same as for the general parameters but for the cumevents table only.
#'}
#'
#'\strong{Specific to the number of cumulative censoring table (cumcensor)}
#'\itemize{
#'  \item \strong{cumcensor.title}: the title to be used for the cumcensor table.
#'  \item \code{cumcensor.col}, \code{cumcensor.y.text}, \code{cumcensor.y.text.col}, \code{cumcensor.height}:
#'   same as for the general parameters but for cumcensor table only.
#'}
#'
#'@section Survival plot height:
#'\itemize{
#'  \item \strong{surv.plot.height}: the height of the survival plot on the grid. Default
#'  is 0.75. Ignored when risk.table = FALSE.
#'}
#'
#'@section Number of censored subjects barplot:
#'\itemize{
#'  \item \strong{ncensor.plot}: logical value. If TRUE, the number of censored subjects at
#'  time t is plotted. Default is FALSE. Ignored when cumcensor = TRUE.
#'  \item \strong{ncensor.plot.title}: the title to be used for the censor plot. Used when
#'  \code{ncensor.plot = TRUE}.
#'  \item \strong{ncensor.plot.height}: the height of the censor plot. Used when
#'  \code{ncensor.plot = TRUE}.
#'}
#'
#'@section Other graphical parameters:
#'The plot can be easily customized using additional arguments to be
#'  passed to the function \code{\link[ggpubr]{ggpar}()}.
#'
#'  These arguments include
#'  \code{font.title, font.subtitle, font.caption, font.x, font.y, font.tickslab and font.legend},
#'  which are vectors of length 3 indicating respectively the size
#'  (e.g.: 14), the style (e.g.: "plain", "bold", "italic", "bold.italic") and
#'  the color (e.g.: "red") of main title, subtitle, caption, xlab and ylab,
#'  axis tick labels and legend, respectively. For example font.x = c(14,
#'  "bold", "red").
#'
#'  Use font.x = 14, to change only font size; or use font.x =
#'  "bold", to change only font face.
#'
#'@return return an object of class ggsurvplot which is list containing the
#'  following components: \itemize{ \item plot: the survival plot (ggplot
#'  object) \item table: the number of subjects at risk table per time (ggplot
#'  object). \item cumevents: the cumulative number of events table (ggplot
#'  object). \item ncensor.plot: the number of censoring (ggplot object). \item
#'  data.survplot: the data used to plot the survival curves (data.frame). \item
#'  data.survtable: the data used to plot the tables under the main survival
#'  curves (data.frame). }
#'
#'@author Alboukadel Kassambara, \email{alboukadel.kassambara@@gmail.com}
#' @examples
#'
#'#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#'# Example 1: Survival curves with two groups
#'#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#'
#'# Fit survival curves
#'#++++++++++++++++++++++++++++++++++++
#'require("survival")
#'fit<- survfit(Surv(time, status) ~ sex, data = lung)
#'
#'# Basic survival curves
#'ggsurvplot(fit, data = lung)
#'
#'# Customized survival curves
#'ggsurvplot(fit, data = lung,
#'  surv.median.line = "hv", # Add medians survival
#'
#'  # Change legends: title & labels
#'  legend.title = "Sex",
#'  legend.labs = c("Male", "Female"),
#'  # Add p-value and tervals
#'  pval = TRUE,
#'
#'  conf.int = TRUE,
#'  # Add risk table
#'  risk.table = TRUE,
#'  tables.height = 0.2,
#'  tables.theme = theme_cleantable(),
#'
#'  # Color palettes. Use custom color: c("#E7B800", "#2E9FDF"),
#'  # or brewer color (e.g.: "Dark2"), or ggsci color (e.g.: "jco")
#'  palette = c("#E7B800", "#2E9FDF"),
#'  ggtheme = theme_bw() # Change ggplot2 theme
#')
#'
#'# Change font size, style and color
#'#++++++++++++++++++++++++++++++++++++
#'\dontrun{
#' # Change font size, style and color at the same time
#' ggsurvplot(fit, data = lung,  main = "Survival curve",
#'    font.main = c(16, "bold", "darkblue"),
#'    font.x = c(14, "bold.italic", "red"),
#'    font.y = c(14, "bold.italic", "darkred"),
#'    font.tickslab = c(12, "plain", "darkgreen"))
#'}
#'
#'
#'
#'#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#'# Example 2: Facet ggsurvplot() output by
#' # a combination of factors
#'#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#'
#'# Fit (complexe) survival curves
#'#++++++++++++++++++++++++++++++++++++
#' \dontrun{
#'require("survival")
#'fit3 <- survfit( Surv(time, status) ~ sex + rx + adhere,
#'                 data = colon )
#'
#'# Visualize
#'#++++++++++++++++++++++++++++++++++++
#' ggsurv <- ggsurvplot(fit3, data = colon,
#'   fun = "cumhaz", conf.int = TRUE,
#'   risk.table = TRUE, risk.table.col="strata",
#'   ggtheme = theme_bw())
#'
#' # Faceting survival curves
#' curv_facet <- ggsurv$plot + facet_grid(rx ~ adhere)
#' curv_facet
#'
#' # Faceting risk tables:
#' # Generate risk table for each facet plot item
#' ggsurv$table + facet_grid(rx ~ adhere, scales = "free")+
#'  theme(legend.position = "none")
#'
#'  # Generate risk table for each facet columns
#' tbl_facet <- ggsurv$table + facet_grid(.~ adhere, scales = "free")
#' tbl_facet + theme(legend.position = "none")
#'
#' # Arrange faceted survival curves and risk tables
#' g2 <- ggplotGrob(curv_facet)
#' g3 <- ggplotGrob(tbl_facet)
#' min_ncol <- min(ncol(g2), ncol(g3))
#' g <- gridExtra::rbind.gtable(g2[, 1:min_ncol], g3[, 1:min_ncol], size="last")
#' g$widths <- grid::unit.pmax(g2$widths, g3$widths)
#' grid::grid.newpage()
#' grid::grid.draw(g)
#'
#' }
#'
#'#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#'# Example 3: CUSTOMIZED PVALUE
#'#%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#' # Customized p-value
#' ggsurvplot(fit, data = lung, pval = TRUE)
#' ggsurvplot(fit, data = lung, pval = 0.03)
#' ggsurvplot(fit, data = lung, pval = "The hot p-value is: 0.031")
#'
#'@rdname ggsurvplot
#'@export
ggsurvplot <- function(fit, data = NULL, fun = NULL,
                       color = NULL, palette = NULL, linetype = 1,
                       conf.int = FALSE, pval = FALSE, pval.method = FALSE,
                       test.for.trend = FALSE,
                       surv.median.line = "none",
                       risk.table = FALSE, cumevents = FALSE, cumcensor = FALSE,
                       tables.height = 0.25,
                       group.by = NULL, facet.by = NULL, add.all = FALSE, combine = FALSE,
                       ggtheme = theme_survminer(),
                       tables.theme = ggtheme,
                       ...
){

  if(length(group.by) > 2)
    stop("group.by should be of length 1 or 2.")


  # Options for ggsurvplot_df
  # Don't accept arguments for pval and survival tables
  opts_df <- list(
                fit = fit, fun = fun,
                color = color, palette = palette, linetype = linetype,
                conf.int = conf.int,  ggtheme = ggtheme, ...)

  # Options for the remaining ggsurvplot_*() functions
  opts <- list(
               fit = fit, data = data, fun = fun,
               color = color, palette = palette, linetype = linetype,
               conf.int = conf.int, pval = pval, pval.method = pval.method,
               test.for.trend = test.for.trend,
               surv.median.line = surv.median.line,
               risk.table = risk.table, cumevents = cumevents, cumcensor = cumcensor,
               tables.height = tables.height, ggtheme = ggtheme,
               tables.theme = tables.theme, ...)




  if(.is_list(fit)){
    if(combine)
      ggsurv <- do.call(ggsurvplot_combine, opts)
    else ggsurv <- do.call(ggsurvplot_list, opts)
  }

  else if(is.data.frame(fit))
    ggsurv <- do.call(ggsurvplot_df, opts_df)

  else if(.is_survfit(fit)){

    if(!is.null(group.by)){
      opts$group.by <- group.by
      ggsurv <- do.call(ggsurvplot_group_by, opts)
    }
    else if(!is.null(facet.by)){
      opts$facet.by <- facet.by
      ggsurv <- do.call(ggsurvplot_facet, opts)
    }
    else if(add.all){
      ggsurv <- do.call(ggsurvplot_add_all, opts)
    }

    else{
      if(is.null(fit$strata)){
        if(missing(conf.int)){
          opts$conf.int = TRUE
          opts$conf.int.fill = "strata"
        }
      }
      ggsurv <- do.call(ggsurvplot_core, opts)
    }

  }

  else if(inherits(fit, "flexsurvreg"))
    ggsurv <- do.call(ggflexsurvplot, opts)


  return(ggsurv)
}



#' @param x an object of class ggsurvplot
#' @method print ggsurvplot
#' @param newpage open a new page. See \code{\link{grid.arrange}}
#' @rdname ggsurvplot
#' @export
print.ggsurvplot <- function(x, surv.plot.height = NULL, risk.table.height = NULL, ncensor.plot.height = NULL, newpage = TRUE, ...){

  res <- .build_ggsurvplot(x = x, surv.plot.height = surv.plot.height,
                           risk.table.height = risk.table.height,
                           ncensor.plot.height = ncensor.plot.height)
  if(newpage) grid::grid.newpage()
  grid::grid.draw(res)

}
