#' Rescale values between minimum and maximum.
#'
#' For a vector of numeric values, the minimum and maximum values are determined
#'     and each value of the vector is rescaled between 0 and 1.
#'     Values near 0 are close to the minimum, values near 1 are close to the
#'     max. This function is utilized by other TSAR functions.
#' @param x a numeric vector to be rescaled
#' @return A numeric vector of rescaled values.
#' @family TSAR Formatting
#' @examples
#' x <- c(0, 1, 3)
#' rescale(x)
#'
#' @export
#'

rescale <- function(x) { # Rescale values between two values.
    rescaled_v <- (x - min(x)) / (max(x) - min(x))
    return(rescaled_v)
}


#' Normalize Fluorescence Curve
#'
#' This function will take the TSA data and normalize the arbitrary fluorescence
#'     measurements based on the specified method. Each well, determined by a
#'     unique well ID, is normalized independently.
#'     All measurements can be normalized to the minimum or maximum value.
#'     Alternatively, setting  \code{by = "rescale"} (the default) will cause
#'     all values to be normalized between the minimum and
#'     maximum values, with the maximum  = 1 and the minimum = 0 and all other
#'     values normalized in-between. Finally, the user can supply a single
#'     value or vector of values to normalize the data to. The returned data
#'     frame will be the input tsa data frame with a new column named "RFU"
#'     containing the normalized TSA data.
#' @param tsa_data a data frame that is unmerged and generated by
#'     TSAR::read_raw_data() or a merged TSA data frame generated by
#'     TSAR::merge_TSA(). Data frames require a column named "Fluorescence"
#'    containing numeric values for normalizing.
#' @param by character string; either c("rescale", "min", "max", "control").
#'     \code{by = "rescale"} by default, scaling Fluorescence values in-between
#'     the minimum and maximum observation. Each well can be
#'     normalized to either the minimum or maximum value with
#'     \code{by = "min"} or \code{by = "max"}, respectively. To normalize
#'     all values to a numeric value or vector, set \code{by = "control"}.
#' @param control_vect numeric vector to normalize the column "Fluorescence"
#'     to. An individual number will normalize all measurements to be normalized
#'     to it. The vector will need to align with tsa_data$Fluorescence. Ensure
#'     \code{by = "control"}, else the supplied vector will be ignored.
#'
#' @return a data frame identical to the tsa_data input with a new column
#'     named "RFU" containing the normalized values
#' @family TSAR Formatting
#' @seealso \code{\link{read_raw_data}} and  \code{\link{merge_TSA}}
#'     for loading data.
#' @examples
#' # examples not ran without example dataset
#' # raw_data <- read_raw_data(raw_data_path)
#' # normalize_fluorescence(raw_data, by == "control)
#'
#' @export
#'

normalize_fluorescence <- function(
    tsa_data = tsa_data,
    by = "rescale",
    control_vect = NA) {

    by <- match.arg(by, choices = c("rescale", "max", "min", "control"))

    if ("well_ID" %in% names(tsa_data)) {
        well_ids <- unique(tsa_data$well_ID)
        n_well_ids <- length(well_ids)
    } else {
        stop("A data frame loaded by read_raw_data() must be supplied")
    }
    tsa_data$RFU <- rep(NA, nrow(tsa_data))

    if (by == "rescale") { # Rescale between the min and max
        tsa_data$RFU <- unlist(lapply(well_ids, function(well_id) {
            tsa_data$Fluorescence[tsa_data$well_ID == well_id] <-
                rescale(tsa_data$Fluorescence[tsa_data$well_ID == well_id])
            tsa_data$Fluorescence[tsa_data$well_ID == well_id]
        }))

    }
    if (by == "max") { # Rescale by max
        tsa_data$RFU <- unlist(lapply(well_ids, function(well_id) {
            tsa_data$Fluorescence[tsa_data$well_ID == well_id] <-
                tsa_data$Fluorescence[tsa_data$well_ID == well_id] /
                max(tsa_data$Fluorescence[tsa_data$well_ID == well_id])
            tsa_data$Fluorescence[tsa_data$well_ID == well_id]
        }))

    }
    if (by == "min") { # Rescale by min
        tsa_data$RFU <- unlist(lapply(well_ids, function(well_id) {
            tsa_data$RFU[tsa_data$well_ID == well_id] <-
                tsa_data$Fluorescence[tsa_data$well_ID == well_id] /
                    min(tsa_data$Fluorescence[tsa_data$well_ID == well_id])
            tsa_data$Fluorescence[tsa_data$well_ID == well_id]
        }))
    }
    if (by == "control") { # Rescale by user supplied vector
        tsa_data$RFU <- unlist(lapply(well_ids, function(well_id) {
            tsa_data$RFU[tsa_data$well_ID == well_id] <-
                tsa_data$Fluorescence[tsa_data$well_ID == well_id] /
                control_vect
            tsa_data$Fluorescence[tsa_data$well_ID == well_id]
        }))
    }
    return(tsa_data)
}
