###############################################################################
##################### Scorecard visualization plotting  #######################
###############################################################################

## This function loads the saved netcdf files containing the spatially 
## aggregated skill metrics for the scorecards and plots the scorecard
## visualizations. The function reads from the general recipe.

##### Load source functions #####
source('modules/Scorecards/R/tmp/LoadMetrics.R')
source('modules/Scorecards/R/tmp/Utils.R')
source('modules/Scorecards/R/tmp/SCTransform.R')
source('modules/Scorecards/R/tmp/ScorecardsSingle.R')
source('modules/Scorecards/R/tmp/ScorecardsMulti.R')
source('modules/Scorecards/R/tmp/ScorecardsSystemDiff.R')
source('modules/Scorecards/R/tmp/VizScorecard.R') 

## Temporary for new ESviz function
source('modules/Scorecards/R/tmp/ColorBarContinuous.R')
source('modules/Scorecards/R/tmp/ClimPalette.R')
.IsColor <- s2dv:::.IsColor
.FilterUserGraphicArgs <- s2dv:::.FilterUserGraphicArgs

## Define function
Scorecards_plotting <- function(recipe) {
  
  ## Parameters for loading data files
  input.path <- paste0(recipe$Run$output_dir, "/outputs/Scorecards/")
  output.path <- paste0(recipe$Run$output_dir, "/plots/Scorecards/")
  dir.create(output.path, recursive = T, showWarnings = F)
  
  system <- as.vector(unlist(recipe$Analysis$Datasets$System$name))
  reference <- as.vector(unlist(recipe$Analysis$Datasets$Reference$name))
  
  var <- recipe$Analysis$Variables$name
  start.year <- as.numeric(recipe$Analysis$Time$hcst_start)
  end.year <- as.numeric(recipe$Analysis$Time$hcst_end)
  forecast.months <- recipe$Analysis$Time$ftime_min:recipe$Analysis$Time$ftime_max
  calib.method <- tolower(recipe$Analysis$Workflow$Calibration$method)
  metrics <- unlist(strsplit(tolower(recipe$Analysis$Workflow$Scorecards$metric), 
                             ", | |,"))
  
  if (recipe$Analysis$Workflow$Scorecards$start_months == 'all' || 
      is.null(recipe$Analysis$Workflow$Scorecards$start_months)) {
    start.months <- as.numeric(substr(recipe$Analysis$Time$sdate, 1, 2))
  } else {
    start.months <- as.numeric(strsplit(recipe$Analysis$Workflow$Scorecards$start_months,
                                        split = ", | |,")[[1]])
    if(!any(as.numeric(substr(recipe$Analysis$Time$sdate, 1,2))) %in% start.months){
      error(recipe$Run$logger,"Requested start dates for scorecards must be loaded")
    }
  }
  start.months <- sprintf("%02d", start.months)
  period <- paste0(start.year, "-", end.year)
  
  ## Parameters for data aggregation
  regions <- recipe$Analysis$Workflow$Scorecards$regions
  for (i in names(regions)){regions[[i]] <- unlist(regions[[i]])}

  ## Parameters for scorecard layout
  table.label <-  recipe$Analysis$Workflow$Scorecards$table_label
  fileout.label <- recipe$Analysis$Workflow$Scorecards$fileout_label
  col1.width <- recipe$Analysis$Workflow$Scorecards$col1_width
  col2.width <- recipe$Analysis$Workflow$Scorecards$col2_width
  legend.breaks <- recipe$Analysis$Workflow$Scorecards$legend_breaks
  legend.width <- recipe$Analysis$Workflow$Scorecards$legend_width
  
  if (is.null(recipe$Analysis$Workflow$Scorecards$plot_legend)) {
    plot.legend <- TRUE
  } else {
    plot.legend <- recipe$Analysis$Workflow$Scorecards$plot_legend
  }
  
  if (is.null(recipe$Analysis$Workflow$Scorecards$columns_width)) {
    columns.width <- 1.2
  } else {
    columns.width <- recipe$Analysis$Workflow$Scorecards$columns_width 
  }
  
  if (is.null(recipe$Analysis$Workflow$Scorecards$legend_white_space)) {
    legend.white.space <- 6
  } else {
    legend.white.space <- recipe$Analysis$Workflow$Scorecards$legend_white_space
  }

  if (is.null(recipe$Analysis$Workflow$Scorecards$legend_height)) {
    legend.height <- 50
  } else {
    legend.height <- recipe$Analysis$Workflow$Scorecards$legend_height
  }
  
  if (is.null(recipe$Analysis$Workflow$Scorecards$label_scale)) {
    label.scale <- 1.4
  } else {
    label.scale <- recipe$Analysis$Workflow$Scorecards$label_scale
  }
  
  if (is.null(recipe$Analysis$Workflow$Scorecards$round_decimal)) {
    round.decimal <- 2
  } else {
    round.decimal <- recipe$Analysis$Workflow$Scorecards$round_decimal
  }
  
  if (is.null(recipe$Analysis$Workflow$Scorecards$font_size)) {
    font.size <- 1.1
  } else {
    font.size <- recipe$Analysis$Workflow$Scorecards$font_size
  }
  
  ## Define if difference scorecard is to be plotted
  if (is.null(recipe$Analysis$Workflow$Scorecards$calculate_diff)) {
    calculate.diff <- FALSE
  } else {
    calculate.diff <- recipe$Analysis$Workflow$Scorecards$calculate_diff
  }
  
  
  if ('name' %in% names(recipe$Analysis$Variables)) {
    if (recipe$Analysis$Variables$name == var) {
      var.units <- recipe$Analysis$Variables$units
    }
  } else {
    for (i in 1:length(recipe$Analysis$Variables)) {
      if (recipe$Analysis$Variables[[i]]$name == var) { 
        var.units <- recipe$Analysis$Variables[[i]]$units 
      }
    }
  }
  
  ####### Load data files #######
  aggregated_metrics <- LoadMetrics(input_path = input.path,
                                   system = system,
                                   reference = reference,
                                   var = var,
                                   data_type = "aggr_metrics",
                                   period = period,
                                   start_months = as.numeric(start.months),
                                   calib_method = calib.method)
  
  attributes(aggregated_metrics)$metrics <- metrics
  
  aggregated_significance <- LoadMetrics(input_path = input.path,
                                         system = system,
                                         reference = reference,
                                         var = var,
                                         data_type = "aggr_significance",
                                         period = period,
                                         start_months = as.numeric(start.months),
                                         calib_method = calib.method)
  
  aggregated_significance <- aggregated_significance == 1


  ####### PLOT SCORECARDS ##########

  ## Create simple scorecard tables 
  ## (one system only)
  ## Metrics input must be in the same order as function SC_spatial_aggregation
  scorecard_single <- ScorecardsSingle(data = aggregated_metrics,
                                       sign = aggregated_significance,
                                       system = system,
                                       reference = reference,
                                       var = var,
                                       var.units = var.units,
                                       start.year = start.year,
                                       end.year = end.year,
                                       start.months = start.months,
                                       forecast.months = forecast.months,
                                       region.names = names(regions),
                                       metrics = metrics,
                                       table.label =  table.label,
                                       fileout.label = fileout.label,
                                       plot.legend = plot.legend,
                                       legend.breaks = legend.breaks,
                                       legend.white.space = legend.white.space, 
                                       legend.width = legend.width,
                                       legend.height = legend.height,
                                       label.scale = label.scale,
                                       col1.width = col1.width,
                                       col2.width = col2.width,
                                       columns.width = columns.width,
                                       font.size = font.size,
                                       round.decimal = round.decimal,
                                       output.path = output.path)
  
  ## Create multi system/reference scorecard tables
  ## (multiple systems with one reference or one system with multiple references)
  ## Metrics input must be in the same order as function SC_spatial_aggregation
  if (length(system) >  1 || length(reference) >  1) {
    scorecard_multi <- ScorecardsMulti(data = aggregated_metrics,
                                       sign = aggregated_significance,
                                       system = system,
                                       reference = reference,
                                       var.units = var.units,
                                       start.year = start.year,
                                       end.year = end.year,
                                       start.months = start.months,
                                       forecast.months = forecast.months,
                                       region.names = names(regions),
                                       metrics = metrics,
                                       table.label =  table.label,
                                       fileout.label = fileout.label,
                                       plot.legend = plot.legend,
                                       legend.breaks = legend.breaks,
                                       legend.white.space = legend.white.space, 
                                       legend.width = legend.width,
                                       legend.height = legend.height,
                                       label.scale = label.scale,
                                       col1.width = col1.width,
                                       col2.width = col2.width,
                                       columns.width = columns.width,
                                       font.size = font.size,
                                       round.decimal = round.decimal,
                                       output.path = output.path)
  } ## close if
  
  if (calculate.diff == TRUE) {
    if (length(system) ==  2 || length(reference) ==  2) {
      scorecard_diff <- ScorecardsSystemDiff(data = aggregated_metrics,
                                             system = system,
                                             reference = reference,
                                             var = var,
                                             var.units = var.units,
                                             start.year = start.year,
                                             end.year = end.year,
                                             start.months = start.months,
                                             forecast.months = forecast.months,
                                             region.names = attributes(regions)$names,
                                             metrics = metrics,
                                             table.label = table.label,
                                             fileout.label =  fileout.label,
                                             legend.white.space = legend.white.space, 
                                             col1.width = col1.width,
                                             col2.width = col2.width,
                                             output.path = output.path)
    } else {
      stop("Difference scorecard can only be computed with two systems or ",
           "two references.")}
  } ## close if on calculate.diff

}

