#' ADAMONT Quantiles S2D computes quantiles for seasonal or decadal forecast data
#'
#'@author Paola Marson, \email{paola.marson@meteo.fr} for PROSNOW version
#'@author Lauriane Batté, \email{lauriane.batte@meteo.fr} for CSTools adaptation
#'@description This function computes quantiles on either reference or seasonal-to-decadal ensemble DAILY forecast data following the ADAMONT method adapted from Verfaillie et al. (2018). A prerequisite is to attribute each day and member of the S2D re-forecast to a given weather type / regime.
#'
#'@param exp an object of class \code{s2dv_cube} of lonlat data as returned by \code{CST_Load} function, containing the reference or seasonal forecast experiment data in \code{$data}, dimensions c(dataset,member,sdate,ftime,lat,lon)
#'@param var variable name (string)
#'@param wt an object of same member, sdate and ftime dimensions as exp, with weather type attribution (values 1 to Nwt where Nwt is the number of weather types)
#'@param tslice list of c(tmin,tmax) is the range of forecast times for which quantiles should be computed (default: NULL, values computed over all forecast times)
#'@param method a string among two options for extrapolation of extrema (default 'ADA': ADAMONT quantile computation, 'interp': interpolated quantile values)
#'@param seqq a list of quantiles (default to c(0.005, seq(from=0.01, to=0.00, by=0.01), 0.995))
#'@param wetonly a logical (default to FALSE); which days quantiles of precipitation are computed (all days or wet)
#'
#'@return qexp an array with dimensions c(Nwt, Nq+2, lat, lon) where the Nq+2 values are [min value; Nq quantiles; max value].
#'
#'@import s2dverification
#'@import ncdf4
#'@import abind
#'
#' EXAMPLE TO BE INSERTED HERE...
#'
#'
#'exp <- runif(n=1*10*20*60*6*7,min=0.,max=5.)
#'dim(exp) <- c(dataset=1,member=10,sdate=20,ftime=60,lat=6,lon=7)
#'wt <- sample(1:4,1*10*20*60,replace=T) # Random sample for weather types numbered from 1 to 4
#'dim(wt) <- c(dataset=1,member=10,sdate=20,ftime=60)

##### Input order should be changed...

Quantiles_S2D <- function(exp, var, wt, tslice=NULL, method='ADA', seqq=c(0.005,seq(from=0.01, to=0.99, by=0.01),0.995), wetonly=FALSE) {

#
#
# CHECKS NEEDED: 
# WT VALUES SHOULD BE 1:NWT
# DIMENSIONS OF EXP AND WT DATA SHOULD BE CONSISTENT
#

interp_quant<-function(data){
   out<-quantile(data,p=seqq,na.rm=TRUE)
   return(c(min(data,na.rm=TRUE),out,max(data,na.rm=TRUE)))
}

ADA_quant<-function(data){
   out<-quantile(data,p=seqq,type=1,na.rm=TRUE)
   return(c(min(data,na.rm=TRUE),out,max(data,na.rm=TRUE)))
}

# Which quantiles method to apply
quant <- switch(method,'ADA'=ADA_quant,'interp'=interp_quant)

# Number of different weather types
wt_f <- wt
dim(wt_f) <- c(prod(dim(wt)))
Nwt <- length(unique(wt_f))

# Select ftimes for quantile computation
if (is.null(tslice)){
   warning('tslice=NULL: Computing quantiles over each forecast time')
   dat <- exp$data
}else if (length(tslice) != 2) {
   stop("Parameter 'tslice' must have length equal to 2 (c(tmin,tmax)) ")
}else {
   dat <- exp$data[,,,tslice[1]:tslice[2],,,drop=FALSE]
}

# Wet days only if variable is precipitation/snow and wetonly=TRUE
if ((var=='prlr') && (wetonly==TRUE)){
   norain=which(exp<1.)
   dat[norain]=NA
}

# Rearrange and flatten dimensions to use apply() function
dim_dat <- dim(dat)
dat_f <- aperm(dat,c(5,6,1,2,3,4))
dim(dat_f) <- c(dim_dat[5],dim_dat[6],prod(dim_dat[1:4]))

qexp <- array(dim=c(type=Nwt,quantiles=dim(array(seqq))+2,dim_dat[5],dim_dat[6]))

for (reg in 1:Nwt){
	qexp[reg,,,] <- apply(dat_f[,,which(wt == reg)],c(1,2),quant)
}

return(qexp)
}


