#' Generating Test Score Distribution
#'
#' This function generates a frequency distribution table
#'  of n discrete test scores in [minscore,maxscore].
#'
#' @param n # of observations.
#' @param minscore The minimum score.
#' @param maxscore The maximum score.
#' @param normal Vector consisting of mean and std for normal distribution.
#' @param beta Vector of alpha and beta parameters for beta distribution
#' in [minscore,maxscore].
#' @param beta_ms Vector of mean and std of the generalized beta distribution
#' in [minscore,maxscore].
#' @param dump = 1 to output the discrete random numbers.
#' @param print = 1 to print the result.
#' @param plot = 1 to plot the result.
#' @param title Title string to be used in plot.
#'
#' @details
#' This function generates a frequency distribution table
#'  of n discrete test scores in [minscore,maxscore].
#'
#' Continuous random numbers, either normal or generalized beta,
#' are first generated and then they are discretized by cut function.
#' Those values outside of [minscore,maxscore] will be set to minscore
#' or maxscore, resp.
#'
#' beta_ms parameter has the priority over beta and nomal parameter.
#'
#' @examples
#' seed <- 1701
#' set.seed(seed)
#'
#' minscore <- 0; maxscore <- 100
#' n <- 500
#'
#' s1 <- gen_test_score( n, minscore, maxscore, beta=c(4,8), plot=1 )
#' ( mands(s1[,1],s1[,2]) )
#' s2 <- gen_test_score( n, minscore, maxscore
#'                     , beta_ms=c(33.29, 13.07), plot=1 )
#' ( mands(s2[,1],s2[,2]) )
#'
#' # mixture
#' minscore <- 0; maxscore <- 50
#' scoredist1 <- gen_test_score( n, minscore, maxscore, beta=c(4,8), plot=1 )
#' scoredist2 <- gen_test_score( n, minscore, maxscore, normal=c(30,5), plot=1)
#' scoredist12 <- merge_tables( scoredist1,scoredist2 )
#' barplot(height=scoredist12[,2], names.arg=as.character(scoredist12[,1])
#'         , main="Score Dist", cex.names=.65, space=0, las=2)
#'
#' @return
#' If dump == 0, a matrix consisting of (score, frequency). \cr
#' otherwise, a list of rv, random numbers, and freqdist matrix.
#'
#' @export
#'

gen_test_score <- function( n, minscore=0, maxscore=100, normal=c(50,15)
                            , beta=NULL, beta_ms=NULL, dump=0, print=0, plot=0
                            , title="Score Distribution" ){
 # generate test score in [minscore,maxscore].
 # Shin-ichi Mayekawa
 # 20160722
 # bugfix score[x]: 20160821
 # dump option: 20160821
 # title: 20161202
 # roxygen commnets: 20180814dnc
 # beta_ms: 20230818
 #

 range=maxscore-minscore

 # random numbers
 if( !is.null(beta_ms) ){
  if( beta_ms[2] > range^2/4 ) beta_ms[2]=range^2/4
  my=(beta_ms[1]-minscore)/range
  sy2=( beta_ms[2]/range )^2
  beta=numeric(2)
  beta[1]=-my*(my^2-my+sy2)/sy2
  beta[2]=-(1-my)*(my^2-my+sy2)/sy2
  Print(my,sy2,beta)
  x0=rbeta(n,beta[1],beta[2])
  x0=x0*range+minscore
  param=paste( beta_ms, collapse=", ")
  dist="beta_ms"
 }
 else if( !is.null(beta) ){
    x0=rbeta(n,beta[1],beta[2])
    x0=x0*range+minscore
    param=paste( beta, collapse=", ")
    dist="beta"
 }
 else if( !is.null(normal) ){
  mean=normal[1]; std=normal[2]
  x0=mean+std*rnorm(n)
  param=paste( normal, collapse=", ")
  dist="normal"
 }

 x0[x0<minscore]=minscore
 x0[x0>maxscore]=maxscore

 # histogram
 score=seq(minscore,maxscore,length.out=maxscore-minscore+1)
 brk=c(score-0.5, maxscore)
 brk[length(brk)]=maxscore
 x=as.numeric( cut( x0, breaks=brk, right=1 ) )
 x=score[x]
 resh=hist( x, breaks=c(-0.5,score+.5), right=1, plot=0 )
 scoredist=cbind(score,resh$count)
 colnames(scoredist)=c("score","freq")

 if( plot ){
  title=paste( title, ":  n = ", n, sep="" )
  title=paste(title, ",  ", dist, " with param = (", param, " )", sep="")
  barplot(height=scoredist[,2], names.arg=as.character(scoredist[,1])
          , main=title, cex.names=.65, space=0, las=2)
 }

 if( print ){
  Print(scoredist)
 }

 res=scoredist
 if( dump == 1 ) res=list( rv=x, freqdist=scoredist )
 return( res )

} # gen_test_score



