# A Shiny palette explorer themed with NDPalette.
#
# It colors the page chrome from the Notre Dame palette with a bslib theme,
# lets you switch among three page backgrounds (plain white, the informal
# soft white, and the informal soft yellow), paints the figure with the
# scale_*_nd() scales, and shows the exact theme code with a copy button and
# a show/hide toggle. A download button saves the current palette as a CSV.
#
# Run it with:
#   shiny::runApp(system.file("examples", "nd-shiny-app", package = "NDPalette"))

library(shiny)
library(ggplot2)
library(NDPalette)

# Three page backgrounds to choose from: plain white, and two soft
# informal tints (which are NOT Notre Dame brand colors -- non-white
# alternatives to a plain white page).
bg_choices <- c(
  "White"       = "#ffffff",
  "Soft white"  = unname(nd_informal_tints[["soft_white"]]),
  "Soft yellow" = unname(nd_informal_tints[["soft_yellow_light"]])
)

# A bslib theme with the chosen background; text and accents stay brand
# colors, so only the page background changes between choices.
nd_theme <- function(bg) {
  bslib::bs_theme(
    version   = 5,
    bg        = bg,
    fg        = nd_color("navy"),
    primary   = nd_color("navy"),
    secondary = nd_color("bright_gold")
  )
}

# The theme code as text, for the copy-the-code panel.
theme_code <- function(bg_name, bg) {
  paste(
    "bslib::bs_theme(",
    "  version   = 5,",
    sprintf('  bg        = "%s",   # %s', bg, bg_name),
    '  fg        = nd_color("navy"),',
    '  primary   = nd_color("navy"),',
    '  secondary = nd_color("bright_gold")',
    ")",
    sep = "\n"
  )
}

ui <- bslib::page_sidebar(
  theme = nd_theme(bg_choices[["Soft white"]]),
  title = "NDPalette — a Notre Dame palette explorer",
  sidebar = bslib::sidebar(
    radioButtons("bg", "Page background", names(bg_choices),
                 selected = "Soft white"),
    selectInput("palette", "Palette",
                c("Notre Dame (nd)"              = "nd",
                  "Colorblind-friendly (nd_cvd)" = "nd_cvd",
                  "Former colors (former)"       = "former")),
    sliderInput("n", "Number of groups", min = 2, max = 10, value = 5),
    checkboxInput("reverse", "Reverse color order", FALSE),
    checkboxInput("show_code", "Show theme code", FALSE),    # the hide option
    downloadButton("dl", "Download palette (CSV)", class = "btn-sm")
  ),
  bslib::card(
    bslib::card_header("Swatches"),
    plotOutput("swatch", height = "110px")
  ),
  # The theme code, shown only when "Show theme code" is checked, with a
  # button that copies it to the clipboard.
  conditionalPanel(
    condition = "input.show_code",
    bslib::card(
      bslib::card_header(
        "Theme code",
        tags$button(
          "Copy", class = "btn btn-sm btn-primary float-end",
          onclick = paste0(
            "navigator.clipboard.writeText(",
            "document.getElementById('themecode').innerText)")
        )
      ),
      verbatimTextOutput("themecode")
    )
  ),
  bslib::card(
    bslib::card_header("A grouped figure painted with scale_color_nd()"),
    plotOutput("plot", height = "340px")
  ),
  bslib::card(
    bslib::card_header("Color reference (nd_colors)"),
    tableOutput("table")
  )
)

server <- function(input, output, session) {
  # Switch the live theme when the background choice changes.
  observeEvent(input$bg, {
    session$setCurrentTheme(nd_theme(bg_choices[[input$bg]]))
  })

  cols <- reactive(
    nd_palette(input$n, palette = input$palette, reverse = input$reverse)
  )

  output$swatch <- renderPlot(show_palette(cols()))

  output$plot <- renderPlot({
    set.seed(113)
    groups <- factor(LETTERS[seq_len(input$n)])
    df <- data.frame(x = rnorm(input$n * 40), y = rnorm(input$n * 40),
                     group = rep(groups, each = 40))
    ggplot(df, aes(x, y, color = group)) +
      geom_point(size = 2, alpha = 0.85) +
      scale_color_nd(palette = input$palette, reverse = input$reverse) +
      theme_minimal(base_size = 13) +
      labs(x = NULL, y = NULL, color = NULL)
  })

  output$themecode <- renderText(theme_code(input$bg, bg_choices[[input$bg]]))

  output$table <- renderTable(
    nd_colors[, c("name", "key", "hex", "role", "description")]
  )

  output$dl <- downloadHandler(
    filename = function() sprintf("nd_palette_%s_%d.csv", input$palette, input$n),
    content  = function(file) {
      utils::write.csv(data.frame(position = seq_along(cols()), hex = cols()),
                       file, row.names = FALSE)
    }
  )
}

shinyApp(ui, server)
