## load data
data(ExampleData.XSYG, envir = environment())
bg.spectrum <- set_RLum("RLum.Data.Spectrum",
                        data = TL.Spectrum@data[, 15:16, drop = FALSE])

test_that("input validation", {
  testthat::skip_on_cran()

  expect_error(plot_RLum.Data.Spectrum("error"),
               "'object' should be of class 'RLum.Data.Spectrum' or 'matrix'")
  expect_error(plot_RLum.Data.Spectrum(set_RLum("RLum.Data.Spectrum")),
               "'object' contains no data")
  expect_error(expect_message(plot_RLum.Data.Spectrum(matrix(0, 0, 0)),
                              "Input has been converted"),
               "'object' contains no data")
  expect_error(plot_RLum.Data.Spectrum(TL.Spectrum, plot.type = "error"),
               "'plot.type' should be one of 'contour', 'persp', 'single'")
  expect_error(plot_RLum.Data.Spectrum(TL.Spectrum, norm = "error"),
               "'norm' should be one of 'max', 'min', 'first', 'last', 'huot' or")
  expect_error(plot_RLum.Data.Spectrum(TL.Spectrum, bg.spectrum = "error"),
               "'bg.spectrum' should be of class 'RLum.Data.Spectrum', 'matrix' or")
  expect_error(plot_RLum.Data.Spectrum(TL.Spectrum, bin.rows = 1.7),
               "'bin.rows' should be a single positive integer value")
  expect_error(plot_RLum.Data.Spectrum(TL.Spectrum, bin.cols = 0),
               "'bin.cols' should be a single positive integer value")

  expect_error(plot_RLum.Data.Spectrum(TL.Spectrum, xlim = 1.2),
               "'xlim' should be of class 'numeric' and have length 2")
  expect_error(plot_RLum.Data.Spectrum(TL.Spectrum, xlim = c(0, 100)),
      "No data left after applying 'xlim' and 'ylim'")
  expect_error(plot_RLum.Data.Spectrum(TL.Spectrum, xlim = c(NA, 1.2)),
               "No data left after applying 'xlim' and 'ylim'")
  expect_error(plot_RLum.Data.Spectrum(TL.Spectrum, ylim = 1.2),
               "'ylim' should be of class 'numeric' and have length 2")
  expect_error(plot_RLum.Data.Spectrum(TL.Spectrum, ylim = c(5, 10)),
      "No data left after applying 'xlim' and 'ylim'")
  expect_error(plot_RLum.Data.Spectrum(TL.Spectrum, ylim = c(NA_real_, NA_real_)),
               "No data left after applying 'xlim' and 'ylim'")
  expect_error(plot_RLum.Data.Spectrum(TL.Spectrum, zlim = 1.2),
               "'zlim' should be of class 'numeric' and have length 2")
  expect_error(plot_RLum.Data.Spectrum(TL.Spectrum, bg.spectrum = bg.spectrum,
                                       ylim = c(0, 100)),
               "No background channels left after applying 'ylim'")

  expect_warning(plot_RLum.Data.Spectrum(TL.Spectrum, bg.channels = -2),
                 "'bg.channels' out of range")
})

test_that("check functionality", {
  testthat::skip_on_cran()

    ##RLum.Data.Spectrum -------
    m <- TL.Spectrum@data

    ##try a matrix as input
    expect_message(plot_RLum.Data.Spectrum(object = m, xaxis.energy = TRUE),
                   "Input has been converted to an 'RLum.Data.Spectrum' object")

    ##remove rownames and column names
    rownames(m) <- NULL
    colnames(m) <- NULL
    expect_message(plot_RLum.Data.Spectrum(object = m),
                   "Input has been converted to an 'RLum.Data.Spectrum' object")

    ## test duplicated column names
    t <- TL.Spectrum
    colnames(t@data) <- rep(50, ncol(t@data))
    expect_warning(plot_RLum.Data.Spectrum(t),
                   "Duplicated column names found")

    ## no plot
    expect_type(plot_RLum.Data.Spectrum(TL.Spectrum, plot = FALSE),
                "double")
    expect_null(plot(TL.Spectrum, plot = FALSE))

    ##test background subtraction ... with bgchannel
    expect_warning(plot_RLum.Data.Spectrum(
      TL.Spectrum,
      plot.type = "persp",
      xlim = c(310, 750),
      ylim = c(0, 300),
      bg.spectrum = bg.spectrum,
      bg.channels = 1,
      plot = FALSE,
      bin.rows = 10,
      bin.cols = 1
    ), "6 channels removed due to row \\(wavelength\\) binning")

    ## plot: multiple.lines ---------
    expect_message(
      plot_RLum.Data.Spectrum(
        TL.Spectrum,
        plot.type = "multiple.lines",
        xlim = c(310, 750),
        frames = c(1, 3, 100),
        ylim = c(0, 50)),
      "Skipped frames exceeding the maximum (3)",
      fixed = TRUE)

    ## plot: transect ------------
    expect_silent(suppressWarnings(
      plot_RLum.Data.Spectrum(
        TL.Spectrum,
        plot.type = "transect",
        xlim = c(310, 750),
        ylim = c(0, 350),
        zlim = c(0, 1e6),
        ylab = "Counts [1 / summed channels]")))

    ## plot: interactive ------------
    expect_silent(suppressWarnings(
      plot_RLum.Data.Spectrum(
        TL.Spectrum,
        plot.type = "interactive",
        xlim = c(310, 750),
        ylim = c(0, 300),
        bin.rows = 10,
        bin.cols = 1
      )
    ))

    ## plot: interactive heatmap --------
    expect_silent(suppressWarnings(
      plot_RLum.Data.Spectrum(
        TL.Spectrum,
        plot.type = "interactive",
        xlim = c(310, 750),
        ylim = c(0, 300),
        bin.rows = 10,
        bin.cols = 1,
        type = "heatmap",
        showscale = TRUE
      )
    ))

    ##interactive contour
    expect_silent(suppressWarnings(
      plot_RLum.Data.Spectrum(
        TL.Spectrum,
        plot.type = "interactive",
        xlim = c(310, 750),
        ylim = c(0, 300),
        bin.rows = 10,
        bin.cols = 1,
        type = "contour",
        norm = "max",
        showscale = TRUE
      )
    ))

  ## normalisation replaces all values with 0
  expect_warning(expect_message(expect_null(
      plot_RLum.Data.Spectrum(TL.Spectrum, plot.type = "persp",
                              bg.spectrum = bg.spectrum, norm = "min")),
      "Error: Insufficient data for plotting, NULL returned"),
      "Curve normalisation produced Inf/NaN values, values replaced by 0")

  ## log transformation with negative data
  suppressWarnings( # surface extends beyond the box
  expect_warning(plot_RLum.Data.Spectrum(TL.Spectrum, plot.type = "persp",
                                         log = "z", norm = "huot"),
                 "Data contains non-positive values, set to NA")
  )

  ## more coverage
  plot_RLum.Data.Spectrum(TL.Spectrum, plot.type = "multiple.lines",
                          phi = 15, theta = -30, r = 10, log = "xyz",
                          shade = 0.4, expand = 0.5, border = 1,
                          optical.wavelength.colours = FALSE, rug = FALSE,
                          axes = FALSE, norm = "min", col = 2, zlim = c(0, 2))

  expect_message(expect_null(
      plot_RLum.Data.Spectrum(TL.Spectrum,
                              plot.type = "multiple.lines",
                              xlim = c(1.4, 4), ylim = c(0, 300),
                              bg.spectrum = bg.spectrum@data * 2,
                              xaxis.energy = TRUE)),
      "Error: After background subtraction all counts are negative")

  spec <- TL.Spectrum
  rownames(spec@data) <- colnames(spec@data) <- NULL
  rownames(bg.spectrum@data) <- NULL
  expect_silent(plot_RLum.Data.Spectrum(spec, bg.spectrum = bg.spectrum,
                                        xlim = c(0, 300), ylim = c(0, 500)))
})

test_that("graphical snapshot tests", {
  testthat::skip_on_cran()
  testthat::skip_if_not_installed("vdiffr")

  SW({
  vdiffr::expect_doppelganger("contour",
                              plot_RLum.Data.Spectrum(TL.Spectrum,
                                                      plot.type = "contour",
                                                      ylim = c(0, 200),
                                                      cex = 2))
  vdiffr::expect_doppelganger("persp",
                              expect_warning(
                              plot_RLum.Data.Spectrum(TL.Spectrum,
                                                      plot.type = "persp",
                                                      xlim = c(310, 750),
                                                      limit_counts = 10000,
                                                      bg.spectrum = bg.spectrum,
                                                      bin.rows = 10),
                              "6 channels removed due to row \\(wavelength\\) binning"))
  vdiffr::expect_doppelganger("persp alternate",
                              expect_warning(
                              plot_RLum.Data.Spectrum(TL.Spectrum,
                                                      plot.type = "persp",
                                                      xlim = c(410, 700),
                                                      ylim = c(200, 300),
                                                      bg.spectrum = bg.spectrum,
                                                      box = "alternate",
                                                      zlab = "test",
                                                      bin.cols = 2),
                              "1 channels removed due to column \\(frame\\) binning"))
  vdiffr::expect_doppelganger("persp theta phi ticktype",
                              expect_warning(
                              plot_RLum.Data.Spectrum(TL.Spectrum,
                                                      plot.type = "persp",
                                                      xlim = c(410, 750),
                                                      ylim = c(0, 200),
                                                      limit_counts = 20,
                                                      theta = -25,
                                                      phi = 45,
                                                      ticktype = "simple",
                                                      bin.rows = 5),
                              "'limit_counts' is smaller than the lowest count value"))
  vdiffr::expect_doppelganger("image",
                              expect_warning(
                              plot_RLum.Data.Spectrum(TL.Spectrum,
                                                      plot.type = "image",
                                                      xlim = c(310, 750),
                                                      ylim = c(50, 300),
                                                      bin.rows = 20,
                                                      col = grDevices::hcl.colors(20),
                                                      contour.col = "yellow"),
                              "3 channels removed due to row \\(wavelength\\) binning"))
  vdiffr::expect_doppelganger("image no contour",
                              plot_RLum.Data.Spectrum(TL.Spectrum,
                                                      plot.type = "image",
                                                      ylim = c(50, 250),
                                                      contour = FALSE))
  vdiffr::expect_doppelganger("image labcex bottom",
                              plot_RLum.Data.Spectrum(TL.Spectrum,
                                                      plot.type = "image",
                                                      xlim = c(310, 750),
                                                      ylim = c(0, 300),
                                                      bin.rows = 10,
                                                      cex = 2,
                                                      labcex = 1.2,
                                                      n_breaks = 10,
                                                      legend.pos = "bottom",
                                                      legend.horiz = TRUE))
  vdiffr::expect_doppelganger("single",
                              plot_RLum.Data.Spectrum(TL.Spectrum,
                                                      plot.type = "single",
                                                      xlim = c(310, 750),
                                                      ylim = c(0, 300),
                                                      frames = 2,
                                                      bin.cols = 10))
  vdiffr::expect_doppelganger("multiple",
                              plot_RLum.Data.Spectrum(TL.Spectrum,
                                                      plot.type = "multiple.lines",
                                                      xlim = c(1.4, 4),
                                                      ylim = c(0, 300),
                                                      bg.spectrum = bg.spectrum,
                                                      bg.channels = 2,
                                                      bin.cols = 1,
                                                      xaxis.energy = TRUE))
  vdiffr::expect_doppelganger("transect",
                              plot_RLum.Data.Spectrum(TL.Spectrum,
                                                      plot.type = "transect",
                                                      xlim = c(310, 750),
                                                      ylim = c(0, 300),
                                                      bin.rows = 10))
  })
})

test_that("regression tests", {
  testthat::skip_on_cran()

  ## issue 415
  expect_silent(plot_RLum.Data.Spectrum(
      TL.Spectrum,
      ylim = c(0, 100),
      bin.cols = 3))
  expect_warning(plot_RLum.Data.Spectrum(
      TL.Spectrum,
      ylim = c(0, 100),
      bin.cols = 8),
      "Single column matrix, 'plot.type' reset to 'single'")
  expect_silent(plot_RLum.Data.Spectrum(
      TL.Spectrum,
      bin.rows = 600))
  expect_message(expect_null(plot_RLum.Data.Spectrum(
      TL.Spectrum,
      bin.rows = 2000)),
      "Insufficient data for plotting, NULL returned")

  ## issue 726
  spec <- TL.Spectrum
  rownames(spec@data) <- colnames(spec@data) <- NULL
  bg.spectrum <- set_RLum(class = "RLum.Data.Spectrum",
                          data = spec@data[, 15:16, drop = FALSE])
  expect_silent(plot_RLum.Data.Spectrum(spec, bg.spectrum = bg.spectrum,
                                        xlim = c(0, 100), ylim = c(0, 10)))

  ## issue 1307
  expect_warning(plot_RLum.Data.Spectrum(TL.Spectrum, plot.type = "single",
                                         log = "z", norm = "huot"),
                 "Data contains non-positive values, set to NA")
  expect_warning(plot_RLum.Data.Spectrum(TL.Spectrum, plot.type = "transect",
                                         log = "z", norm = "huot"),
                 "Data contains non-positive values, set to NA")
})
