# ============================================================
# GENERIC USAGE EXAMPLE (MDaRes)
# ADAPTED TO THE FILES AVAILABLE IN inst/extdata
# - Import Structural Alphabet
# - Perform encoding from trajectory
# - Compute Shannon entropy, ranking, and frequency profile
# - Compute Mutual Information, ranking, and total ranking
# - Export results for PyMOL visualization
# - Add UniProt annotation (optional)
# ============================================================

library(MDaRes)

run_mdares_workflow <- function(
    output_dir = tempfile("MDaRes-workflow-")
) {
dir.create(output_dir, recursive = TRUE, showWarnings = FALSE)

# ------------------------------------------------------------
# 0) Setup: locate package extdata and load Structural Alphabet
# ------------------------------------------------------------
extdata_path <- system.file("extdata", package = "MDaRes")

SA <- import_SA()

# ------------------------------------------------------------
# 1) Structural Alphabet encoding from XTC + topology/structure
# ------------------------------------------------------------
trj_name  <- file.path(extdata_path, "example_calpha.xtc")
top_name  <- file.path(extdata_path, "example_calpha_top.pdb")
pdb_name  <- file.path(extdata_path, "example_calpha_ref.pdb")
sel_chain <- "A"

enc <- SA_encoding(
  SA        = SA,
  trj_name  = trj_name,
  top_name  = top_name,
  pdb_name  = pdb_name,
  sel_chain = sel_chain,
  parallel  = "none",
  verbose   = TRUE
)

encoding_file <- file.path(output_dir, "enc_example_calpha.RDS")
saveRDS(enc, encoding_file)

# Optional: run encoding with future-based parallelization
# enc_future <- SA_encoding(
#   SA          = SA,
#   trj_name    = trj_name,
#   top_name    = top_name,
#   pdb_name    = pdb_name,
#   sel_chain   = sel_chain,
#   parallel    = "future",
#   workers     = 6,
#   future_plan = future::multisession,
#   verbose     = TRUE
# )
# saveRDS(enc_future, file.path(output_dir, "enc_example_calpha_future.RDS"))

# ------------------------------------------------------------
# 2) Single-system analysis: Shannon, frequency, MI, total ranking
# ------------------------------------------------------------
encoding <- readRDS(encoding_file)

# -- Shannon entropy
sh <- shannon_entropy(encoded_trajectory = encoding)

# Display the Shannon entropy plot interactively
if (interactive()) {
  shannon_entropy_plot(shannon_output = sh)
}

# Save the Shannon entropy plot to file
do_shannon_entropy_plot(
  shannon_output = sh,
  output_name    = file.path(output_dir, "shannon_plot_example_calpha")
)

# Compute Shannon-based residue ranking
sh_rank <- shannon_ranking(shannon_output = sh)
write.csv(
  sh_rank,
  file.path(output_dir, "sh_ranking_example_calpha.csv"),
  row.names = FALSE
)

# -- Structural sequence profile (state frequency)
# Display the frequency profile interactively
if (interactive()) {
  freq_plot(shannon_output = sh)
}

# Save the frequency profile to file
do_freq_plot(
  shannon_output = sh,
  output_name    = file.path(output_dir, "frequency_example_calpha")
)

# -- Mutual Information
mi <- MImat(encoded_trajectory = encoding)
saveRDS(mi, file.path(output_dir, "MImat_example_calpha.RDS"))

# Display the MI matrix plot interactively
if (interactive()) {
  MI_plot(MI_output = mi)
}

# Save the MI matrix plot to file
do_MI_plot(mi, file.path(output_dir, "MImatrix_example_calpha"))

# Compute pairwise MI ranking
mi_couples <- MI_ranking_couple(mi)
write.csv(
  mi_couples,
  file.path(output_dir, "MIcouple_example_calpha.csv"),
  row.names = FALSE
)

# Compute residue-wise MI ranking
mi_rank <- MI_ranking_median(mi)

# -- Total ranking
# Merge Shannon ranking and MI ranking into a combined score
tot_rank <- total_ranking(sh_rank, mi_rank)
write.csv(
  tot_rank,
  file.path(output_dir, "totalRanking_example_calpha.csv"),
  row.names = FALSE
)

# ------------------------------------------------------------
# 3) PyMOL export
# Write entropy/ranking values into the PDB B-factor column
# and generate the PyMOL visualization script
# ------------------------------------------------------------
working_pdb <- file.path(output_dir, basename(pdb_name))
file.copy(pdb_name, working_pdb, overwrite = TRUE)

entropy_visualization(
  pdb_filename    = working_pdb,
  chain           = "A",
  shannon_output  = sh
)

# ------------------------------------------------------------
# 4) UniProt annotation (optional)
# Add UniProt feature annotations to the ranking table
# ------------------------------------------------------------
annot <- add_uniprot_annotation("PXXXXX", tot_rank)
write.csv(
  annot,
  file.path(output_dir, "annotation_example_calpha.csv"),
  row.names = FALSE
)

# ------------------------------------------------------------
# 5) Comparison between two encoded systems
# ------------------------------------------------------------

# Load the first encoding (generated in this workflow)
enc_1 <- readRDS(encoding_file)

# Load the second encoding from the package extdata
enc_2 <- readRDS(
  system.file("extdata", "example_encoding_2.RDS", package = "MDaRes")
)

# ---- Shannon entropy comparison ----

sh_1 <- shannon_entropy(encoded_trajectory = enc_1)
sh_2 <- shannon_entropy(encoded_trajectory = enc_2)

# Display Shannon entropy difference interactively
if (interactive()) {
  shannon_entropy_diff_plot(
    first_out  = sh_1,
    second_out = sh_2,
    overlay    = TRUE
  )
}

# Save Shannon entropy difference plot
do_shannon_entropy_diff_plot(
  first_shannon  = sh_1,
  second_shannon = sh_2,
  output_name    = file.path(output_dir, "DiffShannon_example")
)

# ---- Frequency profile comparison ----

# Display frequency difference interactively
if (interactive()) {
  freq_diff_plot(
    first_freq  = sh_1,
    second_freq = sh_2
  )
}

# Save frequency difference plot
do_freq_diff_plot(
  first_freq  = sh_1,
  second_freq = sh_2,
  output_name = file.path(output_dir, "FreqDiff_example")
)

# ---- Mutual Information comparison ----

# Compute MI matrices for both systems
MI_1 <- MImat(encoded_trajectory = enc_1)
MI_2 <- MImat(encoded_trajectory = enc_2)

# Build MI difference object
MI_diff <- list(
  "MI" = (MI_1$MI - MI_2$MI),
  "Residues numbering" = MI_1$`Residues numbering`
)

class(MI_diff) <- "MI_list"

# Display MI difference matrix
if (interactive()) {
  MI_plot(MI_diff)
}

invisible(output_dir)
}
