# Expected Evolution of parameters in the algorithm
render_FV_PAR_PER_FUN <- reactive({
  req(input$FV_PAR.Plot.Min, input$FV_PAR.Plot.Max)
  withProgress({
    rt_min <- as.numeric(input$FV_PAR.Plot.Min)
    rt_max <- as.numeric(input$FV_PAR.Plot.Max)
    
    tryCatch({
      data <- subset(DATA(), algId %in% input$FV_PAR.Plot.Algs)
      Plot.FV.Parameters(data, rt_min, rt_max,
                         show.mean = (input$FV_PAR.Plot.show.mean == 'mean'),
                         show.median = (input$FV_PAR.Plot.show.mean == 'median'),
                         scale.xlog = input$FV_PAR.Plot.Logx,
                         scale.ylog = input$FV_PAR.Plot.Logy, 
                         show.CI = input$FV_PAR.Plot.CI,
                         par_name = input$FV_PAR.Plot.Params)
    },
    error = function(e) {
      # TODO: more robust error handling; don't assume this causes the error
      shinyjs::alert("Not all algorithms contain the same parameters. 
                      Please select a single algorithm to plot instead.")
    }
    )
  },
  message = "Creating plot")
})

output$FV_PAR.Plot.Download <- downloadHandler(
  filename = function() {
    eval(FIG_NAME_FV_PAR_PER_FUN)
  },
  content = function(file) {
    save_plotly(render_FV_PAR_PER_FUN(), file)
  },
  contentType = paste0('image/', input$FV_PAR.Plot.Format)
)

output$FV_PAR.Plot.Figure <- renderPlotly({
  render_FV_PAR_PER_FUN()
})

# TODO: add ks test for ECDF later
# output$ks <- renderPrint({
#   target <- input$target %>% as.numeric
#   df.aligneds <- aligned()
#
#   running_time <- list()
#   for (i in seq_along(df.aligneds)) {
#     df <- df.aligneds[[i]]
#     v <- rownames(df) %>% as.numeric
#     idx <- order(abs(target - v))[1]
#     running_time[[i]] <- df[idx, ] %>% as.vector
#   }
#   algorithm1 <- running_time[[1]]
#   algorithm2 <- running_time[[2]]
#   a <- ks.test(algorithm1, algorithm2, alternative = 'less')
#   print(a)
# })
#

fv_parameter_summary <- reactive({
  req(input$FV_PAR.Summary.Min, input$FV_PAR.Summary.Max, input$FV_PAR.Summary.Step)
  
  rtstart <- as.numeric(input$FV_PAR.Summary.Min) 
  rtstop <- as.numeric(input$FV_PAR.Summary.Max)
  rtstep <- as.numeric(input$FV_PAR.Summary.Step)
  data <- DATA()
  
  if (!input$FV_PAR.Summary.Single) {
    req(rtstart <= rtstop, rtstep <= rtstop - rtstart)
    rtall <- get_runtimes(data)
    rtseq <- seq_RT(rtall, rtstart, rtstop, by = rtstep)
    req(rtseq)
  }
  else 
    rtseq <- rtstart
  
  dt <- get_PAR_summary(data, rtseq, input$FV_PAR.Summary.Algid, 
                        input$FV_PAR.Summary.Param, which = 'by_RT')
  req(length(dt) != 0)
  
  dt$runs %<>% as.integer
  dt$mean %<>% format(digits = 2, nsmall = 2)
  dt$median %<>% format(digits = 2, nsmall = 2)
  dt$sd %<>% format(digits = 2, nsmall = 2)
  
  probs <- getOption("IOHanalyzer.quantiles")
  
  # format the integers
  for (p in paste0(probs * 100, '%')) {
    dt[[p]] %<>% format(digits = 2, nsmall = 2)
  }
  dt
})

fv_parameter_sample <- reactive({
  req(input$FV_PAR.Sample.Algid, input$FV_PAR.Sample.Max,
      input$FV_PAR.Sample.Step, input$FV_PAR.Sample.Min,
      input$FV_PAR.Sample.Param)
  
  rtstart <- as.numeric(input$FV_PAR.Sample.Min) 
  rtstop <- as.numeric(input$FV_PAR.Sample.Max)
  rtstep <- as.numeric(input$FV_PAR.Sample.Step)
  data <- DATA()
  
  if (!input$FV_PAR.Sample.Single) {
    req(rtstart <= rtstop, rtstep <= rtstop - rtstart)
    rtall <- get_runtimes(data)
    rtseq <- seq_RT(rtall, rtstart, rtstop, by = rtstep)
    req(rtseq)
  }
  else
    rtseq <- rtstart
  
  df <- get_PAR_sample(data, idxValue = rtseq, 
                       algorithm = input$FV_PAR.Sample.Algid,
                       parId = input$FV_PAR.Sample.Param,
                       output = input$FV_PAR.Sample.Format,
                       which = 'by_RT')
  
  for (p in paste0('run.', seq(ncol(data[[1]]$FV))))
    df[[p]] %<>% format(digits = 2, nsmall = 2)
  
  df
})

output$table_FV_PAR_SAMPLE <- DT::renderDataTable({
  dt <- fv_parameter_sample()
  req(length(dt) != 0)
  dt[is.na(dt)] <- 'NA'
  dt
}, filter = list(position = 'top', clear = FALSE),
options = list(dom = 'lrtip', pageLength = 15, scrollX = T, server = T))

output$table_FV_PAR_summary <- DT::renderDataTable({
  fv_parameter_summary()
}, filter = list(position = 'top', clear = FALSE),
options = list(dom = 'lrtip', pageLength = 15, scrollX = T, server = T, digits = 2))

output$FV_PAR.Sample.Download <- downloadHandler(
  filename = function() {
    eval(PARSample_csv_name)
  },
  content = function(file) {
    df <- parameter_sample()
    df <- df[input[["table_FV_PAR_SAMPLE_rows_all"]]]
    if (input$FV_PAR.Sample.FileFormat == 'csv')
      write.csv(df, file, row.names = F)
    else
      print(xtable(df), file = file)
  },
  contentType = "text/csv"
)

output$FV_PAR.Summary.Download <- downloadHandler(
  filename = function() {
    eval(PAR_csv_name)
  },
  content = function(file) {
    df <- parameter_summary()
    df <- df[input[["table_FV_PAR_summary_rows_all"]]]
    if (input$FV_PAR.Summary.Format == 'csv')
      write.csv(df, file, row.names = F)
    else
      print(xtable(df), file = file)
  },
  contentType = "text/csv"
)