#' Plot the column totals of a selected assay
#' 
#' @param se A \code{SummarizedExperiment} object, typically generated by 
#'     \code{summarizeExperiment()}.
#' @param selAssay Character scalar specifying the assay in \code{se} to 
#'     use for the plotting.
#' @param groupBy Character scalar indicating a column in 
#'     \code{rowData(se)} to group the features by before calculating the 
#'     column sums.
#' 
#' @export
#' @author Charlotte Soneson
#' 
#' @return A ggplot object.
#' 
#' @importFrom ggplot2 ggplot theme_minimal theme element_text labs 
#'     geom_bar scale_fill_discrete aes
#' @importFrom SummarizedExperiment assay rowData assayNames
#' @importFrom rlang .data
#' 
#' @examples 
#' se <- readRDS(system.file("extdata", "GSE102901_cis_se.rds", 
#'                           package = "mutscan"))[1:200, ]
#' plotTotals(se)
#' 
plotTotals <- function(se, selAssay = "counts", groupBy = NULL) {
    .assertVector(x = se, type = "SummarizedExperiment")
    .assertScalar(x = selAssay, type = "character",
                  validValues = assayNames(se))
    if (!is.null(groupBy)) {
        .assertScalar(
            x = groupBy, type = "character",
            validValues = colnames(rowData(se)))
    }
    
    ## Extract the assay matrix and reformat relevant parts of it for plotting
    selAssayMat <- assay(se, selAssay)
    if (!is.null(groupBy)) {
        df <- do.call(
            rbind, 
            lapply(unique(rowData(se)[[groupBy]]), 
                   function(rn) {
                       data.frame(
                           names = colnames(se),
                           category = rn,
                           total = colSums(
                               selAssayMat[rowData(se)[[groupBy]] == rn, ])
                       )
                   })
        )
    } else {
        df <- data.frame(names = colnames(se),
                         category = "all",
                         total = colSums(selAssayMat))
    }
    
    gg <- ggplot(df, aes(x = .data$names, y = .data$total)) + 
        theme_minimal() + 
        theme(
            axis.text.x = element_text(angle = 90, hjust = 1, 
                                       vjust = 0.5, size = 12),
            axis.text.y = element_text(size = 12),
            axis.title = element_text(size = 14)) + 
        labs(x = "", y = paste0("Total (", selAssay, ")"))
    if (!is.null(groupBy)) {
        gg <- gg + 
            geom_bar(stat = "identity", position = "stack", 
                     aes(fill = .data$category)) + 
            scale_fill_discrete(name = groupBy)
    } else {
        gg <- gg + 
            geom_bar(stat = "identity", position = "stack")
    }
    
    gg
}
