#include <TMB.hpp>                                // Links in the TMB libraries

template<class Type>
Type objective_function<Type>::operator() ()
{
    DATA_INTEGER(n);                                       // number of capture histories
    DATA_INTEGER(m);                                       // number of capture occasions
    DATA_MATRIX(ch);                                       // capture history matrix
    DATA_VECTOR(frq);                                      // capture history frequencies
    DATA_IVECTOR(frst);                                    // occasion first seen for each history
    DATA_IVECTOR(lst);                                     // occasion last seen for each history
    DATA_IVECTOR(loc);                                     // 0 or 1, 1 if lost on capture at last event
    DATA_MATRIX(tint);                                     // time interval between occasions 
    DATA_INTEGER(kphi);                                    // number of Phi DM columns
	DATA_MATRIX(phi_fixedDM);                              // Phi DM
    DATA_INTEGER(kp);                                      // number of p DM columns
	DATA_MATRIX(p_fixedDM);                                // p DM
		
    PARAMETER_VECTOR(phi_beta);
    PARAMETER_VECTOR(p_beta);
	
    vector<Type> phi(m);              // temp vector for Phis for each occasion for a single history
    vector<Type> p(m-1);              // temp vector for Phis for each occasion for a single history
    vector<Type> phicumprod(m);       // cummulative survival probability across occasions
    vector<Type> cump(m);             // cummulative probability of being seen across occasions
    Type pch;                         // probability of capture history
    int i1,i2,j,L;	                  // miscellaneous ints
    Type mu;                          // link function value
	Type f=0;

	for(int i=1;i<=n;i++)                                 // loop over capture histories - one per animal
    {
       vector<Type> phi(m);              // temp vector for Phis for each occasion for a single history
       vector<Type> p(m-1);              // temp vector for Phis for each occasion for a single history
	   vector<Type> phicumprod(m);       // cummulative survival probability across occasions
	   vector<Type> cump(m);             // cummulative probability of being seen across occasions
	   Type pch;                         // probability of capture history
       int i1,i2,j,L;	                 // miscellaneous ints
       Type mu;                          // link function value

	   for(j=0;j<=m-1;j++)               
       {   
 	      phicumprod(j)=1.0;             // set cummulative survival to 1
          cump(j)=1.0;                   // set cummulative p to 1
		  phi(j)=0;                      // set all phi values to 0
       }		  
	   i1=(m-1)*(i-1);                                                // compute beginning index in design matrix
	   for(j=frst(i-1)+1;j<=m;j++)                                      // loop over occasions from frst to m
	   {
	      i2=i1+j-1;                                                  // increment index in design matrix
          /////// phi computation //////////
	      if(phi_fixedDM(i2-1,kphi)== -1)
	      {
	         mu=0;
	         for(L=1;L<=kphi;L++)
                mu+=phi_fixedDM(i2-1,L-1)*phi_beta(L-1);                     // fixed portion of mean 
             phi(j-2)=1/(1+exp(-mu));                                 // compute phi for the interval
             if(tint(i-1,j-2)!=1)
                phi(j-2)=pow(phi(j-2),tint(i-1,j-2));                   // adjust phi for the time interval length
	      } else
	         phi(j-2)=phi_fixedDM(i2-1,kphi);
	      /////// p computation /////////
	      if(p_fixedDM(i2-1,kp)== -1)
	      {
   	         mu=0;
	         for(L=1;L<=kp;L++)
                mu+=p_fixedDM(i2-1,L-1)*p_beta(L-1);                         // fixed portion of mean 
             p(j-2)=1/(1+exp(-mu));                                     
          } else
	         p(j-2)=p_fixedDM(i2-1,kp);
	   
	      phicumprod(j-1)=phicumprod(j-2)*phi(j-2);                     // compute cummulative survival
	      cump(j-1)=cump(j-2)*((1-p(j-2))*(1-ch(i-1,j-1))+p(j-2)*ch(i-1,j-1));  // compute cummulative capture probability
	   }   
       pch=0.0;                                                       // initialize prob of the capture history to 0
       for(j=lst(i-1);j<=((1-loc(i-1))*m+loc(i-1)*lst(i-1));j++)              // loop over last occasion to m unless loss on capture
       {                                                              // to compute prob of the capture history 
          if(loc(i-1)==1)
             pch=pch+cump(j-1)*phicumprod(j-1);                           // probability of history given possible last occasion alive
          else       
             pch=pch+cump(j-1)*phicumprod(j-1)*(1-phi(j-1));                // probability of history given possible last occasion alive
       }   
          f-= log(pch+1E-24)*frq(i-1);                                  // sum log-likelihood log(pr(ch))
    }
    return f;
}
