#' @title Select features through the selection  of singular value vectors
#'
#' @param SVD SVD computed from matrix generated by partial summation of a tensor
#' @param cond Condition to select singular value vectors
#' @param de  Initial values to be used for optimization of standard deviation  
#' @param p0  Threshold value for the significance
#' @param breaks Number of bins of histogram of P-values
#' @param input_all The ID of selected singular value vectors. If it is null, 
#' interactive mode is activated.
#'
#' @return List of lists that includes P-vales as well as if individual
#'  features selected.
#' @export
#'
#' @examples
#' set.seed(0)
#' matrix1 <- matrix(runif(2000),200)
#' matrix2 <- matrix(runif(4000),200)
#' SVD <- computeSVD(matrix1,matrix2)
#' index_all <- selectFeatureRect(SVD,
#' list(NULL,rep(seq_len(2),each=5),rep(seq_len(2),each=10)),de=rep(0.5,2),
#' input_all=1)
selectFeatureRect <- function(SVD, cond, de = rep(1e-4, 2), p0 = 0.01,
                              breaks = 100L, input_all = NULL) {
  # Augument check
  stopifnot("`SVD` must be a list." = is.list(SVD))
  stopifnot("`cond` must be a list." = is.list(cond))
  stopifnot("`de` must be a numeric." = is.numeric(de))
  stopifnot("`p0` must be a numeric." = is.numeric(p0))
  stopifnot("`breaks` must be a integer." = is.integer(breaks))
  stopifnot("`input_all` must be a vector." = is.vector(input_all) |
    is.null(input_all))
  #
  interact <- FALSE
  if (is.null(input_all)) {
    interact <- TRUE
    j <- 1
    ui <- fluidPage(
      sidebarLayout(
        sidebarPanel(
          h3("Select one with prefarable dependence"),
          actionButton(inputId = "action", label = "Next"),
          actionButton(inputId = "prev", label = "Prev"),
          actionButton(inputId = "select", label = "Select")
        ),
        mainPanel(
          plotOutput("plot")
        )
      )
    )

    server <- function(input, output) {
      observeEvent(input$action, {
        if (j < dim(SVD$SVD$u)[2]) j <<- j + 1
      })
      observeEvent(input$prev, {
        if (j != 1) {
          j <<- j - 1
        }
      })
      observeEvent(input$select, {
        input_all <<- j
        stopApp()
      })
      output$plot <- renderPlot({
        input$action
        input$prev
        par(mfrow = c(1, 2))
        boxplot(SVD$SVD$u[, j] ~ cond[[2]], main = j)
        abline(0, 0, col = 2, lty = 2)
        boxplot(SVD$SVD$v[, j] ~ cond[[3]], main = j)
        abline(0, 0, col = 2, lty = 2)
        par(mfrow = c(1, 1))
      })
    }
    app <- shinyApp(ui, server)
    runApp(app)
  } else {
    par(mfrow = c(1, 2))
    boxplot(SVD$SVD$u[, input_all] ~ cond[[2]], main = input_all)
    abline(0, 0, col = 2, lty = 2)
    boxplot(SVD$SVD$v[, input_all] ~ cond[[3]], main = input_all)
    abline(0, 0, col = 2, lty = 2)
    par(mfrow = c(1, 1))
  }
  th <- function(sd, breaks, p0) {
    P2 <- pchisq((u / sd)^2, 1, lower.tail = FALSE)
    hc <- hist(1 - P2, breaks = breaks, plot = FALSE)
    return(sd(hc$count[seq_len(sum(hc$breaks
    < 1 - min(P2[p.adjust(P2, "BH") > p0])))]))
  }
  index_all <- rep(list(NA))
  for (i in seq_len(2))
  {
    u <- scale(SVD[[i + 1]][, input_all])
    sd <- optim(de[i], function(x) {
      th(x, breaks, p0)
    },
    control = list(warn.1d.NelderMead = FALSE)
    )$par
    sd1 <- seq(0.1 * sd, 2 * sd, by = 0.1 * sd)
    th0 <- apply(matrix(sd1, ncol = 1), 1, function(x) {
      th(x, breaks, p0)
    })
    P2 <- pchisq((u / sd)^2, 1, lower.tail = FALSE)
    if (interact) {
      ui <- fluidPage(
        sidebarLayout(
          sidebarPanel(
            actionButton(inputId = "action", label = "Next")
          ),
          mainPanel(
            plotOutput("plot")
          )
        )
      )
      server <- function(input, output) {
        observeEvent(input$action, {
          stopApp()
        })
        output$plot <- renderPlot({
          input$action
          par(mfrow = c(1, 2))
          plot(sd1, th0, type = "o")
          arrows(sd, max(th0), sd, min(th0), col = 2)
          hist(1 - P2, breaks = breaks)
          par(mfrow = c(1, 1))
        })
      }
      app <- shinyApp(ui, server)
      runApp(app)
    } else {
      par(mfrow = c(1, 2))
      plot(sd1, th0, type = "o")
      arrows(sd, max(th0), sd, min(th0), col = 2)
      hist(1 - P2, breaks = breaks)
      par(mfrow = c(1, 1))
    }
    index <- p.adjust(P2, "BH") < p0
    index_all[[i]] <- list(index = index, p.value = P2)
  }
  return(index_all)
}
    