#' Cairo wrapper function with plot capture capability
#'
#' Cairo wrapper function returning NULL if not \code{type} is specified.
#' Enhanced version that can capture plots for later replay.
#'
#' \code{openGraphCairo()} \code{Cairo()} wrapper function. Differences to
#' \code{Cairo:} a) prematurely ends the function call to \code{Cairo()}
#' returning NULL, if no output \code{type}  of types 'png', 'jpeg', 'pdf',
#' 'svg', 'ps' or 'tiff' is provided. b) The \code{file} argument of the
#' underlying Cairo function is generated by
#' \code{file.path(fileDirectory,paste(fileName,'.', type, sep = ''))}.
#' c) Can set up plot capture when \code{capture_env} is provided.
#'
#' @param width see \code{Cairo()}
#' @param height see \code{Cairo()}
#' @param fileName name of file to be created. Does not include both file
#'   extension '.\code{type}' and file \code{filedirectory}. Default file name
#'   'visstat_plot'.
#' @param type Supported output types are 'png', 'jpeg', 'pdf', 'svg', 'ps' and
#'   'tiff'. See \code{Cairo()}
#' @param fileDirectory path of directory, where plot is stored. Default current
#'   working directory.
#' @param pointsize see \code{Cairo()}
#' @param bg see \code{Cairo()}
#' @param canvas see \code{Cairo()}
#' @param units see \code{Cairo()}
#' @param dpi DPI used for the conversion of units to pixels. Default value 150.
#' @name openGraphCairo
#' @return NULL, if no \code{type} is specified. Otherwise see \code{Cairo()}
#' @examples
#'
#' ##  adapted from example in \code{Cairo()}
#' openGraphCairo(fileName = "normal_dist", type = "pdf", fileDirectory = tempdir())
#' plot(rnorm(4000), rnorm(4000), col = "#ff000018", pch = 19, cex = 2)
#' dev.off() # creates a file 'normal_dist.pdf' in the directory specified in fileDirectory
#' # ## remove the plot from fileDirectory
#' file.remove(file.path(tempdir(), "normal_dist.pdf"))
#' @import Cairo
#' @export
openGraphCairo <- function(width = 640,
                           height = 480,
                           fileName = NULL,
                           type = NULL,
                           fileDirectory = getwd(),
                           pointsize = 12,
                           bg = "transparent",
                           canvas = "white",
                           units = "px",
                           dpi = 150) {
  # oldparCairo <- par(no.readonly = TRUE)
  # oldparCairo$new <- FALSE
  # on.exit(par(oldparCairo))
  # 
  
  
  
  
  if (is.null(type)) {
    return()
  }
  
  if (is.null(fileName)) {
    fileName <- "visstat_plot"
  }
  
  
  
  fullfilename <- paste(fileName, ".", type, sep = "")
  Cairofilename <- file.path(fileDirectory, fullfilename)
  
  if (type == "png") {
    CairoPNG(filename = Cairofilename, width = width, height = height, 
             pointsize = pointsize, bg = bg, dpi = dpi)
  } else if (type == "pdf") {
    CairoPDF(file = Cairofilename, width = width, height = height, 
             pointsize = pointsize, bg = bg)
  } else if (type == "jpeg") {
    CairoJPEG(filename = Cairofilename, width = width, height = height, 
              pointsize = pointsize, bg = bg, dpi = dpi)
  } else if (type == "tiff") {
    CairoTIFF(filename = Cairofilename, width = width, height = height, 
              pointsize = pointsize, bg = bg, dpi = dpi)
  } else if (type == "svg") {
    CairoSVG(file = Cairofilename, width = width, height = height, 
             pointsize = pointsize, bg = bg)
  } else if (type == "ps") {
    CairoPS(file = Cairofilename, width = width, height = height, 
            pointsize = pointsize, bg = bg, family = "Helvetica")
  } else {
    warning("Chosen output type not supported. No graphics saved.")
    return()
  }
}



#' Saves Graphical Output with plot capture capability
#'
#' Closes all graphical devices with \code{dev.off()} and saves the output only
#' if both \code{fileName} and \code{type} are provided. Enhanced version that
#' can capture plots before closing devices.
#'
#' @param fileName name of file to be created in directory \code{fileDirectory}
#'   without file extension '.\code{type}'.
#' @param type see \code{Cairo()}.
#' @param fileDirectory path of directory, where graphic is stored. Default
#'   setting current working directory.
#' @param oldfile old file of same name to be overwritten
#' @param capture_env Environment to store captured plots. If NULL, no capture occurs.
#'
#' @return NULL, if no \code{type} or \code{fileName} is provided, file path if graph
#'   is created
#' @examples
#'
#' # very simple KDE (adapted from example in Cairo())
#' openGraphCairo(type = "png", fileDirectory = tempdir())
#' plot(rnorm(4000), rnorm(4000), col = "#ff000018", pch = 19, cex = 2)
#' # save file 'norm.png' in directory specified in fileDirectory
#' saveGraphVisstat("norm", type = "png", fileDirectory = tempdir())
#' file.remove(file.path(tempdir(), "norm.png")) # remove file 'norm.png'
#'
#' @export
saveGraphVisstat <- function(fileName = NULL,
                             type = NULL,
                             fileDirectory = getwd(),
                             oldfile = NULL,
                             capture_env = NULL) {
  
  # logic to capture plots independent of type
  
  
  
  if (!is.null(capture_env)) {
    capture_env$captured_plots[[length(capture_env$captured_plots) + 1]] <- recordPlot()
  }
  
  if (is.null(fileName)) {
    return()
  } else if (is.null(type)) {
    return()
  } else if (is.null(oldfile)) {
    dummy_name <- "visstat_plot"
    oldPlotName <- paste(dummy_name, ".", type, sep = "")
    oldfile <- file.path(fileDirectory, oldPlotName)
  }
  
  while (!is.null(dev.list())) {
    dev.off()
  }
  
  file2 <- gsub("[^[:alnum:]]", "_", fileName)
  file3 <- gsub("_{2,}", "_", file2)
  
  newFileName <- paste0(file3, ".", type)
  Cairofile <- file.path(fileDirectory, newFileName)
  file.copy(oldfile, Cairofile, overwrite = T)
  
  if (file.exists(oldfile)) {
    file.remove(oldfile)
  }
  
  return(invisible(Cairofile))
}