R/SeaSondeRAPM.R

Defines functions summary.SeaSondeRAPM print.SeaSondeRAPM seasonder_plotAPMLoops seasonder_readPhaseFile seasonder_readSeaSondeRAPMFile parse_metadata_line read_matrix_row seasonder_extrapolateAPM seasonder_applyAPMAmplitudeAndPhaseCorrections seasonder_trimAPM seasonder_smoothAPM seasonder_getSeaSondeRAPM_FileID seasonder_setSeaSondeRAPM_FileID seasonder_setSeaSondeRAPM_CommentLine seasonder_getSeaSondeRAPM_CommentLine seasonder_setSeaSondeRAPM_Smoothing seasonder_getSeaSondeRAPM_Smoothing seasonder_setSeaSondeRAPM_BearingResolution seasonder_getSeaSondeRAPM_BearingResolution seasonder_setSeaSondeRAPM_StationCode seasonder_getSeaSondeRAPM_StationCode seasonder_setSeaSondeRAPM_AntennaBearing seasonder_getSeaSondeRAPM_AntennaBearing seasonder_setSeaSondeRAPM_AmplitudeFactors seasonder_getSeaSondeRAPM_AmplitudeFactors seasonder_setSeaSondeRAPM_ProcessingSteps seasonder_getSeaSondeRAPM_ProcessingSteps seasonder_setSeaSondeRAPM_CreateTimeStamp seasonder_getSeaSondeRAPM_CreateTimeStamp seasonder_setSeaSondeRAPM_FileName seasonder_getSeaSondeRAPM_FileName seasonder_setSeaSondeRAPM_SiteOrigin seasonder_getSeaSondeRAPM_SiteOrigin seasonder_setSeaSondeRAPM_SiteName seasonder_getSeaSondeRAPM_SiteName seasonder_setSeaSondeRAPM_Creator seasonder_getSeaSondeRAPM_Creator seasonder_setSeaSondeRAPM_Type seasonder_getSeaSondeRAPM_Type seasonder_setSeaSondeRAPM_PhaseCorrections seasonder_getSeaSondeRAPM_PhaseCorrections seasonder_setSeaSondeRAPM_BEAR seasonder_getSeaSondeRAPM_BEAR seasonder_setSeaSondeRAPM_quality_matrix seasonder_getSeaSondeRAPM_quality_matrix seasonder_getVersion.SeaSondeRAPM validate_SeaSondeRAPM_PhaseCorrections validate_SeaSondeRAPM_FileID validate_SeaSondeRAPM_CommentLine validate_SeaSondeRAPM_Smoothing validate_SeaSondeRAPM_BearingResolution validate_SeaSondeRAPM_StationCode validate_SeaSondeRAPM_AntennaBearing validate_SeaSondeRAPM_AmplitudeFactors validate_SeaSondeRAPM_ProcessingSteps validate_SeaSondeRAPM_CreateTimeStamp validate_SeaSondeRAPM_FileName validate_SeaSondeRAPM_SiteOrigin validate_SeaSondeRAPM_SiteName validate_SeaSondeRAPM_Creator validate_SeaSondeRAPM_Type validate_SeaSondeRAPM_BEAR validate_SeaSondeRAPM_quality_matrix seasonder_validateAttributesSeaSondeRAPM seasonder_validateCalibrationMatrixSeaSondeRAPM SeaSondeRAPM_SiteOrigin_override_step_text SeaSondeRAPM_amplitude_factors_override_step_text SeaSondeRAPM_phase_correction_override_step_text SeaSondeRAPM_amplitude_and_phase_corrections_step_text SeaSondeRAPM_trimming_step_text SeaSondeRAPM_smoothing_step_text SeaSondeRAPM_antenna_bearing_override_step_text SeaSondeRAPM_creation_step_text seasonder_initializeAttributesSeaSondeRAPM seasonder_createSeaSondeRAPM

Documented in parse_metadata_line print.SeaSondeRAPM read_matrix_row SeaSondeRAPM_amplitude_and_phase_corrections_step_text SeaSondeRAPM_amplitude_factors_override_step_text SeaSondeRAPM_antenna_bearing_override_step_text SeaSondeRAPM_creation_step_text SeaSondeRAPM_phase_correction_override_step_text SeaSondeRAPM_SiteOrigin_override_step_text SeaSondeRAPM_smoothing_step_text SeaSondeRAPM_trimming_step_text seasonder_applyAPMAmplitudeAndPhaseCorrections seasonder_createSeaSondeRAPM seasonder_extrapolateAPM seasonder_getSeaSondeRAPM_AmplitudeFactors seasonder_getSeaSondeRAPM_AntennaBearing seasonder_getSeaSondeRAPM_BEAR seasonder_getSeaSondeRAPM_BearingResolution seasonder_getSeaSondeRAPM_CommentLine seasonder_getSeaSondeRAPM_CreateTimeStamp seasonder_getSeaSondeRAPM_Creator seasonder_getSeaSondeRAPM_FileID seasonder_getSeaSondeRAPM_FileName seasonder_getSeaSondeRAPM_PhaseCorrections seasonder_getSeaSondeRAPM_ProcessingSteps seasonder_getSeaSondeRAPM_quality_matrix seasonder_getSeaSondeRAPM_SiteName seasonder_getSeaSondeRAPM_SiteOrigin seasonder_getSeaSondeRAPM_Smoothing seasonder_getSeaSondeRAPM_StationCode seasonder_getSeaSondeRAPM_Type seasonder_getVersion.SeaSondeRAPM seasonder_initializeAttributesSeaSondeRAPM seasonder_plotAPMLoops seasonder_readPhaseFile seasonder_readSeaSondeRAPMFile seasonder_setSeaSondeRAPM_AmplitudeFactors seasonder_setSeaSondeRAPM_AntennaBearing seasonder_setSeaSondeRAPM_BEAR seasonder_setSeaSondeRAPM_BearingResolution seasonder_setSeaSondeRAPM_CommentLine seasonder_setSeaSondeRAPM_CreateTimeStamp seasonder_setSeaSondeRAPM_Creator seasonder_setSeaSondeRAPM_FileID seasonder_setSeaSondeRAPM_FileName seasonder_setSeaSondeRAPM_PhaseCorrections seasonder_setSeaSondeRAPM_ProcessingSteps seasonder_setSeaSondeRAPM_quality_matrix seasonder_setSeaSondeRAPM_SiteName seasonder_setSeaSondeRAPM_SiteOrigin seasonder_setSeaSondeRAPM_Smoothing seasonder_setSeaSondeRAPM_StationCode seasonder_setSeaSondeRAPM_Type seasonder_smoothAPM seasonder_trimAPM seasonder_validateAttributesSeaSondeRAPM seasonder_validateCalibrationMatrixSeaSondeRAPM summary.SeaSondeRAPM validate_SeaSondeRAPM_AmplitudeFactors validate_SeaSondeRAPM_AntennaBearing validate_SeaSondeRAPM_BEAR validate_SeaSondeRAPM_BearingResolution validate_SeaSondeRAPM_CommentLine validate_SeaSondeRAPM_CreateTimeStamp validate_SeaSondeRAPM_Creator validate_SeaSondeRAPM_FileID validate_SeaSondeRAPM_FileName validate_SeaSondeRAPM_PhaseCorrections validate_SeaSondeRAPM_ProcessingSteps validate_SeaSondeRAPM_quality_matrix validate_SeaSondeRAPM_SiteName validate_SeaSondeRAPM_SiteOrigin validate_SeaSondeRAPM_Smoothing validate_SeaSondeRAPM_StationCode validate_SeaSondeRAPM_Type

#' Create a SeaSondeRAPM Object
#'
#' This function creates a SeaSondeRAPM object to store antenna pattern calibration data.
#'
#' @param calibration_matrix A 3 x b complex matrix, where b is the number of bearings for calibration.
#' @param ... Additional named attributes that will be passed to \code{\link{seasonder_initializeAttributesSeaSondeRAPM}}.
#'
#' @return A SeaSondeRAPM object containing a complex matrix with class attribute 'SeaSondeRAPM' and
#'         additional attributes for metadata. Row names are set "A13", "A23" and "A33" and column names are set to be the values in BEAR.
#'
#' @details
#' The function performs the following operations:
#' 1. Validates the \code{calibration_matrix} with \code{\link{seasonder_validateCalibrationMatrixSeaSondeRAPM}}.
#' 2. Initializes all other attributes either with default or user-provided values.
#' 3. Merges the initialized attributes into \code{calibration_matrix}.
#' 4. Sets the object's class to 'SeaSondeRAPM'.
#'
#' For more details on the attributes, see \code{\link{seasonder_initializeAttributesSeaSondeRAPM}}.
#'
#' @seealso
#' \code{\link{seasonder_validateCalibrationMatrixSeaSondeRAPM}},
#' \code{\link{seasonder_initializeAttributesSeaSondeRAPM}}
#'
#' @importFrom rlang %||%
#' @importFrom magrittr %>% %<>%
#' @export
#' @examples
#'   # Create a test SeaSondeRAPM object by reading sample file
#'   apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#'   obj <- seasonder_readSeaSondeRAPMFile(apm_file)
seasonder_createSeaSondeRAPM <- function(calibration_matrix = matrix(complex(real = NA_real_, imaginary = NA_real_),
                                                                     nrow = 3, ncol = 0), ...) {

  # Validate the calibration matrix to ensure it meets required criteria
  seasonder_validateCalibrationMatrixSeaSondeRAPM(calibration_matrix)

  # Set row names for the calibration matrix channels
  rownames(calibration_matrix) <- c("A13", "A23", "A33")

  # Initialize attributes (metadata and quality information) with defaults or user-provided values
  attributes_list <- seasonder_initializeAttributesSeaSondeRAPM(calibration_matrix, ...)

  # Determine the dataset type based on several conditions.
  # First, check if the 'Type' attribute is not already set to either "Measured" or "Ideal".
  # If not set, then proceed as follows:
  # 1. If 'FileName' contains "MeasPattern", assign "Measured" to 'Type'.
  # 2. Else if 'FileName' contains "IdealPattern", assign "Ideal" to 'Type'.
  # 3. Else if 'StationCode' exactly equals "XXXX", assign "Ideal" to 'Type'.
  # 4. Else if 'StationCode' is non-empty, assign "Measured" to 'Type'.
  # This logic ensures that each file is classified correctly as either "Measured" or "Ideal"
  # based on its file name pattern or station code.
  if (length(attributes_list$Type) == 0 ||
      !( "Measured" %in% attributes_list$Type ||
         "Ideal" %in% attributes_list$Type)) {
    attributes_list$Type <- dplyr::case_when(
      length(attributes_list$FileName) > 0 & grepl("MeasPattern", attributes_list$FileName) ~ "Measured",
      length(attributes_list$FileName) > 0 & grepl("IdealPattern", attributes_list$FileName) ~ "Ideal",
      length(attributes_list$StationCode) > 0 & attributes_list$StationCode == "XXXX" ~ "Ideal",
      length(attributes_list$StationCode) > 0 & nchar(attributes_list$StationCode) > 0 ~ "Measured",
      nchar(attributes_list$StationCode) > 0 ~ "Measured",
      TRUE ~ attributes_list$Type
    )
  }

  # Assign column names to the calibration matrix using the BEAR attribute from the initialized list
  colnames(calibration_matrix) <- attributes_list$BEAR

  # Iterate over each attribute in the attributes list to update the calibration matrix using its setter
  calibration_matrix <- attributes_list %>%
    purrr::reduce2(
      names(attributes_list),
      \(cal_matrix_so_far, attribute, attribute_name) {
        # Construct the name of the setter function dynamically
        setter_fun <- get(glue::glue("seasonder_setSeaSondeRAPM_{attribute_name}"))
        # Apply the setter function to update the current state of the calibration matrix
        cal_matrix_so_far <- setter_fun(cal_matrix_so_far, new_value = attribute)
      },
      .init = calibration_matrix
    )

  # Assign the custom class "SeaSondeRAPM" to the calibration matrix object
  class(calibration_matrix) <- c("SeaSondeRAPM", class(calibration_matrix))

  # Set a version attribute for the object
  attr(calibration_matrix, "version") <- 1

  # Log a message indicating successful creation of the APM object
  seasonder_logAndMessage("seasonder_createSeaSondeRAPM: APM object created successfully.", "info")

  # Return the fully constructed SeaSondeRAPM object
  return(calibration_matrix)
}


#' Initialize Attributes for a SeaSondeRAPM Object
#'
#' This function initializes attributes for a SeaSondeRAPM object, including metadata and properties.
#'
#' @param calibration_matrix A 2 x b complex matrix, where b is the number of bearings for calibration.
#' @param ... Additional named attributes that may override the defaults.
#'
#' @return A list containing initialized attributes for a SeaSondeRAPM object.
#'
#' @details
#' The function initializes the following attributes:
#' - \code{quality_matrix}: A 3 x b complex matrix for quality data, where b is the number of bearings.
#' - \code{BEAR}: A numeric vector for bearings (degrees CCW from the site bearing).
#' - \code{Type}: Character string for antenna pattern type.
#' - \code{Creator}: Object creator name. Default is an empty character vector.
#' - \code{SiteName}: Site name (not the same as SiteCode). Default is an empty character vector.
#' - \code{SiteOrigin}: Numeric vector with two elements representing the Station GPS location. Default is \code{c(0,0)}.
#' - \code{FileName}: Default is an empty character vector.
#' - \code{CreateTimeStamp}: APM file creation time. Default is current system date and time.
#' - \code{ProcessingSteps}: Processing steps applied to this object. Default is an empty character vector.
#' - \code{AmplitudeFactors}: Numeric vector with two elements for the amplitude factors. Default is \code{c(0,0)}.
#' - \code{AntennaBearing}: Site bearing (CW degrees from true north). Default is an empty numeric vector.
#' - \code{StationCode}: 4-character station code. Default is an empty character vector.
#' - \code{BearingResolution}: In degrees. Default is an empty numeric vector.
#' - \code{Smoothing}: Numeric vector indicating smoothing applied to the antenna pattern. Default is an empty numeric vector.
#' - \code{CommentLine}: Metadata lines in the data file not matching any other attribute. Default is an empty character vector.
#' - \code{FileID}: File's UUID. Default is an empty character vector.
#' - \code{PhaseCorrections}: Numeric vector with two elements for phase corrections. Default is \code{c(0,0)}.
#'
#' @seealso
#' \code{\link{seasonder_createSeaSondeRAPM}},
#' \code{\link{seasonder_validateAttributesSeaSondeRAPM}}
#'
#' @importFrom magrittr %<>%
#' @export
#' @examples
#'   # Initialize attributes for a dummy calibration matrix
#'   attrs <- seasonder_initializeAttributesSeaSondeRAPM(matrix(1:6, nrow = 3))
seasonder_initializeAttributesSeaSondeRAPM <- function(calibration_matrix, ...) {

  # Define default attribute values for the SeaSondeRAPM object
  defaults <- list(
    quality_matrix = matrix(complex(real = NA_real_, imaginary = NA_real_), nrow = 3, ncol = ncol(calibration_matrix)),
    BEAR = numeric(ncol(calibration_matrix)),
    Type = character(0),
    Creator = character(0),
    SiteName = character(0),
    SiteOrigin = numeric(2),
    FileName = character(0),
    CreateTimeStamp = Sys.time(),
    ProcessingSteps = character(0),
    AmplitudeFactors = numeric(2),
    AntennaBearing = numeric(0),
    StationCode = character(0),
    BearingResolution = numeric(0),
    Smoothing = numeric(0),
    CommentLine = character(0),
    FileID = character(0),
    PhaseCorrections = numeric(2)
  )

  # Merge user-provided attributes with defaults; in case of homonyms, the first provided is used
  out <- do.call(rlang::dots_list, c(rlang::list2(...), defaults, list(.homonyms = "first")))

  # Retain only the attributes defined in defaults (preserving the expected order)
  out <- out[names(defaults)]

  # Return the initialized attributes list
  return(out)
}


#### Processing_steps ####

#' Generate Creation Step Text
#'
#' This function generates a text message indicating the time an APM object was created based on the current system time and the provided file path.
#'
#' @param file_path A character string specifying the path to the file.
#'
#' @return A character string with the formatted creation message.
#'
SeaSondeRAPM_creation_step_text <- function(file_path) {
  # Format and return the creation message with the current time and file path using glue
  glue::glue("{Sys.time()}: Created from {file_path}.")
}

#' Generate Antenna Bearing Override Step Text
#'
#' This function generates a message indicating that the AntennaBearing attribute was overridden.
#'
#' @param antenna_bearing The new antenna bearing value.
#'
#' @return A character string stating that the antenna bearing has been overridden.
#'
SeaSondeRAPM_antenna_bearing_override_step_text <- function(antenna_bearing) {
  # Return a formatted message stating that the antenna bearing has been overridden
  glue::glue("{Sys.time()}: AntennaBearing overriden with value {antenna_bearing}.")
}

#' Generate Smoothing Step Text
#'
#' This function generates a message indicating that smoothing has been applied to the APM.
#'
#' @param smoothing The smoothing parameter (number of points used).
#'
#' @return A character string detailing the smoothing operation.
#'
SeaSondeRAPM_smoothing_step_text <- function(smoothing){
  # Return a formatted message stating the smoothing parameter used
  glue::glue("{Sys.time()}: APM smoothed with smoothing {smoothing}.")
}

#' Generate Trimming Step Text
#'
#' This function generates a message indicating that trimming has been applied to the APM.
#'
#' @param trimming The number of points trimmed from each end of the APM.
#'
#' @return A character string with the trimming details.
#'
SeaSondeRAPM_trimming_step_text <- function(trimming){
  # Return a formatted message stating how many points were trimmed from the APM ends
  glue::glue("{Sys.time()}: trimmed {trimming} points on APM ends.")
}

#' Generate Amplitude and Phase Corrections Step Text
#'
#' This function generates a message indicating the amplitude and phase corrections applied to the APM.
#'
#' @param amplitude1 Amplitude correction for the first channel.
#' @param amplitude2 Amplitude correction for the second channel.
#' @param phase1 Phase correction (in degrees) for the first channel.
#' @param phase2 Phase correction (in degrees) for the second channel.
#'
#' @return A character string detailing the applied amplitude and phase corrections.
#'
SeaSondeRAPM_amplitude_and_phase_corrections_step_text <- function(amplitude1, amplitude2, phase1, phase2){
  # Return a formatted message detailing the amplitude and phase corrections applied
  glue::glue("{Sys.time()}: Phase corrections {phase1}, {phase2}, and amplitude correction {amplitude1}, {amplitude2} applied to APM.")
}

#' Generate Phase Correction Override Step Text
#'
#' This function generates a message indicating that phase corrections have been overridden.
#'
#' @param phase_correction A numeric vector with two elements for the new phase corrections.
#'
#' @return A character string stating the new phase correction values.
#'
SeaSondeRAPM_phase_correction_override_step_text <- function(phase_correction) {
  # Return a formatted message stating the new phase correction values
  glue::glue("{Sys.time()}: PhaseCorrection overriden with values {phase_correction[1]} and {phase_correction[2]}.")
}

#' Generate Amplitude Factors Override Step Text
#'
#' This function generates a message indicating that amplitude factors have been overridden.
#'
#' @param amplitude_factors A numeric vector with two elements for the new amplitude factors.
#'
#' @return A character string stating the new amplitude factors.
#'
SeaSondeRAPM_amplitude_factors_override_step_text <- function(amplitude_factors) {
  # Return a formatted message stating the new amplitude factors
  glue::glue("{Sys.time()}: AmplitudeFactors overriden with values {amplitude_factors[1]} and {amplitude_factors[2]}.")
}

#' Generate SiteOrigin Override Step Text
#'
#' This function generates a message indicating that the SiteOrigin has been overridden.
#'
#' @param SiteOrigin A numeric vector with two elements representing the new latitude and longitude.
#'
#' @return A character string with the updated SiteOrigin details.
#'
SeaSondeRAPM_SiteOrigin_override_step_text <- function(SiteOrigin) {
  # Return a formatted message stating the new SiteOrigin (latitude and longitude)
  glue::glue("{Sys.time()}: SiteOrigin overriden with Latitude {SiteOrigin[1]} and Longitude {SiteOrigin[2]}.")
}


#### Validation ####

#' Validate Calibration Matrix for a SeaSondeRAPM Object
#'
#' This function validates the input calibration_matrix to ensure it meets the required specifications
#' for use in a SeaSondeRAPM object.
#'
#' @param matrix A 3 x b complex matrix for calibration, where b is the number of bearings.
#'
#' @return TRUE if the matrix is valid. The function will stop execution and display an error message if the matrix is invalid.
#'
#' @details
#' The function performs the following validation checks:
#' 1. Confirms that the input is a matrix.
#' 2. Verifies that the matrix has exactly three rows.
#' 3. Checks that the matrix contains only complex numbers.
#'
#' If any of these validation steps fail, the function will log a fatal error and stop the execution using \code{rlang::abort}.
#'
#' @seealso
#' \code{\link{seasonder_createSeaSondeRAPM}}
#'
#' @export
#' @examples
#' valid <- seasonder_validateCalibrationMatrixSeaSondeRAPM(
#'   matrix(complex(real = 1, imaginary = 0), nrow = 3, ncol = 5)
#' )
seasonder_validateCalibrationMatrixSeaSondeRAPM <- function(matrix) {
  # Check if the input is a matrix
  if (!is.matrix(matrix)) {
    seasonder_logAndMessage("seasonder_validateCalibrationMatrixSeaSondeRAPM: Input calibration_matrix must be a matrix.", "fatal")
    rlang::abort("seasonder_validateCalibrationMatrixSeaSondeRAPM: Input calibration_matrix must be a matrix.")
  }

  # Verify that the matrix has exactly three rows
  if (nrow(matrix) != 3) {
    seasonder_logAndMessage("seasonder_validateCalibrationMatrixSeaSondeRAPM: Calibration matrix must have three rows.", "fatal")
    rlang::abort("seasonder_validateCalibrationMatrixSeaSondeRAPM: Calibration matrix must have three rows.")
  }

  # Ensure that the matrix contains complex numbers only
  if (!is.complex(matrix)) {
    seasonder_logAndMessage("seasonder_validateCalibrationMatrixSeaSondeRAPM: Calibration matrix must contain complex numbers.", "fatal")
    rlang::abort("seasonder_validateCalibrationMatrixSeaSondeRAPM: Calibration matrix must contain complex numbers.")
  }

  # If all checks pass, return TRUE
  TRUE
}

#' Validate Attributes for a SeaSondeRAPM Object
#'
#' This function validates the attributes of a given SeaSondeRAPM object to ensure they meet the required specifications.
#'
#' @param seasonde_apm_obj A SeaSondeRAPM object whose attributes are to be validated.
#'
#' @return TRUE if all attributes are valid. The function will stop execution and display an error message if any of the attributes are invalid.
#'
#' @details
#' The function performs validation on the following attributes of the SeaSondeRAPM object:
#' - quality_matrix
#' - BEAR
#' - Type
#' - Creator
#' - SiteName
#' - SiteOrigin
#' - FileName
#' - CreateTimeStamp
#' - ProcessingSteps
#' - AmplitudeFactors
#' - AntennaBearing
#' - StationCode
#' - BearingResolution
#' - Smoothing
#' - CommentLine
#' - FileID
#' - PhaseCorrections
#'
#' It internally calls specific validation functions for each of these attributes. If any of the attributes are found to be invalid, the function will stop execution and display an error message.
#'
#' @seealso
#' \code{\link{validate_SeaSondeRAPM_quality_matrix}},
#' \code{\link{validate_SeaSondeRAPM_BEAR}},
#' \code{\link{validate_SeaSondeRAPM_Type}},
#' \code{\link{validate_SeaSondeRAPM_Creator}},
#' \code{\link{validate_SeaSondeRAPM_SiteName}},
#' \code{\link{validate_SeaSondeRAPM_SiteOrigin}},
#' \code{\link{validate_SeaSondeRAPM_FileName}},
#' \code{\link{validate_SeaSondeRAPM_CreateTimeStamp}},
#' \code{\link{validate_SeaSondeRAPM_ProcessingSteps}},
#' \code{\link{validate_SeaSondeRAPM_AmplitudeFactors}},
#' \code{\link{validate_SeaSondeRAPM_AntennaBearing}},
#' \code{\link{validate_SeaSondeRAPM_StationCode}},
#' \code{\link{validate_SeaSondeRAPM_BearingResolution}},
#' \code{\link{validate_SeaSondeRAPM_Smoothing}},
#' \code{\link{validate_SeaSondeRAPM_CommentLine}},
#' \code{\link{validate_SeaSondeRAPM_FileID}},
#' \code{\link{validate_SeaSondeRAPM_PhaseCorrections}}
#'
#' @export
#' @examples
#' # Create a test SeaSondeRAPM object by reading sample file
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' valid <- seasonder_validateAttributesSeaSondeRAPM(obj)
seasonder_validateAttributesSeaSondeRAPM <- function(seasonde_apm_obj) {
  # Validate each attribute of the SeaSondeRAPM object using their respective validation functions
  validate_SeaSondeRAPM_quality_matrix(attributes(seasonde_apm_obj)$quality_matrix, seasonde_apm_obj)
  validate_SeaSondeRAPM_BEAR(attributes(seasonde_apm_obj)$BEAR, seasonde_apm_obj)
  validate_SeaSondeRAPM_Type(attributes(seasonde_apm_obj)$Type)
  validate_SeaSondeRAPM_Creator(attributes(seasonde_apm_obj)$Creator)
  validate_SeaSondeRAPM_SiteName(attributes(seasonde_apm_obj)$SiteName)
  validate_SeaSondeRAPM_SiteOrigin(attributes(seasonde_apm_obj)$SiteOrigin)
  validate_SeaSondeRAPM_FileName(attributes(seasonde_apm_obj)$FileName)
  validate_SeaSondeRAPM_CreateTimeStamp(attributes(seasonde_apm_obj)$CreateTimeStamp)
  validate_SeaSondeRAPM_ProcessingSteps(attributes(seasonde_apm_obj)$ProcessingSteps)
  validate_SeaSondeRAPM_AmplitudeFactors(attributes(seasonde_apm_obj)$AmplitudeFactors)
  validate_SeaSondeRAPM_AntennaBearing(attributes(seasonde_apm_obj)$AntennaBearing)
  validate_SeaSondeRAPM_StationCode(attributes(seasonde_apm_obj)$StationCode)
  validate_SeaSondeRAPM_BearingResolution(attributes(seasonde_apm_obj)$BearingResolution)
  validate_SeaSondeRAPM_Smoothing(attributes(seasonde_apm_obj)$Smoothing)
  validate_SeaSondeRAPM_CommentLine(attributes(seasonde_apm_obj)$CommentLine)
  validate_SeaSondeRAPM_FileID(attributes(seasonde_apm_obj)$FileID)
  validate_SeaSondeRAPM_PhaseCorrections(attributes(seasonde_apm_obj)$PhaseCorrections)

  # Return TRUE if all validations pass
  return(TRUE)
}

#' Validate quality_matrix Attribute for a SeaSondeRAPM Object
#'
#' This function validates if the provided quality_matrix is a 3-row complex matrix.
#' It also checks if the number of columns matches that of the calibration_matrix in the given SeaSondeRAPM object.
#'
#' @param matrix The matrix to be validated.
#' @param seasonde_apm_obj The SeaSondeRAPM object for compatibility check.
#' @return Returns TRUE if the validation passes.
#'
validate_SeaSondeRAPM_quality_matrix <- function(matrix, seasonde_apm_obj) {
  # Check that the matrix is a valid 3-row complex matrix
  if (!is.matrix(matrix) || nrow(matrix) != 3 || !is.complex(matrix)) {
    msg <- "validate_SeaSondeRAPM_quality_matrix: The quality_matrix must be a 3-row complex matrix."
    seasonder_logAndMessage(msg, "fatal")
    rlang::abort(msg)
  }

  # Check that the number of columns in the quality_matrix matches the calibration_matrix
  if (ncol(matrix) != ncol(seasonde_apm_obj)) {
    msg <- glue::glue("validate_SeaSondeRAPM_quality_matrix: The quality_matrix must be a {ncol(seasonde_apm_obj)}-column complex matrix, same as the calibration_matrix. Currently has {ncol(matrix)} columns.")
    seasonder_logAndMessage(msg, "fatal")
    rlang::abort(msg)
  }

  # Return TRUE if both checks pass
  return(TRUE)
}

#' Validate BEAR Attribute for a SeaSondeRAPM Object
#'
#' This function validates if the provided BEAR is a numeric vector and if its length
#' matches the number of columns in the calibration_matrix of the given SeaSondeRAPM object.
#' It also validates that the bearings are between -180 and 180 degrees.
#'
#' @param vector The numeric vector to be validated.
#' @param seasonde_apm_obj The SeaSondeRAPM object for compatibility check.
#' @return Returns TRUE if the validation passes.
#'
validate_SeaSondeRAPM_BEAR <- function(vector, seasonde_apm_obj) {
  # Ensure BEAR is numeric
  if (!is.numeric(vector)) {
    msg <- "validate_SeaSondeRAPM_BEAR: BEAR must be a numeric vector."
    seasonder_logAndMessage(msg, "fatal")
    rlang::abort(msg)
  }

  # Check that the length of BEAR matches the number of columns in the calibration matrix
  if (length(vector) != ncol(seasonde_apm_obj)) {
    msg <- glue::glue("validate_SeaSondeRAPM_BEAR: BEAR must be a numeric vector of length {ncol(seasonde_apm_obj)}, matching the number of columns of the calibration matrix. Currently is of length {length(vector)}.")
    seasonder_logAndMessage(msg, "fatal")
    rlang::abort(msg)
  }

  # Validate that all bearing values are within the range -180 to 180 degrees
  if (any(!dplyr::between(vector, -180, 180))) {
    msg <- glue::glue("validate_SeaSondeRAPM_BEAR: BEAR must be a numeric vector of values between -180 and 180.")
    seasonder_logAndMessage(msg, "fatal")
    rlang::abort(msg)
  }

  # Return TRUE if all validations pass
  return(TRUE)
}

#' Validate Type Attribute for a SeaSondeRAPM Object
#'
#' This function validates if the provided Type is a character string.
#'
#' @param type The character string to be validated.
#' @return Returns TRUE if the validation passes.
#'
validate_SeaSondeRAPM_Type <- function(type) {
  # Check if type is a character vector
  if (!is.character(type)) {
    seasonder_logAndAbort("validate_SeaSondeRAPM_Type: Type must be a character string.", "fatal")
  }
  # If type is non-empty, it must be either "Measured" or "Ideal"
  if (length(type) > 0 && !all(type %in% c("Measured", "Ideal"))) {
    seasonder_logAndAbort("validate_SeaSondeRAPM_Type: When provided, Type must be either 'Measured' or 'Ideal'.", "fatal")
  }
  return(TRUE)
}

#' Validate Creator Attribute for a SeaSondeRAPM Object
#'
#' This function validates if the provided Creator is a character string.
#'
#' @param creator The character string to be validated.
#' @return Returns TRUE if the validation passes.
#'
validate_SeaSondeRAPM_Creator <- function(creator) {
  # Ensure Creator is a character string
  if (!is.character(creator)) {
    seasonder_logAndMessage("validate_SeaSondeRAPM_Creator: Creator must be a character string.", "fatal")
    rlang::abort("validate_SeaSondeRAPM_Creator: Creator must be a character string.")
  }
  return(TRUE)
}

#' Validate SiteName Attribute for a SeaSondeRAPM Object
#'
#' This function validates if the provided SiteName is a character string.
#'
#' @param site_name The character string to be validated.
#' @return Returns TRUE if the validation passes.
#'
validate_SeaSondeRAPM_SiteName <- function(site_name) {
  # Check if SiteName is a character string
  if (!is.character(site_name)) {
    seasonder_logAndMessage("validate_SeaSondeRAPM_SiteName: SiteName must be a character string.", "fatal")
    rlang::abort("validate_SeaSondeRAPM_SiteName: SiteName must be a character string.")
  }
  return(TRUE)
}

#' Validate SiteOrigin Attribute for a SeaSondeRAPM Object
#'
#' This function validates if the provided SiteOrigin is a numeric vector of length 2.
#'
#' @param site_origin The numeric vector to be validated.
#' @return Returns TRUE if the validation passes.
#'
validate_SeaSondeRAPM_SiteOrigin <- function(site_origin) {
  # Check if SiteOrigin is numeric and has exactly 2 elements
  if (!is.numeric(site_origin) | length(site_origin) != 2) {
    msg <- glue::glue("validate_SeaSondeRAPM_SiteOrigin: SiteOrigin must be a numeric vector of length 2. Current length is {length(site_origin)}")
    seasonder_logAndMessage(msg, "fatal")
    rlang::abort(msg)
  }
  return(TRUE)
}

#' Validate FileName Attribute for a SeaSondeRAPM Object
#'
#' This function validates if the provided FileName is a character string.
#'
#' @param file_name The character string to be validated.
#' @return Returns TRUE if the validation passes.
#'
validate_SeaSondeRAPM_FileName <- function(file_name) {
  # Check if FileName is a character string
  if (!is.character(file_name)) {
    seasonder_logAndMessage("validate_SeaSondeRAPM_FileName: FileName must be a character string.", "fatal")
    rlang::abort("validate_SeaSondeRAPM_FileName: FileName must be a character string.")
  }
  return(TRUE)
}

#' Validate CreateTimeStamp Attribute for a SeaSondeRAPM Object
#'
#' This function validates if the provided CreateTimeStamp is a POSIXct Date object.
#'
#' @param timestamp The Date object to be validated.
#' @return Returns TRUE if the validation passes.
#'
validate_SeaSondeRAPM_CreateTimeStamp <- function(timestamp) {
  # Check if the timestamp inherits from POSIXct (i.e., is a valid date-time object)
  if (!inherits(timestamp, "POSIXct")) {
    seasonder_logAndMessage("validate_SeaSondeRAPM_CreateTimeStamp: CreateTimeStamp must be a Date object.", "fatal")
    rlang::abort("validate_SeaSondeRAPM_CreateTimeStamp: CreateTimeStamp must be a Date object.")
  }
  return(TRUE)
}

#' Validate ProcessingSteps Attribute for a SeaSondeRAPM Object
#'
#' This function validates if the provided ProcessingSteps is a character vector.
#'
#' @param steps The character vector to be validated.
#' @return Returns TRUE if the validation passes.
#'
validate_SeaSondeRAPM_ProcessingSteps <- function(steps) {
  # Ensure ProcessingSteps is a character vector
  if (!is.character(steps)) {
    seasonder_logAndMessage("validate_SeaSondeRAPM_ProcessingSteps: ProcessingSteps must be a character vector.", "fatal")
    rlang::abort("validate_SeaSondeRAPM_ProcessingSteps: ProcessingSteps must be a character vector.")
  }
  return(TRUE)
}

#' Validate AmplitudeFactors Attribute for a SeaSondeRAPM Object
#'
#' This function validates if the provided AmplitudeFactors is a numeric vector of length 2.
#'
#' @param factors The numeric vector to be validated.
#' @return Returns TRUE if the validation passes.
#'
validate_SeaSondeRAPM_AmplitudeFactors <- function(factors) {
  # Check if AmplitudeFactors is numeric and exactly length 2
  if (!is.numeric(factors) | length(factors) != 2) {
    msg <- glue::glue("validate_SeaSondeRAPM_AmplitudeFactors: AmplitudeFactors must be a numeric vector of length 2. Current length is {length(factors)}")
    seasonder_logAndMessage(msg, "fatal")
    rlang::abort(msg)
  }
  return(TRUE)
}

#' Validate AntennaBearing Attribute for a SeaSondeRAPM Object
#'
#' This function validates if the provided AntennaBearing is a numeric value.
#'
#' @param bearing The numeric value to be validated.
#' @return Returns TRUE if the validation passes.
#'
validate_SeaSondeRAPM_AntennaBearing <- function(bearing) {
  # Ensure that AntennaBearing is numeric
  if (!is.numeric(bearing)) {
    seasonder_logAndMessage("validate_SeaSondeRAPM_AntennaBearing: AntennaBearing must be a numeric value.", "fatal")
    rlang::abort("validate_SeaSondeRAPM_AntennaBearing: AntennaBearing must be a numeric value.")
  }
  return(TRUE)
}

#' Validate StationCode Attribute for a SeaSondeRAPM Object
#'
#' This function validates if the provided StationCode is an empty character string or a 4-character string of length 1.
#'
#' @param code The character string to be validated.
#' @return Returns TRUE if the validation passes.
#'
validate_SeaSondeRAPM_StationCode <- function(code) {
  # Check if StationCode is a character string
  if (!is.character(code)) {
    msg <- glue::glue("validate_SeaSondeRAPM_StationCode: StationCode must be a character string. Provided value is {code}")
    seasonder_logAndMessage(msg, "fatal")
    rlang::abort(msg)
  }
  # If a non-empty code is provided, check its length and number of characters
  if (length(code) > 0) {
    if (length(code) == 1) {
      if (nchar(code) != 4) {
        msg <- glue::glue("validate_SeaSondeRAPM_StationCode: StationCode must have 4 characters. Provided value is {code}.")
        seasonder_logAndMessage(msg, "fatal")
        rlang::abort(msg)
      }
    } else {
      msg <- glue::glue("validate_SeaSondeRAPM_StationCode: StationCode must have length 0 or 1. Provided value is {length(code)}.")
      seasonder_logAndMessage(msg, "fatal")
      rlang::abort(msg)
    }
  }
  return(TRUE)
}

#' Validate BearingResolution Attribute for a SeaSondeRAPM Object
#'
#' This function validates if the provided BearingResolution is a numeric value.
#'
#' @param resolution The numeric value to be validated.
#' @return Returns TRUE if the validation passes.
#'
validate_SeaSondeRAPM_BearingResolution <- function(resolution) {
  # Check if BearingResolution is numeric
  if (!is.numeric(resolution)) {
    seasonder_logAndMessage("validate_SeaSondeRAPM_BearingResolution: BearingResolution must be a numeric value.", "fatal")
    rlang::abort("validate_SeaSondeRAPM_BearingResolution: BearingResolution must be a numeric value.")
  }
  return(TRUE)
}

#' Validate Smoothing Attribute for a SeaSondeRAPM Object
#'
#' This function validates if the provided Smoothing is a numeric value.
#'
#' @param smoothing The numeric value to be validated.
#' @return Returns TRUE if the validation passes.
#'
validate_SeaSondeRAPM_Smoothing <- function(smoothing) {
  # Ensure that Smoothing is numeric
  if (!is.numeric(smoothing)) {
    seasonder_logAndMessage("validate_SeaSondeRAPM_Smoothing: Smoothing must be a numeric value.", "fatal")
    rlang::abort("validate_SeaSondeRAPM_Smoothing: Smoothing must be a numeric value.")
  }
  return(TRUE)
}

#' Validate CommentLine Attribute for a SeaSondeRAPM Object
#'
#' This function validates if the provided CommentLine is a character string.
#'
#' @param comment The character string to be validated.
#' @return Returns TRUE if the validation passes.
#'
validate_SeaSondeRAPM_CommentLine <- function(comment) {
  # Check if CommentLine is a character string
  if (!is.character(comment)) {
    seasonder_logAndMessage("validate_SeaSondeRAPM_CommentLine: CommentLine must be a character string.", "fatal")
    rlang::abort("validate_SeaSondeRAPM_CommentLine: CommentLine must be a character string.")
  }
  return(TRUE)
}

#' Validate FileID Attribute for a SeaSondeRAPM Object
#'
#' This function validates if the provided FileID is a unique character string.
#'
#' @param id The unique character string to be validated.
#' @return Returns TRUE if the validation passes.
#'
validate_SeaSondeRAPM_FileID <- function(id) {
  # Check if FileID is a character string
  if (!is.character(id)) {
    seasonder_logAndMessage("validate_SeaSondeRAPM_FileID: FileID must be a unique character string.", "fatal")
    rlang::abort("validate_SeaSondeRAPM_FileID: FileID must be a unique character string.")
  }
  return(TRUE)
}

#' Validate PhaseCorrections Attribute for a SeaSondeRAPM Object
#'
#' This function validates if the provided PhaseCorrections attribute is a numeric
#' vector of length 2.
#'
#' @param corrections The numeric vector to be validated.
#' @return Returns TRUE if the validation passes.
#'
validate_SeaSondeRAPM_PhaseCorrections <- function(corrections) {
  # Check if PhaseCorrections is numeric and has exactly 2 elements
  if (!is.numeric(corrections) | length(corrections) != 2) {
    msg <- glue::glue("validate_SeaSondeRAPM_PhaseCorrections: PhaseCorrections must be a numeric vector of length 2. Current length is {length(corrections)}")
    seasonder_logAndMessage(msg, "fatal")
    rlang::abort(msg)
  }
  return(TRUE)
}


#### Getters and Setters ####

#' Get the version value from a SeaSondeRAPM object
#'
#' @param seasonder_obj A SeaSondeRAPM object.
#' @return The version value.
#' @export
#' @examples
#' # Create a default SeaSondeRAPM object
#' obj <- seasonder_createSeaSondeRAPM()
#' # Retrieve version via the generic function
#' version <- seasonder_getVersion(obj)
#' print(version)
seasonder_getVersion.SeaSondeRAPM <- function(seasonder_obj) {
  # Retrieve the "version" attribute from the object
  attr(seasonder_obj, "version", exact = TRUE)
}

#' Getter for quality_matrix
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#'
#' @return The quality_matrix attribute from the object.
#'
#' @export
#' @examples
#' # Create a default SeaSondeRAPM object
#' obj <- seasonder_createSeaSondeRAPM()
#' quality_matrix <- seasonder_getSeaSondeRAPM_quality_matrix(obj)
seasonder_getSeaSondeRAPM_quality_matrix <- function(seasonde_apm_obj) {
  # Return the quality_matrix attribute from the object
  return(attributes(seasonde_apm_obj)$quality_matrix)
}

#' Setter for quality_matrix
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#' @param new_value new value
#'
#' @return The modified SeaSondeRAPM object with updated quality_matrix.
#'
#' @export
#' @examples
#' # Create a default SeaSondeRAPM object
#' obj <- seasonder_createSeaSondeRAPM()
#' # Retrieve the existing quality_matrix
#' new_quality_matrix <- attributes(obj)$quality_matrix
#' # Update quality_matrix in the object
#' obj <- seasonder_setSeaSondeRAPM_quality_matrix(obj, new_quality_matrix)
seasonder_setSeaSondeRAPM_quality_matrix <- function(seasonde_apm_obj, new_value) {
  # Validate the new quality_matrix value against the object
  validate_SeaSondeRAPM_quality_matrix(new_value, seasonde_apm_obj)
  modified_obj <- seasonde_apm_obj

  # Ensure that the new quality_matrix has the same row and column names as the existing object
  colnames(new_value) <- colnames(seasonde_apm_obj)
  rownames(new_value) <- rownames(seasonde_apm_obj)

  # Update the quality_matrix attribute in the object
  attributes(modified_obj)$quality_matrix <- new_value
  return(modified_obj)
}

#' Getter for BEAR
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#'
#' @return The BEAR attribute (bearing values) from the object.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_getSeaSondeRAPM_BEAR
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' bear <- seasonder_getSeaSondeRAPM_BEAR(apm_obj)
#' print(bear)
seasonder_getSeaSondeRAPM_BEAR <- function(seasonde_apm_obj) {
  # Return the BEAR attribute (bearing values) from the object
  return(attributes(seasonde_apm_obj)$BEAR)
}

#' Setter for BEAR
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#' @param new_value new value
#'
#' @return The modified SeaSondeRAPM object with updated BEAR.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_setSeaSondeRAPM_BEAR
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' new_bear <- attributes(apm_obj)$BEAR
#' apm_obj <- seasonder_setSeaSondeRAPM_BEAR(apm_obj, new_bear)
#' print(attributes(apm_obj)$BEAR)
seasonder_setSeaSondeRAPM_BEAR <- function(seasonde_apm_obj, new_value) {
  # Validate the new BEAR value
  validate_SeaSondeRAPM_BEAR(new_value, seasonde_apm_obj)
  modified_obj <- seasonde_apm_obj
  # Update the BEAR attribute with the new value
  attributes(modified_obj)$BEAR <- new_value
  return(modified_obj)
}

#' Getter for PhaseCorrections
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#'
#' @return The PhaseCorrections attribute from the object.
#'
#' @export
#' @examples
#' # Create a default SeaSondeRAPM object
#' obj <- seasonder_createSeaSondeRAPM()
#' phase_corrections <- seasonder_getSeaSondeRAPM_PhaseCorrections(obj)
seasonder_getSeaSondeRAPM_PhaseCorrections <- function(seasonde_apm_obj) {
  # Return the PhaseCorrections attribute from the object
  return(attributes(seasonde_apm_obj)$PhaseCorrections)
}

#' Setter for PhaseCorrections
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#' @param new_value new value
#'
#' @return The modified SeaSondeRAPM object with updated PhaseCorrections.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_setSeaSondeRAPM_PhaseCorrections
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' new_phase_corrections <- attributes(apm_obj)$PhaseCorrections
#' apm_obj <- seasonder_setSeaSondeRAPM_PhaseCorrections(apm_obj, new_phase_corrections)
#' print(attributes(apm_obj)$PhaseCorrections)
seasonder_setSeaSondeRAPM_PhaseCorrections <- function(seasonde_apm_obj, new_value) {
  # Validate the new PhaseCorrections value
  validate_SeaSondeRAPM_PhaseCorrections(new_value)
  modified_obj <- seasonde_apm_obj
  # Update the PhaseCorrections attribute with the new value
  attributes(modified_obj)$PhaseCorrections <- new_value
  return(modified_obj)
}

#' Getter for Type
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#'
#' @return The Type attribute from the object.
#'
#' @export
#' @examples
#' # Create a default SeaSondeRAPM object
#' obj <- seasonder_createSeaSondeRAPM()
#' type <- seasonder_getSeaSondeRAPM_Type(obj)
seasonder_getSeaSondeRAPM_Type <- function(seasonde_apm_obj) {
  # Return the Type attribute from the object
  return(attributes(seasonde_apm_obj)$Type)
}

#' Setter for Type
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#' @param new_value new value
#'
#' @return The modified SeaSondeRAPM object with updated Type.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_setSeaSondeRAPM_Type
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' new_type <- attributes(apm_obj)$Type
#' apm_obj <- seasonder_setSeaSondeRAPM_Type(apm_obj, new_type)
#' print(attributes(apm_obj)$Type)
seasonder_setSeaSondeRAPM_Type <- function(seasonde_apm_obj, new_value) {
  # Validate the new Type value
  validate_SeaSondeRAPM_Type(new_value)
  modified_obj <- seasonde_apm_obj
  # Update the Type attribute with the new value
  attributes(modified_obj)$Type <- new_value
  return(modified_obj)
}

#' Getter for Creator
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#'
#' @return The Creator attribute from the object.
#'
#' @export
#' @examples
#' # Create a default SeaSondeRAPM object
#' obj <- seasonder_createSeaSondeRAPM()
#' creator <- seasonder_getSeaSondeRAPM_Creator(obj)
seasonder_getSeaSondeRAPM_Creator <- function(seasonde_apm_obj) {
  # Return the Creator attribute from the object
  return(attributes(seasonde_apm_obj)$Creator)
}

#' Setter for Creator
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#' @param new_value new value
#'
#' @return The modified SeaSondeRAPM object with updated Creator.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_setSeaSondeRAPM_Creator
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' new_creator <- attributes(apm_obj)$Creator
#' apm_obj <- seasonder_setSeaSondeRAPM_Creator(apm_obj, new_creator)
#' print(attributes(apm_obj)$Creator)
seasonder_setSeaSondeRAPM_Creator <- function(seasonde_apm_obj, new_value) {
  # Validate the new Creator value
  validate_SeaSondeRAPM_Creator(new_value)
  modified_obj <- seasonde_apm_obj
  # Update the Creator attribute with the new value
  attributes(modified_obj)$Creator <- new_value
  return(modified_obj)
}

#' Getter for SiteName
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#'
#' @return The SiteName attribute from the object.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_getSeaSondeRAPM_SiteName
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' site_name <- seasonder_getSeaSondeRAPM_SiteName(apm_obj)
#' print(site_name)
seasonder_getSeaSondeRAPM_SiteName <- function(seasonde_apm_obj) {
  # Return the SiteName attribute from the object
  return(attributes(seasonde_apm_obj)$SiteName)
}

#' Setter for SiteName
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#' @param new_value new value
#'
#' @return The modified SeaSondeRAPM object with updated SiteName.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_setSeaSondeRAPM_SiteName
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' new_site_name <- attributes(apm_obj)$SiteName
#' apm_obj <- seasonder_setSeaSondeRAPM_SiteName(apm_obj, new_site_name)
#' print(attributes(apm_obj)$SiteName)
seasonder_setSeaSondeRAPM_SiteName <- function(seasonde_apm_obj, new_value) {
  # Validate the new SiteName value
  validate_SeaSondeRAPM_SiteName(new_value)
  modified_obj <- seasonde_apm_obj
  # Update the SiteName attribute with the new value
  attributes(modified_obj)$SiteName <- new_value
  return(modified_obj)
}

#' Getter for SiteOrigin
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#'
#' @return The SiteOrigin attribute from the object.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_getSeaSondeRAPM_SiteOrigin
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' site_origin <- seasonder_getSeaSondeRAPM_SiteOrigin(apm_obj)
#' print(site_origin)
seasonder_getSeaSondeRAPM_SiteOrigin <- function(seasonde_apm_obj) {
  # Return the SiteOrigin attribute from the object
  return(attributes(seasonde_apm_obj)$SiteOrigin)
}

#' Setter for SiteOrigin
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#' @param new_value new value
#'
#' @return The modified SeaSondeRAPM object with updated SiteOrigin.
#'
#' @export
#' @examples
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' new_site_origin <- attributes(apm_obj)$SiteOrigin
#' apm_obj <- seasonder_setSeaSondeRAPM_SiteOrigin(apm_obj, new_site_origin)
#' print(attributes(apm_obj)$SiteOrigin)
seasonder_setSeaSondeRAPM_SiteOrigin <- function(seasonde_apm_obj, new_value) {
  # Validate the new SiteOrigin value
  validate_SeaSondeRAPM_SiteOrigin(new_value)
  modified_obj <- seasonde_apm_obj
  # Assign names to the new SiteOrigin values for clarity
  names(new_value) <- c("Latitude", "Longitude")
  # Update the SiteOrigin attribute with the new value
  attributes(modified_obj)$SiteOrigin <- new_value
  return(modified_obj)
}

#' Getter for FileName
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#'
#' @return The FileName attribute from the object.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_getSeaSondeRAPM_FileName
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' file_name <- seasonder_getSeaSondeRAPM_FileName(apm_obj)
#' print(file_name)
seasonder_getSeaSondeRAPM_FileName <- function(seasonde_apm_obj) {
  # Return the FileName attribute from the object
  return(attributes(seasonde_apm_obj)$FileName)
}

#' Setter for FileName
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#' @param new_value new value
#'
#' @return The modified SeaSondeRAPM object with updated FileName.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_setSeaSondeRAPM_FileName
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' new_file_name <- "new.txt"
#' apm_obj <- seasonder_setSeaSondeRAPM_FileName(apm_obj, new_file_name)
#' print(attributes(apm_obj)$FileName)
seasonder_setSeaSondeRAPM_FileName <- function(seasonde_apm_obj, new_value) {
  # Validate the new FileName value
  validate_SeaSondeRAPM_FileName(new_value)
  modified_obj <- seasonde_apm_obj
  # Update the FileName attribute with the new value
  attributes(modified_obj)$FileName <- new_value
  return(modified_obj)
}

#' Getter for CreateTimeStamp
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#'
#' @return The CreateTimeStamp attribute from the object.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_getSeaSondeRAPM_CreateTimeStamp
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' create_time_stamp <- seasonder_getSeaSondeRAPM_CreateTimeStamp(apm_obj)
#' print(create_time_stamp)
seasonder_getSeaSondeRAPM_CreateTimeStamp <- function(seasonde_apm_obj) {
  # Return the CreateTimeStamp attribute from the object
  return(attributes(seasonde_apm_obj)$CreateTimeStamp)
}

#' Setter for CreateTimeStamp
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#' @param new_value new value
#'
#' @return The modified SeaSondeRAPM object with updated CreateTimeStamp.
#'
#' @export
## Example to set a new CreateTimeStamp value
#' @examples
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' new_create_time_stamp <- as.POSIXct("2000-01-01 00:00:00", tz = "UTC")
#' apm_obj <- seasonder_setSeaSondeRAPM_CreateTimeStamp(apm_obj, new_create_time_stamp)
#' print(attributes(apm_obj)$CreateTimeStamp)
seasonder_setSeaSondeRAPM_CreateTimeStamp <- function(seasonde_apm_obj, new_value) {
  # Validate the new CreateTimeStamp value
  validate_SeaSondeRAPM_CreateTimeStamp(new_value)
  modified_obj <- seasonde_apm_obj
  # Update the CreateTimeStamp attribute with the new value
  attributes(modified_obj)$CreateTimeStamp <- new_value
  return(modified_obj)
}

#' Getter for ProcessingSteps
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#'
#' @return The ProcessingSteps attribute from the object.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_getSeaSondeRAPM_ProcessingSteps
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' processing_steps <- seasonder_getSeaSondeRAPM_ProcessingSteps(apm_obj)
#' print(processing_steps)
seasonder_getSeaSondeRAPM_ProcessingSteps <- function(seasonde_apm_obj) {
  # Return the ProcessingSteps attribute from the object
  return(attributes(seasonde_apm_obj)$ProcessingSteps)
}

#' Setter for ProcessingSteps
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#' @param new_value new value
#' @param append Append the new step to existing steps if TRUE; otherwise, replace previous steps.
#'
#' @return The modified SeaSondeRAPM object with updated ProcessingSteps.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_setSeaSondeRAPM_ProcessingSteps
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' new_processing_steps <- "step1"
#' apm_obj <- seasonder_setSeaSondeRAPM_ProcessingSteps(apm_obj, new_processing_steps)
#' print(attributes(apm_obj)$ProcessingSteps)
seasonder_setSeaSondeRAPM_ProcessingSteps <- function(seasonde_apm_obj, new_value, append = TRUE) {
  # If appending, combine the existing processing steps with the new step
  if (append) {
    steps <- seasonder_getSeaSondeRAPM_ProcessingSteps(seasonde_apm_obj)
    new_value <- c(steps, new_value)
  }
  # Validate the new ProcessingSteps value
  validate_SeaSondeRAPM_ProcessingSteps(new_value)
  modified_obj <- seasonde_apm_obj

  # Update the ProcessingSteps attribute with the new value
  attributes(modified_obj)$ProcessingSteps <- new_value
  return(modified_obj)
}

#' Getter for AmplitudeFactors
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#'
#' @return The AmplitudeFactors attribute from the object.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_getSeaSondeRAPM_AmplitudeFactors
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' amplitude_factors <- seasonder_getSeaSondeRAPM_AmplitudeFactors(apm_obj)
#' print(amplitude_factors)
seasonder_getSeaSondeRAPM_AmplitudeFactors <- function(seasonde_apm_obj) {
  # Return the AmplitudeFactors attribute from the object
  return(attributes(seasonde_apm_obj)$AmplitudeFactors)
}

#' Setter for AmplitudeFactors
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#' @param new_value new value
#'
#' @return The modified SeaSondeRAPM object with updated AmplitudeFactors.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_setSeaSondeRAPM_AmplitudeFactors
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' new_factors <- c(1, 2)
#' apm_obj <- seasonder_setSeaSondeRAPM_AmplitudeFactors(apm_obj, new_factors)
#' print(attributes(apm_obj)$AmplitudeFactors)
seasonder_setSeaSondeRAPM_AmplitudeFactors <- function(seasonde_apm_obj, new_value) {
  # Validate the new AmplitudeFactors value
  validate_SeaSondeRAPM_AmplitudeFactors(new_value)
  modified_obj <- seasonde_apm_obj
  # Update the AmplitudeFactors attribute with the new value
  attributes(modified_obj)$AmplitudeFactors <- new_value
  return(modified_obj)
}

#' Getter for AntennaBearing
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#'
#' @return The AntennaBearing attribute from the object.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_getSeaSondeRAPM_AntennaBearing
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' antenna_bearing <- seasonder_getSeaSondeRAPM_AntennaBearing(apm_obj)
#' print(antenna_bearing)
seasonder_getSeaSondeRAPM_AntennaBearing <- function(seasonde_apm_obj) {
  # Return the AntennaBearing attribute from the object
  return(attributes(seasonde_apm_obj)$AntennaBearing)
}

#' Setter for AntennaBearing
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#' @param new_value new value
#'
#' @return The modified SeaSondeRAPM object with updated AntennaBearing.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_setSeaSondeRAPM_AntennaBearing
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' new_bearing <- 45
#' apm_obj <- seasonder_setSeaSondeRAPM_AntennaBearing(apm_obj, new_bearing)
#' print(attributes(apm_obj)$AntennaBearing)
seasonder_setSeaSondeRAPM_AntennaBearing <- function(seasonde_apm_obj, new_value) {
  # Validate the new AntennaBearing value
  validate_SeaSondeRAPM_AntennaBearing(new_value)
  modified_obj <- seasonde_apm_obj
  # Update the AntennaBearing attribute with the new value
  attributes(modified_obj)$AntennaBearing <- new_value
  return(modified_obj)
}

#' Getter for StationCode
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#'
#' @return The StationCode attribute from the object.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_getSeaSondeRAPM_StationCode
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' station_code <- seasonder_getSeaSondeRAPM_StationCode(apm_obj)
#' print(station_code)
seasonder_getSeaSondeRAPM_StationCode <- function(seasonde_apm_obj) {
  # Return the StationCode attribute from the object
  return(attributes(seasonde_apm_obj)$StationCode)
}

#' Setter for StationCode
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#' @param new_value new value
#'
#' @return The modified SeaSondeRAPM object with updated StationCode.
#'
#' @export
 #' @examples
 #' # Minimal example for seasonder_setSeaSondeRAPM_StationCode
 #' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
 #' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
 #' new_station_code <- attr(apm_obj, "StationCode")
 #' apm_obj <- seasonder_setSeaSondeRAPM_StationCode(apm_obj, new_station_code)
 #' print(attributes(apm_obj)$StationCode)
seasonder_setSeaSondeRAPM_StationCode <- function(seasonde_apm_obj, new_value) {
  # Validate the new StationCode value
  validate_SeaSondeRAPM_StationCode(new_value)
  modified_obj <- seasonde_apm_obj
  # Update the StationCode attribute with the new value
  attributes(modified_obj)$StationCode <- new_value
  return(modified_obj)
}

#' Getter for BearingResolution
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#'
#' @return The BearingResolution attribute from the object.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_getSeaSondeRAPM_BearingResolution
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' bearing_resolution <- seasonder_getSeaSondeRAPM_BearingResolution(apm_obj)
#' print(bearing_resolution)
seasonder_getSeaSondeRAPM_BearingResolution <- function(seasonde_apm_obj) {
  # Return the BearingResolution attribute from the object
  return(attributes(seasonde_apm_obj)$BearingResolution)
}

#' Setter for BearingResolution
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#' @param new_value new value
#'
#' @return The modified SeaSondeRAPM object with updated BearingResolution.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_setSeaSondeRAPM_BearingResolution
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' new_bearing_resolution <- 1.0
#' apm_obj <- seasonder_setSeaSondeRAPM_BearingResolution(apm_obj, new_bearing_resolution)
#' print(attributes(apm_obj)$BearingResolution)
seasonder_setSeaSondeRAPM_BearingResolution <- function(seasonde_apm_obj, new_value) {
  # Validate the new BearingResolution value
  validate_SeaSondeRAPM_BearingResolution(new_value)
  modified_obj <- seasonde_apm_obj
  # Update the BearingResolution attribute with the new value
  attributes(modified_obj)$BearingResolution <- new_value
  return(modified_obj)
}

#' Getter for Smoothing
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#'
#' @return The Smoothing attribute from the object.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_getSeaSondeRAPM_Smoothing
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' smoothing <- seasonder_getSeaSondeRAPM_Smoothing(apm_obj)
#' print(smoothing)
seasonder_getSeaSondeRAPM_Smoothing <- function(seasonde_apm_obj) {
  # Return the Smoothing attribute from the object
  return(attributes(seasonde_apm_obj)$Smoothing)
}

#' Setter for Smoothing
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#' @param new_value new value
#'
#' @return The modified SeaSondeRAPM object with updated Smoothing.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_setSeaSondeRAPM_Smoothing
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' new_smoothing <- 3
#' apm_obj <- seasonder_setSeaSondeRAPM_Smoothing(apm_obj, new_smoothing)
#' print(attributes(apm_obj)$Smoothing)
seasonder_setSeaSondeRAPM_Smoothing <- function(seasonde_apm_obj, new_value) {
  # Validate the new Smoothing value
  validate_SeaSondeRAPM_Smoothing(new_value)
  modified_obj <- seasonde_apm_obj
  # Update the Smoothing attribute with the new value
  attributes(modified_obj)$Smoothing <- new_value
  return(modified_obj)
}

#' Getter for CommentLine
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#'
#' @return The CommentLine attribute from the object.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_getSeaSondeRAPM_CommentLine
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' comment_line <- seasonder_getSeaSondeRAPM_CommentLine(apm_obj)
#' print(comment_line)
seasonder_getSeaSondeRAPM_CommentLine <- function(seasonde_apm_obj) {
  # Return the CommentLine attribute from the object
  return(attributes(seasonde_apm_obj)$CommentLine)
}

#' Setter for CommentLine
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#' @param new_value new value
#'
#' @return The modified SeaSondeRAPM object with updated CommentLine.
#'
#' @export
#' @examples
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' new_comment_line <- "Test comment"
#' apm_obj <- seasonder_setSeaSondeRAPM_CommentLine(apm_obj, new_comment_line)
#' print(attributes(apm_obj)$CommentLine)
seasonder_setSeaSondeRAPM_CommentLine <- function(seasonde_apm_obj, new_value) {
  # Validate the new CommentLine value
  validate_SeaSondeRAPM_CommentLine(new_value)
  modified_obj <- seasonde_apm_obj
  # Update the CommentLine attribute with the new value
  attributes(modified_obj)$CommentLine <- new_value
  return(modified_obj)
}

#' Setter for FileID
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#' @param new_value new value
#'
#' @return The modified SeaSondeRAPM object with updated FileID.
#'
#' @export
#' @examples
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' new_file_id <- attributes(apm_obj)$FileID
#' apm_obj <- seasonder_setSeaSondeRAPM_FileID(apm_obj, new_file_id)
#' print(attributes(apm_obj)$FileID)
seasonder_setSeaSondeRAPM_FileID <- function(seasonde_apm_obj, new_value) {
  # Validate the new FileID value
  validate_SeaSondeRAPM_FileID(new_value)
  modified_obj <- seasonde_apm_obj
  # Update the FileID attribute with the new value
  attributes(modified_obj)$FileID <- new_value
  return(modified_obj)
}

#' Getter for FileID
#'
#' @param seasonde_apm_obj SeaSonderAPM object
#'
#' @return The FileID attribute from the object.
#'
#' @export
#' @examples
#' # Minimal example for seasonder_getSeaSondeRAPM_FileID
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' apm_obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' file_id <- seasonder_getSeaSondeRAPM_FileID(apm_obj)
#' print(file_id)
seasonder_getSeaSondeRAPM_FileID <- function(seasonde_apm_obj) {
  # Return the FileID attribute from the object
  return(attributes(seasonde_apm_obj)$FileID)
}


#### Methods ####

#' Smooth APM Data
#'
#' This function smooths the antenna pattern data for each channel of a SeaSonde RAPM object
#' by applying a moving average with a specified number of points.
#'
#' @param seasonder_apm_object A SeaSonde RAPM object containing raw antenna pattern data.
#' @param smoothing The number of points to use for the moving average smoothing.
#'
#' @return The SeaSonde RAPM object with smoothed antenna pattern data and an updated processing step.
#'
#' @export
#' @examples
#' # Smooth antenna pattern data from a test SeaSondeRAPM object
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' smoothed_obj <- seasonder_smoothAPM(obj, 5)
seasonder_smoothAPM <- function(seasonder_apm_object, smoothing) {
  # Smooth the first antenna channel:
  # - Extract the real part using pracma::Real and apply moving average using slider::slide_mean
  # - Extract the imaginary part using pracma::Imag and apply moving average similarly
  seasonder_apm_object[1,] <- complex(
    real = slider::slide_mean(pracma::Real(seasonder_apm_object[1,]), before = smoothing, na_rm = TRUE),
    imaginary = slider::slide_mean(pracma::Imag(seasonder_apm_object[1,]), before = smoothing, na_rm = TRUE)
  )

  # Smooth the second antenna channel in the same way
  seasonder_apm_object[2,] <- complex(
    real = slider::slide_mean(pracma::Real(seasonder_apm_object[2,]), before = smoothing, na_rm = TRUE),
    imaginary = slider::slide_mean(pracma::Imag(seasonder_apm_object[2,]), before = smoothing, na_rm = TRUE)
  )

  # Update the processing steps attribute with a message indicating the smoothing operation
  seasonder_apm_object %<>% seasonder_setSeaSondeRAPM_ProcessingSteps(SeaSondeRAPM_smoothing_step_text(smoothing))

  # Return the modified SeaSonde RAPM object with smoothed data
  return(seasonder_apm_object)
}

#' Trim APM Data
#'
#' This function trims a specified number of points from the beginning and end of the antenna pattern data.
#'
#' @param seasonder_apm_object A SeaSonde RAPM object containing the antenna pattern data.
#' @param trimming The number of points to trim from each end.
#'
#' @return The SeaSonde RAPM object with trimmed antenna pattern data and updated attributes.
#'
#' @export
#' @examples
#' # Trim loops for a test SeaSondeRAPM object
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' trimmed_obj <- seasonder_trimAPM(obj, 3)
seasonder_trimAPM <- function(seasonder_apm_object, trimming) {

  # Store the current attributes of the APM object
  attrib <- attributes(seasonder_apm_object)

  # Trim the columns: remove the first 'trimming' columns and the last 'trimming' columns
  seasonder_apm_object <- seasonder_apm_object[, -c(1:trimming, (dim(seasonder_apm_object)[2] - trimming + 1):dim(seasonder_apm_object)[2])]

  # Update the dimension attribute to reflect the new size of the matrix
  attrib[["dim"]] <- dim(seasonder_apm_object)

  # Update the column names in the dimnames attribute by removing the trimmed names
  attrib[["dimnames"]][[2]] <- attrib[["dimnames"]][[2]][-c(1:trimming, (length(attrib[["dimnames"]][[2]]) - trimming + 1):length(attrib[["dimnames"]][[2]]))]

  # Update the BEAR attribute by removing the corresponding trimmed bearing values
  new_bear <- attrib[["BEAR"]]
  new_bear <- new_bear[-c(1:trimming, (length(new_bear) - trimming + 1):length(new_bear))]
  attrib[["BEAR"]] <- new_bear

  # Reassign the updated attributes to the modified APM object
  attributes(seasonder_apm_object) <- attrib

  # Log the trimming operation in the processing steps attribute
  seasonder_apm_object %<>% seasonder_setSeaSondeRAPM_ProcessingSteps(SeaSondeRAPM_trimming_step_text(trimming))

  # Return the trimmed SeaSonde RAPM object
  return(seasonder_apm_object)
}

#' Apply Amplitude and Phase Corrections to a SeaSonde RAPM Object
#'
#' This function applies amplitude and phase corrections to each antenna channel
#' of a SeaSonde RAPM object based on the correction factors stored within the object.
#'
#' @param seasonder_apm_object A SeaSonde RAPM object containing raw data and correction factors.
#'
#' @return The SeaSonde RAPM object with amplitude and phase corrections applied to the data.
#'
#' @export
#' @examples
#' # Apply amplitude & phase corrections to a test SeaSondeRAPM object
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' corrected_obj <- seasonder_applyAPMAmplitudeAndPhaseCorrections(obj)
seasonder_applyAPMAmplitudeAndPhaseCorrections <- function(seasonder_apm_object) {
  # Retrieve the amplitude factors from the object
  amplitude_factors <- seasonder_getSeaSondeRAPM_AmplitudeFactors(seasonder_apm_object)
  # Retrieve the phase corrections (in degrees) from the object
  phase_corrections <- seasonder_getSeaSondeRAPM_PhaseCorrections(seasonder_apm_object)

  # Extract individual correction values for clarity
  amplitude1 <- amplitude_factors[1]
  amplitude2 <- amplitude_factors[2]
  phase1 <- phase_corrections[1]
  phase2 <- phase_corrections[2]

  # Apply amplitude and phase correction to the first antenna channel
  seasonder_apm_object[1,] <- seasonder_apm_object[1,] * amplitude1 * exp(1i * phase1 * pi / 180)

  # Apply amplitude and phase correction to the second antenna channel
  seasonder_apm_object[2,] <- seasonder_apm_object[2,] * amplitude2 * exp(1i * phase2 * pi / 180)

  # Update the processing steps attribute with a message detailing the applied corrections
  seasonder_apm_object %<>% seasonder_setSeaSondeRAPM_ProcessingSteps(
    SeaSondeRAPM_amplitude_and_phase_corrections_step_text(amplitude1, amplitude2, phase1, phase2)
  )

  # Return the corrected SeaSonde RAPM object
  return(seasonder_apm_object)
}

#' Extrapolate SeaSondeR APM Matrix
#'
#' This function performs linear extrapolation on the SeaSondeR APM measurement matrix.
#' It adds \code{n} extrapolated columns to both the left and right sides of the matrix.
#'
#' The function retrieves the original bearing vector from the APM object using
#' \code{seasonder_getSeaSondeRAPM_BEAR} and obtains the bearing resolution (attribute
#' "BearingResolution"). If \code{n == 0}, the original matrix is returned unchanged.
#' For \code{n > 0}, new bearings are generated for both sides using the resolution. The
#' left side is extrapolated using the slope computed from the first two columns of the matrix,
#' and the right side is extrapolated using the slope from the last two columns. The new columns
#' are then combined with the original matrix, and the column names and the "BEAR" attribute
#' are updated to reflect the complete set of bearings.
#'
#' @param seasonder_apm_object A matrix containing SeaSondeR APM measurements. Its attributes
#'        include "BEAR" (numeric vector of bearings) and "BearingResolution" (numeric resolution).
#' @param n An integer specifying how many extrapolated columns to add on each side (default is 1).
#' @return A modified matrix with \code{n} extrapolated columns added to both sides. The column names
#'         and the "BEAR" attribute are updated with the new bearings, while the "BearingResolution"
#'         attribute remains unchanged.
#' @examples
#' # Extrapolate loops for a test SeaSondeRAPM object
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' result <- seasonder_extrapolateAPM(obj, n = 1)
#' @export
seasonder_extrapolateAPM <- function(seasonder_apm_object, n = 1) {

  # Retrieve the original BEAR vector and bearing resolution from the input object
  BEAR <- seasonder_getSeaSondeRAPM_BEAR(seasonder_apm_object)
  res <- attr(seasonder_apm_object, "BearingResolution")

  # If no extrapolation is requested (n == 0), return the original object unchanged
  if (n == 0) return(seasonder_apm_object)

  # Generate new bearings for the left and right sides using the bearing resolution
  # left_new: sequence of new bearings to the left of the original (decreasing values)
  # right_new: sequence of new bearings to the right of the original (increasing values)
  left_new <- seq(from = BEAR[1] - n * res, to = BEAR[1] - res, by = res)
  right_new <- seq(from = utils::tail(BEAR, 1) + res, to = utils::tail(BEAR, 1) + n * res, by = res)
  new_BEAR <- c(left_new, BEAR, right_new)

  # Store the original measurement matrix in M
  M <- seasonder_apm_object

  # Extrapolate the left side using linear extrapolation based on the first two columns of M
  # Calculate the slope from the first two columns
  slope_left <- (M[, 2] - M[, 1]) / (BEAR[2] - BEAR[1])
  # For each new left bearing, extrapolate the value from the first column
  left_mat <- sapply(left_new, function(b) M[, 1] + slope_left * (b - BEAR[1]))
  # Ensure that left_mat is a matrix with the correct number of columns
  if (is.null(dim(left_mat))) {
    left_mat <- matrix(left_mat, ncol = length(left_new))
  }

  # Extrapolate the right side using linear extrapolation based on the last two columns of M
  n_orig <- ncol(M)
  slope_right <- (M[, n_orig] - M[, n_orig - 1]) / (BEAR[length(BEAR)] - BEAR[length(BEAR) - 1])
  # For each new right bearing, extrapolate the value from the last column
  right_mat <- sapply(right_new, function(b) M[, n_orig] + slope_right * (b - BEAR[length(BEAR)]))
  if (is.null(dim(right_mat))) {
    right_mat <- matrix(right_mat, ncol = length(right_new))
  }

  # Combine the left extrapolated columns, the original matrix, and the right extrapolated columns
  new_M <- cbind(left_mat, M, right_mat)
  old_attr <- attributes(seasonder_apm_object)
  attributes(new_M) <- c(attributes(new_M), old_attr[!names(old_attr) %in% names(attributes(new_M))])
  # Update the column names to match the new bearings and update the BEAR attribute
  colnames(new_M) <- as.character(new_BEAR)
  attr(new_M, "BEAR") <- new_BEAR

  quality_m <- attr(seasonder_apm_object, "quality_matrix", exact = TRUE)
  new_q <- cbind(matrix(rep(-1+0i, n*3), ncol = n),quality_m,  matrix(rep(-1+0i, n*3), ncol = n))
  colnames(new_q) <- as.character(new_BEAR)
  attr(new_M,"quality_matrix") <- new_q
  # Return the updated measurement matrix with extrapolated columns
  return(new_M)
}

#### File Reading ####

#' Read a Row from a Matrix Represented as Text Lines
#'
#' This function reads a row of numbers from a matrix that is represented
#' as an array of text lines. It is used to facilitate reading data from
#' SeaSonde APM files.
#'
#' @param lines The array of lines, each representing part of the row.
#' @param start The start index of the lines to read from.
#' @param number_of_lines_to_read The number of lines to read to form the row.
#' @return A numeric vector containing the row values.
#'
read_matrix_row <- function(lines, start, number_of_lines_to_read) {
  # Concatenate the specified lines into a single string with spaces between them
  row_str <- paste(lines[start:(start + number_of_lines_to_read - 1)], collapse = " ")
  # Split the string by spaces, convert to numeric, and return the resulting vector
  row_str <- as.numeric(unlist(stringr::str_split(stringr::str_squish(row_str), " ")))
}

#' Parse a Metadata Line from a SeaSonde APM File
#'
#' This function takes a single line from a SeaSonde APM file and parses it into
#' a named attribute and its corresponding value.
#'
#' @param line The line of text to parse.
#' @return A list containing the attribute name and its value.
#'
parse_metadata_line <- function(line) {
  # Split the line into components using "!" as the delimiter
  components <- unlist(strsplit(line, "!"))
  # Trim and extract the value part from the first component
  value_str <- stringr::str_squish(components[1])
  # Trim and extract the attribute descriptor from the second component
  attribute_str <- stringr::str_squish(components[2])

  # Map the attribute descriptor to the corresponding attribute name using switch
  attribute_name <- switch(attribute_str,
                           "Amplitude Factors" = "AmplitudeFactors",
                           "Antenna Bearing" = "AntennaBearing",
                           "Site Code" = "StationCode",
                           "Site Lat Lon" = "SiteOrigin",
                           "Degree Resolution" = "BearingResolution",
                           "Degree Smoothing" = "Smoothing",
                           "Date Year Mo Day Hr Mn Sec" = "CreateTimeStamp",
                           "UUID" = "FileID",
                           "Phase Corrections" = "PhaseCorrections",
                           "Unknown")
  # Convert the value string to the appropriate type based on the attribute name
  value <- switch(attribute_name,
                  "AmplitudeFactors" = as.numeric(unlist(strsplit(value_str, " "))),
                  "AntennaBearing" = as.numeric(value_str),
                  "StationCode" = value_str,
                  "SiteOrigin" = as.numeric(unlist(strsplit(value_str, " "))),
                  "BearingResolution" = as.numeric(value_str),
                  "Smoothing" = as.numeric(value_str),
                  "CreateTimeStamp" = as.POSIXct(value_str, format = "%Y %m %d  %H %M %S"),
                  "FileID" = value_str,
                  "PhaseCorrections" = as.numeric(unlist(strsplit(value_str, " "))),
                  value_str)

  # Return a list containing the parsed attribute name and value
  return(list(attribute_name = attribute_name, value = value))
}

#' Read and Parse a SeaSonde APM File
#'
#' This function reads a SeaSonde APM file and returns a SeaSondeRAPM object containing
#' the parsed data.
#'
#' @param file_path The path to the SeaSonde APM file to read.
#' @param override_antenna_bearing If not NULL, overrides the Antenna Bearing data in the file.
#' @param override_phase_corrections If not NULL, overrides the phase corrections in the file.
#' @param override_amplitude_factors If not NULL, overrides the amplitude factors in the file.
#' @param override_SiteOrigin If not NULL, overrides the SiteOrigin attribute.
#' @param ... Additional arguments passed to the object creation function.
#'
#' @return A SeaSondeRAPM object containing the parsed data.
#'
#' @export
#' @importFrom magrittr %<>%
#' @seealso \code{\link{seasonder_createSeaSondeRAPM}}
#' @seealso \code{\link{seasonder_validateAttributesSeaSondeRAPM}}
#' @examples
#' # Read a test SeaSondeRAPM object from sample file
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' obj <- seasonder_readSeaSondeRAPMFile(apm_file)
seasonder_readSeaSondeRAPMFile <- function(file_path, override_antenna_bearing = NULL, override_phase_corrections = NULL, override_amplitude_factors = NULL, override_SiteOrigin = NULL, ...) {

  # Read all lines from the specified file
  lines <- readLines(file_path)
  # The first line contains the number of angles (bearings)
  num_angles <- as.integer(lines[1])

  # Determine the number of lines needed to represent one row of data (assuming 7 values per line)
  number_of_lines_to_read <- ceiling(num_angles / 7)
  # Define the starting line indices for various sections of the file
  BEAR_start <- 2
  A13R_start  <- BEAR_start + number_of_lines_to_read
  A13RQ_start  <- A13R_start + number_of_lines_to_read
  A13I_start  <- A13RQ_start + number_of_lines_to_read
  A13IQ_start  <- A13I_start + number_of_lines_to_read
  A23R_start  <- A13IQ_start + number_of_lines_to_read
  A23RQ_start  <- A23R_start + number_of_lines_to_read
  A23I_start  <- A23RQ_start + number_of_lines_to_read
  A23IQ_start  <- A23I_start + number_of_lines_to_read

  # Read the BEAR values (bearing angles) from the file
  BEAR <- read_matrix_row(lines, BEAR_start, number_of_lines_to_read)
  # Read the real and imaginary parts for the first antenna channel (A13)
  A13R <- read_matrix_row(lines, A13R_start, number_of_lines_to_read)
  A13RQ <- read_matrix_row(lines, A13RQ_start, number_of_lines_to_read)
  A13I <- read_matrix_row(lines, A13I_start, number_of_lines_to_read)
  A13IQ <- read_matrix_row(lines, A13IQ_start, number_of_lines_to_read)
  # Read the real and imaginary parts for the second antenna channel (A23)
  A23R <- read_matrix_row(lines, A23R_start, number_of_lines_to_read)
  A23RQ <- read_matrix_row(lines, A23RQ_start, number_of_lines_to_read)
  A23I <- read_matrix_row(lines, A23I_start, number_of_lines_to_read)
  A23IQ <- read_matrix_row(lines, A23IQ_start, number_of_lines_to_read)

  # Concatenate the lines representing the angles and split them to obtain numeric angle values
  angle_str <- paste(lines[2:(2 + number_of_lines_to_read - 1)], collapse = " ")
  angles <- as.numeric(unlist(stringr::str_split(stringr::str_squish(angle_str), " ")))

  # Create the calibration matrix using the real and imaginary parts of A13 and A23
  # A33 is assumed to be a unity gain channel (real = 1, imaginary = 0)
  A13 <- complex(real = A13R, imaginary = A13I)
  A23 <- complex(real = A23R, imaginary = A23I)
  A33 <- complex(real = rep(1, length(A13R)), imaginary = rep(0, length(A13I)))
  # Construct the calibration matrix with 3 rows (A13, A23, A33)
  calibration_matrix <- matrix(c(A13, A23, A33), nrow = 3, byrow = TRUE)

  # Create the quality matrix using the quality data (A13Q, A23Q) and zeros for A33Q
  A13Q <- complex(real = A13RQ, imaginary = A13IQ)
  A23Q <- complex(real = A23RQ, imaginary = A23IQ)
  A33Q <- complex(real = rep(0, length(A13R)), imaginary = rep(0, length(A13I)))
  quality_matrix <- matrix(c(A13Q, A23Q, A33Q), nrow = 3, byrow = TRUE)

  # Create the SeaSondeRAPM object using the calibration and quality matrices, along with BEAR and additional arguments
  out <- seasonder_createSeaSondeRAPM(calibration_matrix = calibration_matrix, quality_matrix = quality_matrix, BEAR = BEAR, ...)

  # Update the quality_matrix attribute explicitly
  out <- seasonder_setSeaSondeRAPM_quality_matrix(out, new_value = quality_matrix)

  # Determine the starting line for metadata (after the data rows)
  metadata_start <- A23IQ_start + number_of_lines_to_read
  metadata_lines <- lines[(metadata_start):length(lines)]
  comment_lines <- character(0)
  # Parse each metadata line into a list of attribute-value pairs
  metadata_list <- lapply(metadata_lines, parse_metadata_line)

  # Iterate over the parsed metadata to update the object's attributes
  for (meta in metadata_list) {
    attribute_name <- meta$attribute_name
    value <- meta$value

    # If the attribute is unknown, collect it as a comment
    if (attribute_name == "Unknown") {
      comment_lines <- c(comment_lines, value)
    } else {
      # Dynamically retrieve the setter function for the attribute and update the object
      setter_fun <- get(glue::glue("seasonder_setSeaSondeRAPM_{attribute_name}"))
      out <- setter_fun(out, new_value = value)
    }
  }

  # If there are any comment lines, concatenate them and set the CommentLine attribute
  if (length(comment_lines) > 0) {
    comment_str <- paste(comment_lines, collapse = "; ")
    setter_fun <- get("seasonder_setSeaSondeRAPM_CommentLine")
    out <- setter_fun(out, new_value = comment_str)
  }

  # Set the FileName attribute using the base name of the file path
  out <- seasonder_setSeaSondeRAPM_FileName(out, basename(file_path))

  # Log the creation step in the processing steps attribute
  out %<>% seasonder_setSeaSondeRAPM_ProcessingSteps(SeaSondeRAPM_creation_step_text(file_path))

  # Override the AntennaBearing attribute if an override value is provided
  if (!is.null(override_antenna_bearing)) {
    out %<>% seasonder_setSeaSondeRAPM_AntennaBearing(override_antenna_bearing)
    out %<>% seasonder_setSeaSondeRAPM_ProcessingSteps(SeaSondeRAPM_antenna_bearing_override_step_text(override_antenna_bearing))
  }

  # Override the PhaseCorrections attribute if an override value is provided
  if (!is.null(override_phase_corrections)) {
    # If the override is a file path, read the phase corrections from the file
    if (is.character(override_phase_corrections) && file.exists(override_phase_corrections)) {
      override_phase_corrections <- seasonder_readPhaseFile(override_phase_corrections)
    }
    # If the override is numeric and of length 2, apply it
    if (is.numeric(override_phase_corrections) && length(override_phase_corrections) == 2) {
      out %<>% seasonder_setSeaSondeRAPM_PhaseCorrections(override_phase_corrections)
      out %<>% seasonder_setSeaSondeRAPM_ProcessingSteps(SeaSondeRAPM_phase_correction_override_step_text(override_phase_corrections))
    } else {
      seasonder_logAndMessage("override_phase_corrections parameters is not a valid file path with valid phase correction values, or a numeric vector of length 2", log_level = "error", calling_function = "seasonder_readSeaSondeRAPMFile")
    }
  }

  # Override the AmplitudeFactors attribute if an override value is provided
  if (!is.null(override_amplitude_factors)) {
    if (is.numeric(override_amplitude_factors) && length(override_amplitude_factors) == 2) {
      out %<>% seasonder_setSeaSondeRAPM_AmplitudeFactors(override_amplitude_factors)
      out %<>% seasonder_setSeaSondeRAPM_ProcessingSteps(SeaSondeRAPM_amplitude_factors_override_step_text(override_amplitude_factors))
    }
  }

  # Override the SiteOrigin attribute if an override value is provided
  if (!is.null(override_SiteOrigin)) {
    out %<>% seasonder_setSeaSondeRAPM_SiteOrigin(override_SiteOrigin)
    out %<>% seasonder_setSeaSondeRAPM_ProcessingSteps(SeaSondeRAPM_SiteOrigin_override_step_text(override_SiteOrigin))
  }

  # Validate all attributes of the final SeaSondeRAPM object
  seasonder_validateAttributesSeaSondeRAPM(out)

  # Return the fully parsed and validated SeaSondeRAPM object
  return(out)
}

#' Read Phase Correction File
#'
#' This function reads a phase correction file and extracts phase correction values.
#'
#' @param file_path The path to the phase correction file.
#'
#' @return A numeric vector with two elements: phase corrections for the two channels.
#'
#' @export
#' @examples
#' # Read phase corrections from sample file
#' phase_file <- system.file("css_data/Phases.txt", package = "SeaSondeR")
#' phase_corrections <- seasonder_readPhaseFile(phase_file)
seasonder_readPhaseFile <- function(file_path) {
  # Read the file lines and extract the first phase correction value using regex
  phasec1 <- readLines(file_path) %>%
    stringr::str_extract("([-\\d\\.]+)\\s*([-\\d\\.]+)", group = 1) %>%
    as.numeric()
  # Read the file lines again and extract the second phase correction value using regex
  phasec2 <- readLines(file_path) %>%
    stringr::str_extract("([-\\d\\.]+)\\s*([-\\d\\.]+)", group = 2) %>%
    as.numeric()
  # Return the phase corrections as a numeric vector with named elements
  return(c(phase1 = phasec1, phase2 = phasec2))
}

#### Plots ####

#' Plot APM Loops in a Polar Coordinate System
#'
#' This function generates a polar plot of the antenna pattern loops from a SeaSonde RAPM object.
#'
#' @param seasonder_apm_obj A SeaSonde RAPM object containing the antenna pattern data.
#'
#' @return A ggplot object displaying the magnitude of the two loops as a function of bearings.
#'
#' @export
#' @examples
#' # Plot loops from a test SeaSondeRAPM object
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' plot <- seasonder_plotAPMLoops(obj)
seasonder_plotAPMLoops <- function(seasonder_apm_obj) {
  loop <- rlang::zap()
  # Convert the BEAR attribute to geographical bearings using a helper function and unlist the result
  bearings <- seasonder_MUSICBearing2GeographicalBearing(attr(seasonder_apm_obj, "BEAR", exact = TRUE), seasonder_apm_obj) %>%
    unlist

  # Create a data frame with bearings and the magnitudes of the two antenna channels
  plot_data <- data.frame(
    bearings = bearings,
    loop1 = Mod(seasonder_apm_obj[1,]),
    loop2 = Mod(seasonder_apm_obj[2,])
  )

  # Pivot the data frame from wide to long format for plotting
  plot_data_long <- plot_data %>%
    tidyr::pivot_longer(
      cols = -bearings,        # Specify that all columns except 'bearings' should be pivoted
      names_to = "loop",       # The new column to store the names of the loops
      values_to = "Mod"        # The new column to store the magnitude values
    )

  # Build the ggplot object step by step
  p <- ggplot2::ggplot(
    data = plot_data_long,
    mapping = ggplot2::aes(x = bearings, y = Mod, color = loop)
  )
  p <- p + ggplot2::geom_point()         # Add points for each data observation
  p <- p + ggplot2::coord_polar()          # Convert the plot to polar coordinates
  p <- p + ggplot2::scale_x_continuous(    # Set x-axis scale for bearings from 0 to 360 degrees with breaks at 0, 90, 180, and 270
    limits = c(0, 360),
    breaks = c(0, 90, 180, 270)
  )

  # Return the completed ggplot object
  return(p)
}

#### print ####

#' Print a SeaSondeRAPM Object
#' 
#' This function prints the details of a SeaSondeRAPM object, including the station code,
#' original file name, site origin (latitude and longitude), and antenna bearing.
#' It is primarily used for displaying the object's metadata in a human-readable format.
#' 
#' @param x A SeaSondeRAPM object. This object should be created using the
#'   seasonder_createSeaSondeRAPM() function and must include a calibration matrix,
#'   a quality matrix, the BEAR attribute, and a StationCode.
#' @param ... Additional arguments that might be passed to other methods; currently not used.
#' @method print SeaSondeRAPM
#' @export
#' 
#' @return The SeaSondeRAPM object itself, invisibly.
#' 
#' @examples
#' # Print metadata of a test SeaSondeRAPM object
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' print(obj)
print.SeaSondeRAPM <- function(x, ...){

  template <- "Station Code{{{StationCode}}}\nOriginal File: {{{FileName}}}\nSite Origin: {{{Latitude}}} {{{Longitude}}}\nAntenna Bearing: {{{AntennaBearing}}}\n"
  render_data <- attributes(x)
  render_data$Longitude <- render_data$SiteOrigin["Longitude"]
  render_data$Latitude <- render_data$SiteOrigin["Latitude"]
  cat(whisker::whisker.render(template,data = render_data))

  invisible(x)

}


#### summary ####

#' Summarizes a SeaSondeRAPM Object
#'
#' This function prints a summary of a SeaSondeRAPM object by displaying its processing steps. 
#' The processing steps provide a record of the transformations and operations applied to the object, 
#' which can be useful for debugging and understanding the data workflow.
#'
#' @param object An object of class "SeaSondeRAPM". This object should be created using 
#'   the seasonder_createSeaSondeRAPM() function and must include a calibration matrix, a quality matrix, 
#'   the BEAR attribute, and a StationCode.
#' @param ... Additional arguments that might be passed to other methods; currently not used.
#'
#' @return Invisibly returns the input SeaSondeRAPM object. This allows the function to be used in a sequence 
#'   of operations (e.g., chaining) without printing the object again after the summary is displayed.
#'
#' @details The function first verifies that the provided object inherits from the "SeaSondeRAPM" class. 
#'   It then retrieves the processing steps associated with the object via the seasonder_getSeaSondeRAPM_ProcessingSteps() 
#'   function. These steps are concatenated into a single string, which is printed alongside a header indicating that 
#'   they represent the processing steps. This method is primarily used for diagnostic purposes and for verifying 
#'   that the object has undergone the intended series of operations.
#'
#' @examples
#' # Summarize a test SeaSondeRAPM object
#' apm_file <- system.file("css_data/MeasPattern.txt", package = "SeaSondeR")
#' obj <- seasonder_readSeaSondeRAPMFile(apm_file)
#' summary(obj)
#' @method summary SeaSondeRAPM
#' @export
summary.SeaSondeRAPM <- function(object, ...) {
  # Check if the object is of class SeaSondeRAPM
  if (!inherits(object, "SeaSondeRAPM")) {
    stop("The object must be of class 'SeaSondeRAPM'")
  }
  
  # Retrieve and collapse the processing steps
  processing_steps <- seasonder_getSeaSondeRAPM_ProcessingSteps(object) %>% 
  paste0(collapse = "\n")
  
  # Print the summary details
  cat("Processing steps:\n")
  cat(processing_steps, "\n")
  cat("\n")
  
  invisible(object)
}

Try the SeaSondeR package in your browser

Any scripts or data that you put into this service are public.

SeaSondeR documentation built on June 8, 2025, 10:50 a.m.