library(shiny)

ui <- fluidPage(
  sidebarLayout(
    sidebarPanel(
      numericInput("n", 
        label = "Number of trials n", 
        value = 10),
      numericInput("p", 
        label = "Probability of success p", 
        value = 0.2, min=0, max=1, step=0.1),
      radioButtons("radio", 
        label = "Please the probability you want to calculate:", 
        choices = list("At least (p-value)" = 1, "Between" = 2, "Exact (probability mass function)" = 3, "At most (cumulative distribution function)" = 4),
        selected = 1),
        conditionalPanel("input.radio == 1",
          numericInput("a1", 
           label = "Boundary", 
           value = 2)		
           ),
        conditionalPanel("input.radio == 2",
          numericInput("a2", 
           label = "Lower bound", 
           value = 2),
          numericInput("b2", 
           label = "Upper bound", 
           value = 4)			
          ),
        conditionalPanel("input.radio == 3",
          numericInput("a3", 
           label = "Value", 
           value = 3)			
          ),
        conditionalPanel("input.radio == 4",
          numericInput("b4", 
           label = "Boundary", 
           value = 4)			
          )
    )
    ,
    mainPanel(
      p("Let ", em("p"), " (0", HTML("&le;"), em("p"),HTML("&le;"),"1) be the pobability of success. The probability mass function is given by:"),
      plotOutput("pdfPlot"),
      textOutput("pdfDescription"),
      strong(textOutput("pdfSum"))
    )
  )
)

server <- function(input, output) {
  CheckPars <- reactive({ 
    #Parameter checks for n and p
    validate(
      need(all(input$n > 0, is.numeric(input$n), input$n%%1==0), "Value for n not allowed. Please check."),
      need(any(input$n < 10001, !is.numeric(input$n)), "Value for n not allowed (n > 10000). Please check."),
      need(all(input$p <= 1, input$p >= 0, is.numeric(input$p)), "Value for p not allowed. Please check.")
    )
    #Parameter checks for a and b
    if (input$radio == 1) {
      validate(
        need(all(is.numeric(input$a1), input$a1%%1==0), "Invalid input. Please check.")
      )
    }
    if (input$radio == 2) {
      validate(
        need(all(is.numeric(input$a2), input$a2%%1==0), "Invalid input. Please check."),
        need(all(is.numeric(input$b2), input$b2%%1==0), "Invalid input. Please check.")
      )
    }
    if (input$radio == 3) {
      validate(
        need(all(is.numeric(input$a3), input$a3%%1==0, input$a3>=0, input$a3<=input$n), "Invalid input. Please check.")
      )
    }
    if (input$radio == 4) {
      validate(
        need(all(input$b4 >= 0, is.numeric(input$b4), input$b4%%1==0), "Invalid input. Please check.")
      )
    }
  })
  
  #Calculation of complete probability density function
  PDF <- reactive({
    CheckPars()
    dbinom(0:input$n, input$n, input$p)
  })
  
  #Calculation of range
  a <- reactive({
    CheckPars()
    if (input$radio == 1) {
      value <- max(input$a1,0)
    }
    if (input$radio == 2) {
      value <- max(input$a2,0)
    }
    if (input$radio == 3) {
      value <- input$a3
    }
    if (input$radio == 4) {
      value <- 0
    }
    return(value)
  })
  
  b <- reactive({
    CheckPars()
    if (input$radio == 1) {
      value <- max(input$n,input$a1)
    }
    if (input$radio == 2) {
      value <- min(input$b2,input$n)
    }
    if (input$radio == 3) {
      value <- input$a3
    }
    if (input$radio == 4) {
      value <- min(input$b4,input$n)
    }
    return(value)
  })		
  
  output$pdfPlot <- renderPlot({
    #General Plot
    plot(PDF(), 
         type = "h",
         xlab = "Number of successes",
         ylab = "Probability",
         axes = FALSE
    )
    #X-Axis
    axis(1,
         at = 1:(input$n+1),
         labels = 0:(input$n)
    )
    #Y-Axis
    axis(2)
    #Points
    points(PDF(),
           pch = 16
    )
    #Mark lines a to b
    points((a()+1):(b()+1),PDF()[(a()+1):(b()+1)],
           col = "red",
           type = "h"
    )
    #Mark points a to b
    points((a()+1):(b()+1),PDF()[(a()+1):(b()+1)],
           pch = 16,
           col = "red"
    )
  })
  
  output$pdfDescription <- renderText({
    if (input$radio == 1) {
      helpertext <- paste("The probability of at least", input$a1, "successes (p-value of binomial test) is:")
    }
    if (input$radio == 2) {
      helpertext <- paste("The probability of between", input$a2, "and", input$b2, "successes is:")
    }
    if (input$radio == 3) {
      helpertext <- paste("The probability of exactly", input$a3, "successes (probability mass function) is:")
    }
    if (input$radio == 4) {
      helpertext <- paste("The probability of at most", input$b4, "successes (cumulative distribution function) is:")
    }
    
    paste(helpertext)
  })
  
  output$pdfSum <- renderText({	
    sumPDF <- sum(PDF()[(a()+1):(b()+1)])
    
    paste(sumPDF)
  })
}

shinyApp(ui = ui, server = server)