#include <NIDAQmx.h>
#include "SMMCVI6.h"
#include <easyio.h>
#include "SMMCVI5.h"
#include <ansi_c.h>
#include <dataacq.h>
#include <userint.h>
#include <formatio.h>
#include <utility.h>
#include <gpib.h>
#include "smmacq5.h" 

static int acqThreadFlush;
int HP834xB_write_data (int, char *str, int);
int wlt67XXB_write_data (int, char *str, int);
short int tempvolts[100000];
static int not;


  
/* local function prototypes */  
int GetIntensity(double *intens, double *auxfreq);

int updateScan(int updn, int indx, int ixend)
{   // set up scan parameters
//  SMMACQCMD acq;

  int waitread, i, temp;//new var temp added for time sweep logic
  temp = 0;				//new
  if (updn > 0){		
  	if (ixend < 0) {	//new
  		temp = 1;			//new
  		ixend = indx + 10;   //new
  	}						 //new
    if (indx > ixend) return -1;
    if (temp) ixend = -1;	   //new
    updn =  1; acqThreadFlush = 0;
  } else if (updn < 0) {
    if (indx < ixend) return -1;
    updn = -1; acqThreadFlush = 0;
  } else { /* updn == 0 */
    acqThreadFlush = 1;
    if (ixend >= 0) return 0;  /* ixend < 0 kills thread */
  }
  acq.updn = updn; acq.indx = indx; acq.ixend = ixend;
  acq.numvolts = numvolts; acq.numav = numav;
  //acqmxn.nnpage = NPage;
  CmtWriteTSQData (acqcmdTSQ, &acq, 1, TSQ_INFINITE_TIMEOUT, NULL);
  return updn;
}


int acqthread(void *dumy)
{ // mother function for data acquisition thread 
//  SMMACQCMD acq;
//  SMMACQDATA acqdata;

  char buffer[20], serpol;
  double synthPower, temp, temp2,tempf, KFac;
  float tempint, intint;
  float64 temp64[2];
  int i, j, t, nPts, len;
  //double gain;
  acq.updn = 0;
  for(;;){
    while (acq.updn == 0 || acqThreadFlush){
      CmtReadTSQData (acqcmdTSQ, &acq, 1, TSQ_INFINITE_TIMEOUT, NULL);
      if (acq.updn == 0) return 0;  /* terminate thread */
    }
     //bjd moved SetFreq discrete command into V/F or LIA cases
    if (NUMPTPI){
     SetFreq(acq.indx);
     temp = 0;
     GetIntensity (&temp, &acqdata.auxfreq);
     acqdata.intens = temp;
     temp2 = 0;
	 if (ZEEMAN){
	  //AOUpdateChannel (DAQNUM3, "0", zhi);
		DAQmxWriteAnalogF64(DAQHandle,1,1,1.0,DAQmx_Val_GroupByChannel, DAQdata,NULL,NULL);
		temp64[1] = DAQdata[1];
		temp64[0] = 0;
	  GetIntensity (&temp, &temp2);
	  acqdata.intens -= temp;
		DAQmxWriteAnalogF64(DAQHandle,1,1,1.0,DAQmx_Val_GroupByChannel, temp64,NULL,NULL);
//	  AOUpdateChannel (DAQNUM3, "0", zlow);
	 }//end if ZEEMAN

	Read_Voltages(acq.numvolts, acq.numav,  acqdata.voltage);

	/**********/
     acqdata.indx = acq.indx; 
     CmtWriteTSQData (acqdataTSQ, &acqdata, 1, TSQ_INFINITE_TIMEOUT, NULL);
     if (acq.indx == acq.ixend) 
      acq.updn = 0;
     else
      if (acq.ixend > -1) acq.indx += acq.updn;			//bjd add
    } else if (LIA){
     SetFreq(acq.indx);
     Delay (WaitCPUTime);
     ibwrt(LIAhandle, "OUTR?1", 6);  //reads channel 1 display 
     ibrd(LIAhandle, buffer, 20);
     sscanf(buffer, "%f", &tempint);
     acqdata.intens = 10000*tempint/sensitivity;


	if (ZEEMAN){
	  //AOUpdateChannel (DAQNUM3, "0", zhi);
      	DAQmxWriteAnalogF64(DAQHandle,1,1,1.0,DAQmx_Val_GroupByChannel,DAQdata,NULL,NULL);
		temp64[1] = DAQdata[1];
		temp64[0] = 0;
	  Delay (WaitCPUTime);
      ibwrt(LIAhandle, "OUTR?1", 6);  //reads channel 1 display 
      ibrd(LIAhandle, buffer, 20);
      sscanf(buffer, "%f", &tempint);
      acqdata.intens -= 10000*tempint/sensitivity;
	  //AOUpdateChannel (DAQNUM3, "0", zlow);
	 	DAQmxWriteAnalogF64(DAQHandle,1,1,1.0,DAQmx_Val_GroupByChannel,temp64,NULL,NULL);

	}

	Read_Voltages(acq.numvolts, acq.numav,  acqdata.voltage);

    /**********/
     acqdata.indx = acq.indx; 
     CmtWriteTSQData (acqdataTSQ, &acqdata, 1, TSQ_INFINITE_TIMEOUT, NULL);
     if (acq.indx == acq.ixend) 
       acq.updn = 0;
     else
       if (acq.ixend > -1) acq.indx += acq.updn;  //bjd add
    }


  }
  return 0;
}

void Read_Voltages(int numv, int numa, double *voltages)
{
int i, j, k, NN;

	DAQmxReadAnalogF64 (DAQInputs, numa, 1.0, DAQmx_Val_GroupByScanNumber, voltages, numa*numv, &NN, 0);
	k = 0;
	for (i = 0; i < 8; ++i){
    	if (gain[i]) {
		 for (j = 1; j < numa; ++j){
		    voltages[k] += voltages[k+j*numv];//put sum into first set	 
    	 }
    	 voltages[k] /= numa;		  //create average
		 ++k;
		} 
    }	
	
}

void SetFreq (int ipt)
{     
  char buf[35];
  double synthNow, temp, tempvolts;
  
  synthNow = synthStart + ipt * synthStep;

  //if (Exp < 4 ){ try to get action from setup buttons while in video mode
  if (Exp < 4 || ipt == 0){
 
   if (synthID == WILTRON){
    Fmt (buf, "%s<F1 %f[p0]KH", synthNow);
   } else {
     Fmt (buf, "%s<CW%f[p0]HZ", synthNow);
   }
   PutSynth(buf, NumFmtdBytes());
   }
   
  else if (Exp == 4){//must use kHz for both synthesizers
   synthNow = synthStart + ipt * synthStep; 
   if (synthID == WILTRON){
    Fmt (buf, "%s<F1 %f[p0]KH", synthNow);
   } else {
     Fmt (buf, "%s<CW%f[p0]KZ", synthNow);
   }
   PutSynth(buf, NumFmtdBytes());
   //synthNow = synthStart - synthOffset + ipt * synthStep;
   synthNow =  synthHarm*(synthNow - synthOffset)/synthHarm2;
   if (synthID2 == WILTRON){
    Fmt (buf, "%s<F1 %f[p1]KH", synthNow);
   } else {
     Fmt (buf, "%s<CW%f[p1]KZ", synthNow);
   }
   PutSynth2(buf, NumFmtdBytes());
   
  } else if (Exp == 5){  //video mode?
	tempvolts = (double) ipt * 0.001 * synthHarm * synthStep/ModSen;
  	Fmt (buf, "%s<OFFS %f[p6]", tempvolts);
   	PutDS345(buf, NumFmtdBytes());	 
  }

/****tune YIG filter with measured polynomial for voltage***/
  if(yigfilt) {
  	//temp = 0.5882*((synthNow/1000000000) - 1)-.004;
   	temp = synthNow/1000000;//	  convert from Hz to MHz
   	/*			   if(temp >= 8055) {
			    temp =  0.0005519098*(temp-8055.41);
			   	
			   } else {
			    temp = 0;
			   }   */
   	temp = -2.004e-10*(temp*temp) + 0.00059254*temp - 0.6388;//0.5882*(temp/1000) - 0.5882;
	//AOUpdateChannel (DAQNUM, "0", temp);
	DAQdata[1] = temp;
	DAQmxWriteAnalogF64(DAQHandle,1,1,1.0,DAQmx_Val_GroupByChannel,DAQdata,NULL,NULL);

  }
  
/****tune synth analyzer to track RF or IF**/
  if (SAType == 1){
   Fmt (buf, "%s<CENTER %f[p3] HZ", synthNow);
   SACMD(buf);
  } else if (SAType == 2) {
   Fmt (buf, "%s<CENTER %f[p3] HZ", synthOffset);			   
   SACMD(buf);
  }
              

}



void LIACMD (char *str)
{
int check;
char serPol;
	 if (LIAhandle < 1) LIAhandle = ibfind("LIA");
	 check = iberr;
     //if (!LIAhandle) LIAhandle = ibdev (0, 8, NO_SAD, T10s, 1, 0); 
     if (LIAhandle > 0){
      ibwrt(LIAhandle, str, strlen(str));
      /*do {
        ibrsp(LIAhandle, &serPol);
        } while ((serPol&2)==0);*/
     }   
}

void SACMD (char *str)
{
int check;
char serPol;
	 if (SAhandle < 1) SAhandle = ibfind("ANALYZER");
	 check = iberr;
     if (SAhandle > 0){
      ibwrt(SAhandle, str, strlen(str));
     }   
}

void FGCMD (char *str)
{
     if (FG < 1) FG = ibfind("HPFG");
     //if (!FG) FG = ibdev (0, 25, NO_SAD, T10s, 1, 0); 
     if (FG > 0) ibwrt(FG, str, strlen(str));
}



void PutSynth(char *str, int len)
{
  int ret;
  if (synthHandle < 0) return;
  if (synthID == WILTRON){
    ret = ibwrt(synthHandle, str, len);
    if (ret > 7999) {
    MessagePopup ("WARNING", "Synthesizer not responding");
    }
  } else {
    ret = ibwrt(synthHandle, str, len);
    if (ret > 7999) {
    MessagePopup ("WARNING", "Synthesizer not responding");
    }
  }
}

void PutSynth2(char *str, int len)
{
  int ret;
  if (synthHandle2 < 0) return;
  if (synthID2 == WILTRON){
    ret = ibwrt(synthHandle2, str, len);
    if (ret > 7999) {
    MessagePopup ("WARNING", "Synthesizer 2 not responding");
    }
  } else {
    ret = ibwrt(synthHandle2, str, len);
    if (ret > 7999) {
    MessagePopup ("WARNING", "Synthesizer 2 not responding");
    }
  }
}

void PutLASER(char *str, int len)
{
  int ret;
  if (laserHandle < 0) return;
    ret = ibwrt(laserHandle, str, len);
    if (ret > 7999) MessagePopup ("WARNING", "LASER not responding");
}


void PutDS345(char *str, int len)
{
  int ret;
  if (ds345Handle < 0) return;
    ret = ibwrt(ds345Handle, str, len);
    if (ret > 7999) MessagePopup ("WARNING", "DS345 not responding");
}
int GetIntensity (double *intens, double *auxfreq)
{
  int bigword;
  *auxfreq = defFreq;
  outp (ADDC, 0xe9);/* set output counter 1 high */
  outp (ADDC, 0x7f);/* load and arm counter 1,2,3,4,5 */
  Delay (WaitCPUTime);
  if((inp (ADDC) & 2) == 0) { /* check for out1 low*/
    *intens = -10000.; return -1;
  }else{
    outp (ADDC, 0xbe);/* save counter 2,3,4,5 into hold register */      
    outp (ADDC, 023);/* pointer to hold register 3 */
    bigword  = inp (ADDD) & BMASK;
    bigword += (inp (ADDD) & BMASK) << 8;
    outp (ADDC, 022);/* pointer to hold register 2 */
    bigword  = (bigword << 16) + (inp (ADDD) & BMASK);
    bigword += (inp (ADDD) & BMASK) <<8;
    *intens = intenScale * bigword - 10000;
    outp (ADDC, 025);/* pointer to hold register 5 */
    bigword  = inp (ADDD) & BMASK;
    bigword += (inp (ADDD) & BMASK) << 8;
    outp (ADDC, 024);/* pointer to hold register 4 */
    bigword  = (bigword << 16) + (inp (ADDD) & BMASK);
    bigword += (inp (ADDD) & BMASK) <<8;
    if (bigword) *auxfreq = freqScale * bigword;
    return 0;
  }
}  



