#' @title ETSestim
#' @description Estimates and forecasts ETS models
#'
#' @details \code{ETSestim} estimates and forecasts a time series using an
#' an ETS model
#'
#' @param m an object of type \code{ETS} created with \code{ETSforecast}
#' 
#' @return The same input object with the appropriate fields 
#' filled in, in particular:
#' \item{p}{Estimated parameters}
#' \item{yFor}{Forecasted values of output}
#' \item{yForV}{Variance of forecasted values of output}
#' \item{ySimul}{Bootstrap simulations for forecasting distribution evaluation}
#' 
#' @author Diego J. Pedregal
#' 
#' @seealso \code{\link{ETS}}, \code{\link{ETSforecast}}, \code{\link{ETSvalidate}},
#'          \code{\link{ETScomponents}}
#'          
#' @examples
#' \donttest{
#' m1 <- ETSsetup(log(gdp))
#' m1 <- ETSestim(m1)
#' }
#' @rdname ETSestim
#' @export
ETSestim = function(m){
    if (is.null(m$u))
        u = m$u
    else {
        if (is.vector(m$u)){
            u = matrix(m$u, 1, length(m$u))
        } else {
            nu = dim(m$u)
            u = as.numeric(m$u);
            u = matrix(u, nu[1], nu[2])
        }
    }
    output = ETSc("estimate", as.numeric(m$y), u, m$model, m$s, m$h,
                  m$criterion, m$armaIdent, m$identAll, m$forIntervals,
                  m$bootstrap, m$nSimul, m$verbose, m$lambda,
                  m$alphaL, m$betaL, m$gammaL, m$phiL, m$p0)
    if (length(output) == 1){   # ERROR!!
            stop()
    } else {
            m$model = output$model
            m$lambda = output$lambda
            m$p = output$p
            m$truep = output$truep
            lu = size(m$u)[1]
            if (lu > 0)
                m$h = lu - length(m$y)
            if (is.ts(m$y) && m$h > 0){
                fake = ts(c(m$y, NA), start = start(m$y), frequency = frequency(m$y))
                m$yFor = ts(output$yFor, start = end(fake), frequency = frequency(m$y))
                m$yForV = ts(output$yForV, start = end(fake), frequency = frequency(m$y))
                if (m$bootstrap)
                    m$ySimul = ts(output$ySimul, start = end(fake), frequency = frequency(m$y))
            } else if (m$h > 0) {
                m$yFor = output$yFor
                m$yForV = output$yForV
                m$ySimul = output$ySimul
            }
            m$criteria = output$criteria
            return(m)
    }
}