#' Heatmap of log-transformed normalization data
#'
#' @description Undertakes normalisation of RPM/FPKM using a pseudocount and 
#' transforms the data using log-scale, to enable visualization of the 
#' differences and patterns in expression across samples using a heatmap. 
#'
#'
#' @param data data.frame; originally generated by [mobileRNA::RNAimport()] 
#' 
#' @param value character; state the values to plot, either `FPKM` or `RPM`. 
#'
#' @param colours character; colors. Default is 
#'` grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "GnBu"))(100) `
#'
#' @param pseudocount numeric; pseudo count, default is `1e-6`
#' 
#' @param cluster logical; include hierarchical clustering when default 
#' `cluster= TRUE`
#' 
#' @param scale character; indicating whether the values should be centered & 
#' scaled in either the row direction or the column direction, or none. 
#' Respective options are "row", "column" & "none". Default is `scale="none"`.
#' 
#' 
#' @param clustering_method character; clustering method used. Accepts the same 
#' values as hclust. Default `clustering_method= "complete"`
#' 
#' @param row.names logical; indicated whether to include rownames from column
#' 1 of data frame. Default `row.names=FALSE`
#' 
#' @param border.color character; the border colour. Default is no border (NA). 
#'
#'@param title character; states plot title, placed at the top center
#'
#'@param column.angle numeric; angle of the column labels, choose from 0, 45, 
#'90, 270 or 315. 
#'
#'
#' @details Undertakes FPKM/RPM normalisation using a pseudocount and then 
#' transforms the normalised-RPM data using log-scale. 
#' 
#' This function expects to receive a data frame containing FPKM/RPM data. 
#' This function employs the use of a pseudo count during 
#' normalisation as the function is expected to be used when identifying mobile 
#' sRNAs in a chimeric system. In such system, it is expected that control 
#' replicates will contain zero values for the candidate mobile sRNA clusters. 
#' 
#' 
#'@return Produces a list objects storing the heatmap plot and the data. 
#'
#' @examples
#'data("sRNA_data")
#'
#' # vector of control names
#' controls <- c("selfgraft_1", "selfgraft_2" , "selfgraft_3")
#'
#' # Locate potentially mobile sRNA clusters associated to tomato, no
#' # statistical analysis
#' sRNA_data_mobile <- RNAmobile(input = "sRNA", data =  sRNA_data,
#' controls = controls, genome.ID = "B_", task = "keep", statistical = FALSE)
#'
#' # plot heatmap of potential mobile sRNAs
#'  p1 <-  plotHeatmap(sRNA_data_mobile)
#'
#'
#'
#'
#' @export
#' @importFrom dplyr %>%
#' @importFrom dplyr select
#' @importFrom tidyselect starts_with
#' @importFrom pheatmap pheatmap
#' @importFrom grDevices colorRampPalette
#' @importFrom RColorBrewer brewer.pal
#' @importFrom grid gpar
plotHeatmap <- function (data, 
                         value = "RPM", 
                         pseudocount = 1e-6, 
                         colours = grDevices::colorRampPalette(RColorBrewer::brewer.pal(9, "GnBu"))(100),
                         cluster = TRUE, scale = "none", 
                         clustering_method = "complete", 
                         row.names = FALSE,
                         border.color = NA,
                         column.angle = 45, 
                         title = NA) {
  if (base::missing(data) || !base::inherits(data, c("matrix","data.frame", 
                                                     "DataFrame"))) {
    stop("data must be an object of class matrix, data.frame, DataFrame.
          See ?plotHeatmap for more information.")
  }
  
  allowed_styles <- c("RPM", "FPKM")
  if (!value %in% allowed_styles) {
    stop("value parameter must be one of 'RPM', or 'FPKM'.")
  }
  
  RPMcolumns <- any(grepl(paste0("^", "RPM_"), colnames(data)))
  if (value == "RPM" && RPMcolumns ) {
    select_data <- data %>% dplyr::select(tidyselect::starts_with("RPM_"))
    names(select_data) <- sub('^RPM_', '', names(select_data))
  } else 
    FPKMcolumns <-any(grepl(paste0("^", "FPKM_"), colnames(data)))
   if (value == "FPKM" && FPKMcolumns) {
    select_data <- data %>% dplyr::select(tidyselect::starts_with("FPKM"))
    names(select_data) <- sub('^FPKM_', '', names(select_data))
   }
    if(RPMcolumns == FALSE  && FPKMcolumns == FALSE ) {
       stop("data must contain columns containing either FPKM, or  RPM data 
          columns depending on the 'value' parameter.")
    }
   
  rownames(select_data) <- data[,1] # remove cluster with no counts 
  select_data <- select_data[rowSums(select_data[])>0,]
  total_reads_per_sample <- colSums(select_data)   # RPM normalization with pseudocount addition
  rpm_matrix <- (select_data / (total_reads_per_sample + pseudocount)) * 1e6
  log_rpm_matrix <- log2(rpm_matrix + 1)   # log transform. 
  
  if(cluster == FALSE){
    p1 <- pheatmap::pheatmap(log_rpm_matrix, 
                             scale = scale,
                             cluster_rows = FALSE, 
                             cluster_cols = FALSE, 
                             show_row_dendrogram = FALSE, 
                             show_col_dendrogram = FALSE, 
                             color = colours,
                             show_rownames = row.names, 
                             border_color = border.color,
                             fontsize_row = 10,            
                             fontsize_col = 10,
                             angle_col = column.angle, 
                             silent =TRUE, main = title)
  } else {
    p1 <- pheatmap::pheatmap(log_rpm_matrix,
                             scale = scale, 
                             color = colours,              
                             clustering_method = clustering_method,  
                             show_rownames = row.names,
                             fontsize_row = 10, 
                             fontsize_col = 10, 
                             border_color = border.color,
                             cluster_cols = FALSE, 
                             angle_col = column.angle,
                             silent =TRUE,
                             main = title)
  }
  
  p1$gtable$grobs[[4]]$gp <- grid::gpar(fontface = "bold") 
  p1$gtable$grobs[[3]]$gp <- grid::gpar(fontface = "bold")
  
  out <- list(plot = p1, data = log_rpm_matrix)
  return(out)
}

