#include <OrbitalInfo.h>

using namespace std;

ClassImp(OrbitalInfoTrkVar);
ClassImp(OrbitalInfo);

OrbitalInfoTrkVar::OrbitalInfoTrkVar(){
  this->Clear();
  //  Eij = new TMatrixD(3,3);
  //  Sij = new TMatrixD(3,3);
}

void OrbitalInfoTrkVar::Clear(Option_t *t){
  trkseqno = 0;
  pitch = -1000.;
  sunangle = -1000;
  sunmagangle = -1000;
  cutoff = -1000.;
  Eij.Zero();
  Sij.Zero();
}

void OrbitalInfoTrkVar::Delete(Option_t *t){
  //  if ( Eij ) Eij->Delete();
  //  if ( Sij ) Sij->Delete();
}

OrbitalInfo::OrbitalInfo(){
  OrbitalInfoTrk = 0; //ELENA
  this->Clear();
}

OrbitalInfoTrkVar::OrbitalInfoTrkVar(const OrbitalInfoTrkVar &t){
  //
  trkseqno = t.trkseqno;  
  //
  pitch = t.pitch;
  cutoff = t.cutoff;
  sunangle=t.sunangle;
  sunmagangle=t.sunmagangle;
  //
  Eij.ResizeTo(t.Eij);	
  Eij = t.Eij;	
  Sij.ResizeTo(t.Sij);	
  Sij = t.Sij;	
  //
};

void OrbitalInfo::Delete(Option_t *t){ //ELENA
  //
  //  if ( Iij ) Iij->Delete();
  if(OrbitalInfoTrk){ 
    OrbitalInfoTrk->Delete(); //ELENA
    delete OrbitalInfoTrk;  //ELENA
  }
  // 
}; //ELENA

void OrbitalInfo::Set(){//ELENA
  if ( !OrbitalInfoTrk ) OrbitalInfoTrk = new TClonesArray("OrbitalInfoTrkVar",2); //ELENA}  
  //  if ( !Iij ) Iij = new TMatrixD(3,3);
}//ELENA
//--------------------------------------
//
//
//--------------------------------------
void OrbitalInfo::SetTrackArray(TClonesArray *track){//ELENA
//    if(track && strcmp(track->GetClass()->GetName(),"OrbitalInfoTrkVar")==0){
	if(OrbitalInfoTrk)OrbitalInfoTrk->Clear("C");
	OrbitalInfoTrk = track;
//    }
}

OrbitalInfoTrkVar *OrbitalInfo::GetOrbitalInfoTrkVar(Int_t itrk){
  //    
  if(itrk >= ntrk()){
    printf(" OrbitalInfo ERROR: track related variables set %i does not exists! \n",itrk);
    printf("                    stored track related variables = %i \n",ntrk());
    return(NULL);
  }  
  //
  if(!OrbitalInfoTrk)return 0; //ELENA
  TClonesArray &t = *(OrbitalInfoTrk);
  OrbitalInfoTrkVar *orbtrack = (OrbitalInfoTrkVar*)t[itrk];
  return orbtrack;
}
/**
 * Retrieves the tof track matching the seqno-th tracker stored track. 
 * 
 */
OrbitalInfoTrkVar *OrbitalInfo::GetOrbitalInfoStoredTrack(int seqno){

  if( ntrk()==0 ){
    printf("OrbitalInfo::GetOrbitalInfoStoredTrack(int) : requested tracker SeqNo %i but no OrbitalInforimeter tracks are stored\n",seqno);
    return NULL;
  };
  
  OrbitalInfoTrkVar *c = 0;
  Int_t it_tof=0;
     
  do { 
    c = GetOrbitalInfoTrkVar(it_tof);
    it_tof++; 
  } while( c && seqno != c->trkseqno && it_tof < ntrk());	
  
  if(!c || seqno != c->trkseqno){
    c = 0;
    if(seqno!=-1 ) printf("OrbitalInfo::GetOrbitalInfoStoredTrack(int) : requested tracker SeqNo %i does not match OrbitalInfo stored tracks\n",seqno);
  };
  return c;
     
}

void OrbitalInfo::Clear(Option_t *t){
  //
  if ( OrbitalInfoTrk ) OrbitalInfoTrk->Delete();
  //
  absTime = 0;
  OBT = 0;
  pkt_num = 0;

  lon = -1000.;
  lat = -1000.;
  alt = -1000.;
  V.SetXYZ(-1000.,-1000.,-1000.);

  Bnorth = -1000.;
  Beast = -1000.;
  Bdown = -1000.;
  Babs = -1000.;
  M = -1000;
  BB0 = -1000.;
  L = -1000.;

   londip = -1000.;
   latdip = -1000.;

  //  std::fill_n(cutoff, 20, 0.);
  //  std::fill_n(cutoff, 2, 0.);
  cutoffsvl = 0.;

  // Quaternions
  q0 = -1000.;
  q1 = -1000.;
  q2 = -1000.;
  q3 = -1000.;

  // Euler angles (nadir reference frame)
  theta = -1000.;
  phi = -1000.;
  etha = -1000.;

  Iij.Zero();

  mode = 0;
  qkind = -1000;
  errq =  -1000;
  azim =  -1000;
  rtqual =-1000;
  //  std::fill_n(goodAttitude, 5, 0);
}

/**
 * Fills a struct cOrbitalInfo with values from a OrbitalInfo object (to put data into a F77 common).
 */
void OrbitalInfo::GetLevel2Struct(cOrbitalInfo *l2) const{
  l2->abstime  = absTime;
  l2->obt      = OBT;
  l2->pkt_num  = pkt_num;

  l2->lon = lon;
  l2->lat = lat;
  l2->alt = alt;
  l2->V = V;

  l2->Bnorth = Bnorth;
  l2->Beast = Beast;
  l2->Bdown = Bdown;
  l2->Babs = Babs;
  l2->M = M;
  l2->BB0 = BB0;
  l2->L = L;

   l2->londip = londip;
   l2->latdip = latdip;

  l2->cutoffsvl = cutoffsvl;
//  memcpy(l2->cutoffsvl, cutoffsvl, sizeof(cutoffsvl));

  // Quaternions
  l2->q0 = q0;
  l2->q1 = q1;
  l2->q2 = q2;
  l2->q3 = q3;

  // Euler angles (nadir reference frame)
  l2->theta = theta;
  l2->phi = phi;
  l2->etha = etha;

  l2->mode = mode;
  l2->qkind = qkind;
  l2->errq = errq;
  l2->azim = azim;
  l2->rtqual=rtqual;

  l2->Iij=Iij;

//   memcpy(l2->goodAttitude, goodAttitude, sizeof(goodAttitude));
}

void OrbitalInfo::SetFromLevel2Struct(cOrbitalInfo *l2){
  absTime  = l2->abstime;
  OBT      = l2->obt;
  pkt_num  = l2->pkt_num;

  lon = l2->lon;
  lat = l2->lat;
  alt = l2->alt;
  V = l2->V;

  Bnorth = l2->Bnorth;
  Beast = l2->Beast;
  Bdown = l2->Bdown;
  Babs = l2->Babs;
  M = l2->M;
  BB0 = l2->BB0;
  L = l2->L;

   londip = l2->londip;
   latdip = l2->latdip;

//  memcpy(cutoff, l2->cutoff, sizeof(l2->cutoff));
  l2->cutoffsvl = cutoffsvl;

  // Quaternions
  q0 = l2->q0;
  q1 = l2->q1;
  q2 = l2->q2;
  q3 = l2->q3;

  // Euler angles (nadir reference frame)
  theta = l2->theta;
  phi = l2->phi;
  etha = l2->etha;

  mode = l2->mode;
  qkind = l2->qkind;
  errq = l2->errq;
  azim = l2->azim;
  rtqual=l2->rtqual;

  Iij=l2->Iij;

//   memcpy(goodAttitude, l2->goodAttitude, sizeof(l2->goodAttitude));
}

