#'Wind capacity factor on s2dv_cube objects
#'
#'@author Llorenç Lledó, \email{llledo@bsc.es}
#'@description Wind capacity factor computes the wind power generated by a 
#'specific wind turbine model under specific wind speed conditions, and 
#'expresses it as a fraction of the rated capacity (i.e. maximum power) of the 
#'turbine.
#'@description It is computed by means of a tabular power curve that relates 
#'wind speed to power output. The tabular values are interpolated with a linear 
#'piecewise approximating function to obtain a smooth power curve. Five 
#'different power curves that span different IEC classes can be selected (see 
#'below).
#'@references Lledó, Ll., Torralba, V., Soret, A., Ramon, J., & Doblas-Reyes, 
#'F. J. (2019). Seasonal forecasts of wind power generation. 
#'Renewable Energy, 143, 91–100. https://doi.org/10.1016/j.renene.2019.04.135 
#'@references International Standard IEC 61400-1 (third ed.) (2005)
#'
#'@param wind An s2dv_cube object with instantaneous wind speeds expressed in m/s.
#'@param IEC_class A string indicating the IEC wind class (see IEC 61400-1) of 
#'  the turbine to be selected. Classes \code{'I'}, \code{'II'} and \code{'III'}
#'  are suitable for sites with an annual mean wind speed of 10, 8.5 and 7.5 m/s 
#'  respectively. Classes \code{'I/II'} and \code{'II/III'} indicate 
#'  intermediate turbines that fit both classes. More details of the five 
#'  turbines and a plot of its power curves can be found in Lledó et al. (2019).
#'@param start An optional parameter to defined the initial date of the period
#'  to select from the data by providing a list of two elements: the initial 
#'  date of the period and the initial month of the period. By default it is set
#'  to NULL and the indicator is computed using all the data provided in 
#'  \code{data}.
#'@param end An optional parameter to defined the final date of the period to
#'  select from the data by providing a list of two elements: the final day of
#'  the period and the final month of the period. By default it is set to NULL
#'  and the indicator is computed using all the data provided in \code{data}.
#'@param time_dim A character string indicating the name of the dimension to
#'  compute the indicator. By default, it is set to 'time'. More than one
#'  dimension name matching the dimensions provided in the object
#'  \code{data$data} can be specified.
#'@param ncores An integer indicating the number of cores to use in parallel
#'  computation for temporal subsetting.
#'@return An s2dv_cube object containing the Wind Capacity Factor (unitless).
#'
#'@examples
#'wind <- NULL
#'wind$data <- array(rweibull(n = 100, shape = 2, scale = 6), 
#'                   c(member = 5, sdate = 3, time = 214, lon = 2, lat = 5))
#'wind$coords <- list(lat =  c(40, 41), lon = 1:5)
#'variable <- list(varName = 'sfcWind', 
#'                 metadata = list(sfcWind = list(level = 'Surface')))
#'wind$attrs <- list(Variable = variable, Datasets = 'synthetic', 
#'                   when = Sys.time(), Dates = '1990-01-01 00:00:00')
#'Dates <- c(seq(as.Date("01-05-2000", format = "%d-%m-%Y"), 
#'                         as.Date("30-11-2000", format = "%d-%m-%Y"), by = 'day'),
#'                     seq(as.Date("01-05-2001", format = "%d-%m-%Y"), 
#'                         as.Date("30-11-2001", format = "%d-%m-%Y"), by = 'day'),
#'                     seq(as.Date("01-05-2002", format = "%d-%m-%Y"), 
#'                         as.Date("30-11-2002", format = "%d-%m-%Y"), by = 'day'))
#'dim(Dates) <- c(sdate = 3, time = 214)
#'wind$attrs$Dates <- Dates
#'class(wind) <- 's2dv_cube'
#'WCF <- CST_WindCapacityFactor(wind, IEC_class = "III", 
#'                              start = list(21, 4), end = list(21, 6))
#'
#'@export
CST_WindCapacityFactor <- function(wind, IEC_class = c("I", "I/II", "II", "II/III", "III"),
                                   start = NULL, end = NULL, time_dim = 'time',
                                   ncores = NULL) {
  # Check 's2dv_cube'
  if (!inherits(wind, 's2dv_cube')) {
    stop("Parameter 'wind' must be of the class 's2dv_cube'.")
  } 
  # Dates subset
  if (!is.null(start) && !is.null(end)) {
    if (is.null(dim(wind$attrs$Dates))) {
      warning("Dimensions in 'wind' element 'attrs$Dates' are missed and ",
              "all data would be used.")
      start <- NULL
      end <- NULL
    }
  }
  
  WindCapacity <- WindCapacityFactor(wind = wind$data, IEC_class = IEC_class, 
                                     dates = wind$attrs$Dates, start = start, 
                                     end = end, time_dim = time_dim, 
                                     ncores = ncores)
  wind$data <- WindCapacity
  wind$dims <- dim(WindCapacity)

  if ('Variable' %in% names(wind$attrs)) {
    if ('varName' %in% names(wind$attrs$Variable)) {
      wind$attrs$Variable$varName <- 'WindCapacityFactor'
    }
  }
  if (!is.null(start) && !is.null(end)) {
     wind$attrs$Dates <- SelectPeriodOnDates(dates = wind$attrs$Dates,
                                             start = start, end = end,
                                             time_dim = time_dim, 
                                             ncores = ncores)
  }
  return(wind)
}
#'Wind capacity factor
#'
#'@author Llorenç Lledó, \email{llledo@bsc.es}
#'@description Wind capacity factor computes the wind power generated by a 
#'specific wind turbine model under specific wind speed conditions, and 
#'expresses it as a fraction of the rated capacity (i.e. maximum power) of the 
#'turbine.
#'@description It is computed by means of a tabular power curve that relates 
#'wind speed to power output. The tabular values are interpolated with a linear 
#'piecewise approximating function to obtain a smooth power curve. Five 
#'different power curves that span different IEC classes can be selected (see 
#'below).
#'@references Lledó, Ll., Torralba, V., Soret, A., Ramon, J., & Doblas-Reyes, 
#'F. J. (2019). Seasonal forecasts of wind power generation. 
#'Renewable Energy, 143, 91–100. https://doi.org/10.1016/j.renene.2019.04.135 
#'@references International Standard IEC 61400-1 (third ed.) (2005)
#'
#'@param wind A multidimensional array, vector or scalar with instantaneous wind
#'  speeds expressed in m/s.
#'@param IEC_class A string indicating the IEC wind class (see IEC 61400-1) of 
#'  the turbine to be selected. Classes \code{'I'}, \code{'II'} and \code{'III'}
#'  are suitable for sites with an annual mean wind speed of 10, 8.5 and 7.5 m/s
#'  respectively. Classes \code{'I/II'} and \code{'II/III'} indicate
#'  intermediate turbines that fit both classes. More details of the five
#'  turbines and a plot of its power curves can be found in Lledó et al. (2019).
#'@param dates A multidimensional array of dates with named dimensions matching 
#'  the temporal dimensions on parameter 'data'. By default it is NULL, to  
#'  select aperiod this parameter must be provided.
#'@param start An optional parameter to defined the initial date of the period
#'  to select from the data by providing a list of two elements: the initial
#'  date of the period and the initial month of the period. By default it is set
#'  to NULL and the indicator is computed using all the data provided in
#'  \code{data}.
#'@param end An optional parameter to defined the final date of the period to
#'  select from the data by providing a list of two elements: the final day of
#'  the period and the final month of the period. By default it is set to NULL
#'  and the indicator is computed using all the data provided in \code{data}.
#'@param time_dim A character string indicating the name of the dimension to
#'  compute the indicator. By default, it is set to 'time'. More than one
#'  dimension name matching the dimensions provided in the object
#'  \code{data$data} can be specified.
#'@param ncores An integer indicating the number of cores to use in parallel
#'  computation for temporal subsetting.
#'
#'@return An array with the same dimensions as wind, containing the Wind
#'  Capacity Factor (unitless).
#'
#'@examples
#'wind <- array(rweibull(n = 32100, shape = 2, scale = 6), 
#'              c(member = 5, sdate = 3, time = 214, lon = 2, lat = 5))
#'
#'Dates <- c(seq(as.Date("01-05-2000", format = "%d-%m-%Y"), 
#'               as.Date("30-11-2000", format = "%d-%m-%Y"), by = 'day'),
#'           seq(as.Date("01-05-2001", format = "%d-%m-%Y"), 
#'               as.Date("30-11-2001", format = "%d-%m-%Y"), by = 'day'),
#'           seq(as.Date("01-05-2002", format = "%d-%m-%Y"), 
#'               as.Date("30-11-2002", format = "%d-%m-%Y"), by = 'day'))
#'dim(Dates) <- c(sdate = 3, time = 214)
#'
#'WCF <- WindCapacityFactor(wind, IEC_class = "III", dates = Dates, 
#'                          start = list(21, 4), end = list(21, 6))
#'
#'@importFrom stats approxfun
#'@importFrom utils read.delim
#'@export
WindCapacityFactor <- function(wind, IEC_class = c("I", "I/II", "II", "II/III", "III"),
                               dates = NULL, start = NULL, end = NULL, 
                               time_dim = 'time', ncores = NULL) {
	IEC_class <-  match.arg(IEC_class)
	pc_files <- c(
		"I" 	 = "Enercon_E70_2.3MW.txt", 
		"I/II"	 = "Gamesa_G80_2.0MW.txt", 
		"II"	 = "Gamesa_G87_2.0MW.txt", 
		"II/III" = "Vestas_V100_2.0MW.txt", 
		"III"	 = "Vestas_V110_2.0MW.txt"
	)
	pc_file <- system.file("power_curves", pc_files[IEC_class], package = "CSIndicators", mustWork = T)
	pc <- read_pc(pc_file)

  if (!is.null(start) && !is.null(end)) {
    if (is.null(dates)) {
      warning("Parameter 'dates' is NULL and the average of the ",
              "full data provided in 'data' is computed.")
    } else {
      if (!any(c(is.list(start), is.list(end)))) {
        stop("Parameter 'start' and 'end' must be lists indicating the ",
             "day and the month of the period start and end.")
      }
      if (!is.null(dim(dates))) {
        wind <- SelectPeriodOnData(data = wind, dates = dates, start = start, 
                                   end = end, time_dim = time_dim, 
                                   ncores = ncores)
      } else {
        warning("Parameter 'wind' must have named dimensions if 'start' and ",
                "'end' are not NULL. All data will be used.")
      }
    }
  }

	cf <- wind2CF(wind, pc)
  dim(cf) <- dim(wind)
	return(cf)
}
