#' @name ggInterval
#' @title A symbolic object by R6 class for interval analysis and ggplot
#' @description  This is an object that will be used to make a ggplot
#' object.A ggInterval object contains both classic data that user have
#' and interval data which we transform.More over,some basic statistics
#' from row data will also be recorded in this object,and the interval
#' data which is from RSDA transformation will still contain RSDA
#' properties.
#' @import R6
#'
#' @export
ggInterval <- R6::R6Class(
  classname = "ggInterval",
  public = list(
    #' @field rawData the data from user.
    rawData = "data.frame",
    
    #' @field statisticsDF contains min max mean median dataframe for each group of symbolic data
    statisticsDF = "list",
    
    #' @field intervalData interval data from RSDA type
    intervalData = "data.frame",
    
    #' @field clusterResult clustering result
    clusterResult = "list",
    
    #' @description
    #' initialize all data, check whether satisfy theirs form
    initialize = function(rawData = NULL,
                          statisticsDF = NULL,
                          intervalData = NULL,
                          clusterResult = NULL) {
      self$rawData <- rawData
      self$statisticsDF <- statisticsDF
      self$intervalData <- intervalData
      self$clusterResult <- clusterResult
      
      if (private$invalidDataType()) {
        stop("Object type error in statisticsDF")
      }
    }
  ),
  private = list(
    invalidDataType = function() {
      n <- length(self$statisticsDF)
      isAllDF <- all(unlist(lapply(self$statisticsDF[1:n], FUN = is.data.frame)))
      return(!isAllDF)
    }
  )
)

#test whether data can be used for ggplot
testData <- function(data) {
  if ("ggInterval" %in% class(data)) {
    # if ggInterval class?
    return(data)
  } else{
    if (("symbolic_tbl" %in% class(data))) {
      #if RSDA class?
      return(RSDA2sym(data))
    } else{
      warning("Automatically transform a classical data to symbolic data")
      return(classic2sym(data))
    }
  }
}

testXY <- function(iData, this.x, this.y) {
  p <- dim(iData)[2]
  with(iData, {
    isVarX <- any(unlist(lapply(
      iData[, 1:p], FUN = identical, x = eval(this.x)
    )))
    isVarY <- any(unlist(lapply(
      iData[, 1:p], FUN = identical, x = eval(this.y)
    )))
    if (isVarX && isVarY) {
      stop("ERROR : This plot must have exactly one variable")
    }
  })
}


addFactor <- function(rawData, iData) {
  tryCatch({
    test <- unlist(lapply(rawData, is.factor))
    if (any(test)) {
      factorIndex <- which(test)
      if (dim(rawData)[1] == dim(iData)[1]) {
        #OK
        for (i in factorIndex) {
          iData <- dplyr::bind_cols(iData, tmp = rawData[[i]])
          colnames(iData)[dim(iData)[2]] <- colnames(rawData)[i]
        }
      }
    }
    return(iData)
  }, error = function(err) {
    return(iData)
  })
}
