## load data
data(ExampleData.DeValues, envir = environment())
ExampleData.DeValues <- ExampleData.DeValues$CA1

CAM <- calc_CentralDose(ExampleData.DeValues,
                        plot = FALSE, verbose = FALSE)
FMM <- calc_FiniteMixture(ExampleData.DeValues, sigmab = 0.01,
                          n.components = 2:3, plot = FALSE, verbose = FALSE)

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

  expect_error(plot_AbanicoPlot(data = "error"),
               "All elements of 'data' should be of class 'data.frame'")
  expect_error(plot_AbanicoPlot(ExampleData.DeValues[, 1, drop = FALSE]),
               "Data set 1 has fewer than 2 columns: data without errors",
               fixed = TRUE)

  expect_message(expect_null(plot_AbanicoPlot(list())),
                 "Error: 'data' is empty, nothing plotted")
  expect_message(expect_null(plot_AbanicoPlot(ExampleData.DeValues[0, ])),
                 "Error: 'data' is empty, nothing plotted")

  expect_warning(expect_message(
      expect_null(plot_AbanicoPlot(ExampleData.DeValues[1, ])),
      "Error: After removing invalid entries, nothing is plotted"),
      "Data set 1 empty or consisting of only 1 row, removed")

  expect_error(plot_AbanicoPlot(ExampleData.DeValues, na.rm = "error"),
               "'na.rm' should be a single logical value")
  expect_error(plot_AbanicoPlot(ExampleData.DeValues, plot = FALSE),
               "'plot.ratio' should be a single positive value")
  expect_error(plot_AbanicoPlot(ExampleData.DeValues, xlab = "x"),
               "'xlab' must have length 2")
  expect_error(plot_AbanicoPlot(ExampleData.DeValues, z.0 = "error"),
               "'z.0' should be one of 'mean', 'mean.weighted', 'median' or")
  expect_error(plot_AbanicoPlot(ExampleData.DeValues, dispersion = "error"),
               "'dispersion' should be one of 'qr', 'sd', '2sd' or a percentile")
  expect_error(plot_AbanicoPlot(ExampleData.DeValues, dispersion = "p5"),
               "'dispersion' should be one of 'qr', 'sd', '2sd' or a percentile")
  expect_error(plot_AbanicoPlot(ExampleData.DeValues, dispersion = "p5a"),
               "'dispersion' should be one of 'qr', 'sd', '2sd' or a percentile")
  expect_error(plot_AbanicoPlot(ExampleData.DeValues, dispersion = "p500"),
               "'dispersion' should be one of 'qr', 'sd', '2sd' or a percentile")
  expect_error(plot_AbanicoPlot(ExampleData.DeValues, dispersion = c("p95", "p86")),
               "'dispersion' should have length 1")
  expect_error(plot_AbanicoPlot(ExampleData.DeValues, summary = 5),
               "'summary' should be of class 'character'")
  expect_error(plot_AbanicoPlot(ExampleData.DeValues, summary.pos = 5),
               "'summary.pos' should have length 2")
  expect_error(plot_AbanicoPlot(ExampleData.DeValues, summary.pos = list()),
               "'summary.pos' should be one of 'sub', 'left', 'center', 'right'")
  expect_error(plot_AbanicoPlot(ExampleData.DeValues, summary.pos = "error"),
               "'summary.pos' should be one of 'sub', 'left', 'center', 'right'")
  expect_error(plot_AbanicoPlot(ExampleData.DeValues, legend = 5),
               "'legend' should be of class 'character'")
  expect_error(plot_AbanicoPlot(ExampleData.DeValues, legend.pos = 5),
               "'legend.pos' should have length 2")
  expect_error(plot_AbanicoPlot(ExampleData.DeValues, frame = NULL),
               "'frame' should be one of '0', '1', '2' or '3'")

  expect_error(plot_AbanicoPlot(ExampleData.DeValues, xlim = NA),
               "'xlim' should be of class 'numeric'")
  expect_error(plot_AbanicoPlot(ExampleData.DeValues, ylim = NA),
               "'ylim' should be of class 'numeric'")
  expect_error(plot_AbanicoPlot(ExampleData.DeValues, zlim = NA),
               "'zlim' should be of class 'numeric'")
  expect_error(plot_AbanicoPlot(ExampleData.DeValues, zlim = c(-10, 10)),
               "'zlim' should only contain positive values when 'log.z = TRUE'")

  ## zero-error values
  data.zeros <- ExampleData.DeValues
  data.zeros[2, 2] <- 0
  expect_warning(plot_AbanicoPlot(data.zeros, grid.col = c(1, 2)),
                 "Values with zero errors cannot be displayed and were removed")
  data.zeros[, 2] <- 0
  expect_error(plot_AbanicoPlot(data.zeros),
               "Data set contains only values with zero errors")

  expect_warning(plot_AbanicoPlot(ExampleData.DeValues, xlim = c(2, 12)),
                 "Lower x-axis limit was 2, reset to zero")
})


test_that("Test examples from the example page", {
  testthat::skip_on_cran()

  ## plot the example data straightforward
  expect_silent(plot_AbanicoPlot(data = ExampleData.DeValues))

  ## now with linear z-scale
  expect_silent(plot_AbanicoPlot(data = ExampleData.DeValues,
                                 xlim = NULL, ylim = NULL, zlim = NULL,
                                 log.z = FALSE))

  ## now with adjusted scale limits
  expect_silent(plot_AbanicoPlot(data = ExampleData.DeValues,
                                 zlim = c(10, 200),
                                 xlim = c(0, 20)))

  ## now with rug to indicate individual values in KDE part
  expect_silent(plot_AbanicoPlot(data = ExampleData.DeValues,
                   rug = TRUE))

  ## now with a smaller bandwidth for the KDE plot
  expect_silent(plot_AbanicoPlot(data = ExampleData.DeValues,
                   bw = 0.04))

  ## now with a histogram instead of the KDE plot
  expect_silent(plot_AbanicoPlot(data = ExampleData.DeValues,
                   hist = TRUE,
                   kde = FALSE))

  ## now with a KDE plot and histogram with manual number of bins
  expect_silent(plot_AbanicoPlot(data = ExampleData.DeValues,
                   hist = TRUE,
                   breaks = 20))

  ## now with a KDE plot and a dot plot
  expect_silent(plot_AbanicoPlot(data = ExampleData.DeValues,
                   dots = TRUE))

  ## now with user-defined plot ratio
  expect_silent(plot_AbanicoPlot(data = ExampleData.DeValues,
                   plot.ratio = 0.5))

  ## now with user-defined central value
  expect_silent(plot_AbanicoPlot(data = ExampleData.DeValues,
                   z.0 = 70))

  ## now with median as central value
  expect_silent(plot_AbanicoPlot(data = ExampleData.DeValues,
                   z.0 = "median"))

  ## now with the 17-83 percentile range as definition of scatter
  expect_silent(plot_AbanicoPlot(data = ExampleData.DeValues,
                   z.0 = "median",
                   dispersion = "p17"))

  ## now with user-defined green line for minimum age model
  expect_silent(plot_AbanicoPlot(data = ExampleData.DeValues,
                   line = list(CAM),
                   line.col = "darkgreen",
                   line.label = "CAM"))

  ## now create plot with legend, colour, different points and smaller scale
  expect_silent(plot_AbanicoPlot(data = ExampleData.DeValues,
                   legend = "Sample 1",
                   col = "tomato4",
                   bar.col = "peachpuff",
                   pch = "R",
                   line = CAM,
                   cex = 0.8))

  ## now without 2-sigma bar, polygon, grid lines and central value line
  expect_silent(plot_AbanicoPlot(data = ExampleData.DeValues,
                   bar.col = FALSE,
                   polygon.col = FALSE,
                   grid.col = FALSE,
                   y.axis = FALSE,
                   lwd = 0))

  ## now with direct display of De errors, without 2-sigma bar
  expect_silent(plot_AbanicoPlot(data = ExampleData.DeValues,
                   bar.col = FALSE,
                   ylab = "",
                   y.axis = FALSE,
                   error.bars = TRUE))

  ## now with user-defined axes labels
  expect_silent(plot_AbanicoPlot(data = ExampleData.DeValues,
                   xlab = c("Data error (%)",
                            "Data precision"),
                   ylab = "Scatter",
                   zlab = "Equivalent dose [Gy]"))

  ## now with minimum, maximum and median value indicated
  expect_silent(plot_AbanicoPlot(data = ExampleData.DeValues,
                   stats = c("min", "max", "median")))

  ## now with another statistical summary
  expect_silent(plot_AbanicoPlot(data = ExampleData.DeValues,
                   summary = c("mean.weighted", "median"),
                   summary.pos = "topleft"))

  ## now a plot with two 2-sigma bars for one data set
  expect_silent(plot_AbanicoPlot(data = ExampleData.DeValues,
                   bar = c(30, 100)))

  ## now the data set is split into sub-groups, one is manipulated
  data.1 <- ExampleData.DeValues[1:30,]
  data.2 <- ExampleData.DeValues[31:62,] * 1.3
  data.3 <- list(data.1, data.2)

  ## now the two data sets are plotted in one plot
  expect_silent(plot_AbanicoPlot(data = data.3))

  ## now with some graphical modification
  expect_silent(plot_AbanicoPlot(data = data.3,
                   z.0 = "median",
                   col = c("steelblue4", "orange4"),
                   bar.col = c("steelblue3", "orange3"),
                   polygon.col = c("steelblue1", "orange1"),
                   pch = c(2, 6),
                   angle = c(30, 50),
                   summary = c("n", "in.2s", "median")))

  ## create Abanico plot with predefined layout definition
  layout <- expect_silent(plot_AbanicoPlot(data = ExampleData.DeValues,
                   layout = "journal"))

  ## trigger a few test cases related to layout
  layout$abanico$colour$centrality <- 1:2
  expect_silent(plot_AbanicoPlot(data = ExampleData.DeValues,
                                 rotate = TRUE,
                                 layout = "journal"))

  ## now with predefined layout definition and further modifications
  expect_silent(plot_AbanicoPlot(data = data.3,
                   z.0 = "median",
                   layout = "journal",
                   col = c("steelblue4", "orange4"),
                   bar.col = adjustcolor(c("steelblue3", "orange3"),
                                         alpha.f = 0.5),
                   polygon.col = c("steelblue3", "orange3")))

  ## for further information on layout definitions see documentation
  ## of function get_Layout()

  ## now with manually added plot content
  ## create empty plot with numeric output
  expect_type(plot_AbanicoPlot(data = ExampleData.DeValues,
                         pch = NA,
                         output = TRUE), "list")

  ## interactive mode
  expect_silent(plot_AbanicoPlot(ExampleData.DeValues, interactive = TRUE))
})

test_that("more coverage", {
  testthat::skip_on_cran()

  ## weights
  expect_silent(plot_AbanicoPlot(ExampleData.DeValues, weights = FALSE,
                                 boxplot = TRUE, frame = 2))
  suppressWarnings( # additional warning on weights not summing to 1
  expect_warning(plot_AbanicoPlot(ExampleData.DeValues, weights = TRUE,
                                  rotate = TRUE, line = 1,
                                  dispersion = "sd", log.z = FALSE,
                                  grid.col = c(1, 2)),
                 "Selecting bandwidth *not* using 'weights'",
                 fixed = TRUE)
  )

  ## negative values
  data.neg <- ExampleData.DeValues
  data.neg[1, 1] <- -1
  expect_silent(plot_AbanicoPlot(data.neg, z.0 = "mean", dispersion = "sd",
                                 boxplot = TRUE, frame = 3, zlim = c(200, 400),
                                 main = "Title", sub = "Subtitle"))
  data.neg[2, 1] <- -120
  expect_silent(plot_AbanicoPlot(data.neg, log.z = FALSE))

  ## missing values
  data.na <- ExampleData.DeValues
  data.na[1, 2] <- NA
  expect_message(plot_AbanicoPlot(data.na, rotate = TRUE, boxplot = TRUE,
                                  hist = TRUE, error.bars = TRUE, dots = TRUE,
                                  rug = TRUE, y.axis = FALSE, stats = "min",
                                  legend = "legend", legend.pos = "bottomleft",
                                  summary.pos = "bottomleft", log.z = FALSE,
                                  xlab = c("x1", "x2", "x3"), lty = 2,
                                  dispersion = "2sd",
                                  at = seq(20, 120, nrow(data.na) - 1)),
                 "Data set 1: 1 NA value excluded",
                 fixed = TRUE)
  expect_message(plot_AbanicoPlot(data.na, y.axis = TRUE,
                                  yaxt = "y",
                                  summary.pos = "bottomright",
                                  dispersion = "2sd"),
                 "Data set 1: 1 NA value excluded",
                 fixed = TRUE)

  ## further edge tests ... check for wrong bw parameter
  expect_warning(
    object = plot_AbanicoPlot(data = ExampleData.DeValues, bw = "tests"),
    regexp = "Option for 'bw' not valid, reset to 'nrd0'")

  ## negative values
  df <-  ExampleData.DeValues
  df[,1] <- -df[,1]
  expect_message(
    object = plot_AbanicoPlot(data = df),
    regexp = "Small standardised estimate scatter, toggle off y.axis?")

  ## test boundaries
  expect_warning(
    object = plot_AbanicoPlot(
    data = data.frame(x = c(0,1), y = c(0.1, 0.1))),
    "Found zero values in x-column of dataset 1, 'log.z' set to FALSE")

  ## handling of negative values; before it produced wrong plots
 expect_silent(plot_AbanicoPlot(data = data.frame(
    x = c(-1,10),
    y = c(0.1,3)
  ), log.z = TRUE, summary = c("mean", "sd.abs")))

 ## handling of negative values; but with zlim
 expect_silent(plot_AbanicoPlot(data = data.frame(
   x = c(-1,10),
   y = c(0.1,3),
   zlim = c(2,10)
 ), log.z = TRUE, summary = c("mean", "sd.abs")))

 ## test panel plots
 par.defaults <- .par_defaults()
 par(mfrow = c(4, 4))
 expect_silent(plot_AbanicoPlot(data = data.frame(
   x = c(-1,10),
   y = c(0.1,3)
 ), log.z = TRUE, summary = c("mean", "sd.abs")))
 par(par.defaults)

 ## test centrality from layout
 layout <- get_Layout("default")

 ## trigger a few test cases related to layout
 layout$abanico$colour$centrality <- 1:2
 expect_silent(
   plot_AbanicoPlot(data = list(ExampleData.DeValues, ExampleData.DeValues),
                  layout = layout))
})

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

  SW({
    vdiffr::expect_doppelganger("default",
                                plot_AbanicoPlot(ExampleData.DeValues))
    vdiffr::expect_doppelganger("dispersion error bars",
                                plot_AbanicoPlot(ExampleData.DeValues,
                                                 dispersion = "sd",
                                                 error.bars = TRUE,
                                                 hist = TRUE,
                                                 boxplot = TRUE,
                                                 summary.pos = "topleft",
                                                 summary = c("n", "se.rel", "kurtosis")))
    vdiffr::expect_doppelganger("rotated",
                                plot_AbanicoPlot(ExampleData.DeValues,
                                                 rotate = TRUE, rug = TRUE,
                                                 hist = TRUE,
                                                 boxplot = TRUE,
                                                 grid.col = "grey",
                                                 summary.pos = "bottomleft",
                                                 summary = c("mean", "in.2s", "skewness")))
    vdiffr::expect_doppelganger("dots cex",
                                plot_AbanicoPlot(ExampleData.DeValues,
                                                 dots = TRUE, cex = 2,
                                                 boxplot = TRUE,
                                                 grid.col = "grey80",
                                                 legend = "primary data",
                                                 summary.pos = "left",
                                                 summary.method = "weighted",
                                                 summary = c("sd.abs", "se.abs",
                                                             "median")))
    vdiffr::expect_doppelganger("plot ratio",
                                plot_AbanicoPlot(ExampleData.DeValues,
                                                 plot.ratio = 0.1))

    data.list <- list(ExampleData.DeValues[1:30,],
                      ExampleData.DeValues[31:62,] * 1.3)
    vdiffr::expect_doppelganger("line frame legend",
                                plot_AbanicoPlot(data = data.list,
                                                 line = 75.7,
                                                 line.lty = 3,
                                                 line.label = "CAM",
                                                 frame = 3,
                                                 legend = c("data 1", "data 2"),
                                                 cex = 1.2,
                                                 log.z = FALSE,
                                                 z.0 = "median",
                                                 col = c("steelblue4", "orange4"),
                                                 bar.col = c("steelblue3", "orange3"),
                                                 polygon.col = c("steelblue1", "orange1"),
                                                 pch = c(2, 6),
                                                 angle = c(30, 50),
                                                 summary = c("n", "in.2s", "median")))
    vdiffr::expect_doppelganger("line frame legend rotated",
                                plot_AbanicoPlot(data = data.list,
                                                 rotate = TRUE,
                                                 line = 75.7,
                                                 line.lty = 3,
                                                 line.label = "CAM",
                                                 frame = 2,
                                                 legend = c("data 1", "data 2"),
                                                 cex = 1.2,
                                                 log.z = FALSE,
                                                 z.0 = "mean",
                                                 col = c("steelblue4", "orange4"),
                                                 bar.col = c("steelblue3", "orange3"),
                                                 polygon.col = c("steelblue1", "orange1"),
                                                 pch = c(2, 6),
                                                 angle = c(30, 50),
                                                 summary = c("n", "in.2s", "median")))

    vdiffr::expect_doppelganger("CAM",
                                plot_AbanicoPlot(data = CAM,
                                                 line.col = "darkseagreen",
                                                 summary.pos = "bottomleft"))
    vdiffr::expect_doppelganger("CAM cex",
                                plot_AbanicoPlot(data = CAM, cex = 2))

    vdiffr::expect_doppelganger("FMM",
                                plot_AbanicoPlot(data = FMM, rotate = TRUE))
    vdiffr::expect_doppelganger("FMM cex",
                                plot_AbanicoPlot(data = FMM, rotate = TRUE, cex = 2))
  })
})
