#' Save kable to files
#'
#' @param x A piece of HTML code for tables, usually generated by kable and
#' kableExtra
#' @param file save to files. If the input table is in HTML and the output file
#' ends with `.png`, `.pdf` and `.jpeg`, `webshot` will be used to do the
#' conversion.
#' @param bs_theme Which Bootstrap theme to use
#' @param self_contained Will the files be self-contained?
#' @param extra_dependencies Additional HTML dependencies. For example,
#' `list(`
#' @param ... Additional variables being passed to `webshot::webshot`. This
#' is for HTML only.
#' @param latex_header_includes A character vector of extra LaTeX header stuff.
#' Each element is a row. You can have things like
#' `c("\\\\usepackage{threeparttable}", "\\\\usepackage{icons}")`  You could
#' probably add your language package here if you use non-English text in your
#' table, such as `\\\\usepackage[magyar]{babel}`.
#' @param keep_tex A T/F option to control if the latex file that is initially created
#' should be kept. Default is `FALSE`.
#'
#' @export
save_kable <- function(x, file,
                       bs_theme = "simplex", self_contained = TRUE,
                       extra_dependencies = NULL, ...,
                       latex_header_includes = NULL, keep_tex = FALSE) {
  if (!is.null(attr(x, "format")) && attr(x, "format") == "latex") {
    return(save_kable_latex(x, file, latex_header_includes, keep_tex))
  }
  return(save_kable_html(x, file, bs_theme, self_contained,
                         extra_dependencies, ...))
}

save_kable_html <- function(x, file, bs_theme, self_contained,
                            extra_dependencies, ...) {
  dependencies <- list(
    rmarkdown::html_dependency_jquery(),
    rmarkdown::html_dependency_bootstrap(theme = bs_theme),
    rmarkdown::html_dependency_font_awesome(),
    html_dependency_kePrint()
  )
  if (!is.null(extra_dependencies)) {
    dependencies <- append(dependencies, extra_dependencies)
  }

  html_header <- htmltools::tag("head", dependencies)
  html_table <- htmltools::HTML(as.character(x))
  html_result <- htmltools::tagList(html_header, html_table)

  # Use webshot if necessary
  if (tools::file_ext(file) %in% c("png", "jpg", "jpeg", "pdf")) {
    message("Putting together a HTML file...")
    file_html <- paste0(tools::file_path_sans_ext(file), ".html")
    htmltools::save_html(html_result, file = file_html)
    message("Converting HTML to ", tools::file_ext(file), "...")
    webshot::webshot(file_html, file, ...)
    message("Done. ")
    if (tools::file_ext(file) == "pdf") {
      message("Note that HTML color may not be displayed on PDF properly.")
    }
    unlink(file_html)
    unlink("lib", recursive = TRUE)
  } else {
    htmltools::save_html(html_result, file = file)
    if (self_contained) {
      rmarkdown::pandoc_self_contained_html(file, file)
      unlink("lib", recursive = TRUE)
    }
  }

  return(file)
}

save_kable_latex <- function(x, file, latex_header_includes, keep_tex) {
  temp_tex <- c(
    "\\documentclass[border=1mm, preview]{standalone}",
    "\\usepackage[active,tightpage]{preview}",
    "\\usepackage{varwidth}",
    "\\usepackage{amssymb, amsmath}",
    "\\usepackage{ifxetex,ifluatex}",
    "\\usepackage{fixltx2e}",
    "\\usepackage{polyglossia}",
    "\\setmainlanguage{$mainlang$}",
    latex_pkg_list(),
    "\\usepackage{graphicx}",
    "\\usepackage{mathspec}",
    "\\usepackage{xltxtra,xunicode}",
    latex_header_includes,
    "\\begin{document}",
    solve_enc(x),
    "\\end{document}"
  )
  temp_tex <- paste(temp_tex, collapse = "\n")

  temp_tex_file <- paste0(tools::file_path_sans_ext(file), ".tex")
  writeLines(temp_tex, temp_tex_file, useBytes = T)
  system(paste0("xelatex -interaction=batchmode ", temp_tex_file))
  if (!keep_tex) {
    temp_file_delete <- paste0(tools::file_path_sans_ext(file),
                               c(".tex", ".aux", ".log"))
    unlink(temp_file_delete)
  }

  if (tools::file_ext(file) != "pdf") {
    table_img_pdf <- try(
      magick::image_read(paste0(tools::file_path_sans_ext(file), ".pdf"),
                         density = 300), silent = T)
    if (class(table_img_pdf) == "try-error") {
      stop("We hit an error when trying to use magick to read the generated ",
           "PDF file. If you are using Windows, it could be possible that you",
           " had not installed ghostscript (https://ghostscript.com/). ",
           "Otherwise, you may check your magick installation and try to ",
           "use magick::image_read to read the PDF file manually. ")
    }
    unlink(paste0(tools::file_path_sans_ext(file), ".pdf"))
    table_img <- magick::image_convert(table_img_pdf,
                                       tools::file_ext(file))
    magick::image_write(table_img, file)
  }

  return(file)
}
