dBIRT=function(z,alpha,beta,phi,gamma0=NULL,gamma1=NULL,model=c("beta","samejima","simplex","normal")){
    model=match.arg(model)
    if(phi<0) stop("The dispersion parameter phi should be larger than 0")
    if(is.null(gamma0)) gamma0=-Inf
    if(is.null(gamma1)) gamma1=Inf
    if(any(z>1) | any(z<0)) stop("Item scores shoud be between 0 and 1")

 if(model=="beta"){
    marg=function(theta,z,beta,alpha,gamma0,gamma1,phi){
    ln_phi=log(phi)
    if(z!=0 & z!=1 & z!=-999){
       a = exp(.5* (alpha*theta + beta+ln_phi));
       b  = exp(.5* (-alpha*theta - beta+ln_phi));
       out= (stats::plogis(gamma1-alpha*theta) - stats::plogis(gamma0-alpha*theta))*stats::dbeta(z,a,b)
    }
    else if(z==0) out=stats::plogis(gamma0-alpha*theta)
    else if(z==1) out=1-stats::plogis(gamma1-alpha*theta)
  return(out*stats::dnorm(theta))
  }
  }

 if(model=="simplex"){
   dsimplex=function (y, m, s2){  #from rmutil by Swihart & Lindsey (2022) but with minor adjustment
     tmp <- -((y - m)/(m * (1 - m)))^2/(2 * y * (1 - y) * s2) -
       (log(2 * pi * s2) + 3 * (log(y) + log(1 - y)))/2
     return(exp(tmp))
   }
  marg=function(theta,z,beta,alpha,gamma0,gamma1,phi){
    if(z!=0 & z!=1 & z!=-999) out= (stats::plogis(gamma1-alpha*theta) - stats::plogis(gamma0-alpha*theta))*dsimplex(z,stats::plogis(beta+alpha*theta),phi)
    else if(z==0) out=stats::plogis(gamma0-alpha*theta)
    else if(z==1) out=1-stats::plogis(gamma1-alpha*theta)
  return(out*stats::dnorm(theta))
  }
  }

 if(model=="samejima"){
 marg=function(theta,z,beta,alpha,gamma0,gamma1,phi){
    if(z!=0 & z!=1 & z!=-999) out= (stats::plogis(gamma1-alpha*theta) - stats::plogis(gamma0-alpha*theta))*1/(z*(1-z))*stats::dnorm(stats::qlogis(z),beta+alpha*theta,sqrt(phi))
    else if(z==0) out=stats::plogis(gamma0-alpha*theta)
    else if(z==1) out=1-stats::plogis(gamma1-alpha*theta)
  return(out*stats::dnorm(theta))
  }
 }
 if(model=="normal"){
  marg=function(theta,z,beta,alpha,gamma0,gamma1,phi){
    if(z!=0 & z!=1 & z!=-999) out= (stats::plogis(gamma1-alpha*theta) - stats::plogis(gamma0-alpha*theta))*stats::dnorm(z,beta+alpha*theta,sqrt(phi))
    else if(z==0) out=stats::plogis(gamma0-alpha*theta)
    else if(z==1) out=1-stats::plogis(gamma1-alpha*theta)
    return(out*stats::dnorm(theta))
  }
}

  ou=c()
  for(i in 1:length(z)){
    ou[i]=stats::integrate(marg,-Inf,Inf,z=z[i],beta=beta,alpha=alpha,gamma0=gamma0,gamma1=gamma1,phi=phi)$value
  }
return(ou)
}
