data {
    int<lower=0> N;
    int<lower=0> nit;
    matrix[N,nit] z;
    int<lower=0> zero_inf[nit];
    int<lower=0> one_inf[nit];
    int<lower=0> n_zero;
    int<lower=0> n_one;

    real<lower=0> sT;
    real<lower=0> sA;
    real<lower=0> sB;
    real<lower=0> sP;
    real<lower=0> sG;
  }

  parameters {
    vector[N] theta;
    vector[nit] beta;
    vector[nit] ln_phi;
    vector[nit] ln_alpha;
    vector[n_zero] gamma0;
    vector[n_one] gamma1;
  }

  transformed parameters{
    vector<lower=0>[nit] alpha = exp(ln_alpha);
    vector<lower=0>[nit] phi = exp(ln_phi);
    vector[nit] gamma0_star;
    vector[nit] gamma1_star;
    for(i in 1:nit){
        if(zero_inf[i]==0) gamma0_star[i]=-10.0; #only needed as a lower bound for gamma1_star (if only one inflation)
        if(zero_inf[i]!=0) gamma0_star[i]=gamma0[zero_inf[i]];
        if(one_inf[i]==0) gamma1_star[i]=10.0; #arbitrary, not used ;
        if(one_inf[i]!=0) gamma1_star[i]=gamma1[one_inf[i]];
   }
   }

   model {
    vector[nit] pbl = beta + ln_phi;
    vector[nit] mbl = -beta + ln_phi;

    for(i in 1:nit){
      if(zero_inf[i]!=0) gamma0[zero_inf[i]]~normal(0,sG);
      if(one_inf[i]!=0) gamma1[one_inf[i]]~normal(0,sG)T[gamma0_star[i],];
    }
  
    beta~normal(0,sB) ;
    ln_phi~normal(0,sP);
    ln_alpha~normal(0,sA);
    theta~normal(0,sT);

     for(p in 1:N){
       for(i in 1:nit){

       real at=alpha[i]*theta[p];

       if(z[p,i]!=0 && z[p,i]!=1 && z[p,i]!=-999){

         if(zero_inf[i]!=0 && one_inf[i]!=0){
           real p1=inv_logit(gamma1_star[i]-at);
           real p0=inv_logit(gamma0_star[i]-at);
           target+=log(p1-p0);
         }
	       if(zero_inf[i]!=0 && one_inf[i]==0){
	         real p0=inv_logit(gamma0_star[i]-at);
	         target+=log1m(p0);
	       }
         if(zero_inf[i]==0 && one_inf[i]!=0){
           real p1=inv_logit(gamma1_star[i]-at);
           target+=log(p1);
         }

         target+=beta_lpdf(z[p,i] |
              exp(.5* (at + pbl[i])),
              exp(.5* (-at + mbl[i])));
       }
       else{
         if(z[p,i]==0){
            real p0=inv_logit(gamma0_star[i]-at);
            target+=log(p0);
         }
         if(z[p,i]==1){
            real p1=inv_logit(gamma1_star[i]-at);
            target+=log1m(p1);
         }
       }
     }
   }
}
