/*
 *  ltdata.cpp
 *  lt
 *
 *  Created by Shane Saxon on 4/4/05.
 *
 *  Shane Saxon has waived all copyright and related or neighboring rights to
 *  "miniTweezers GUI". Published from the United States as Public Domain.
 *  Creative Commons License CC0 1.0 Universal.
 *
 *  Created by Shane Saxon with contributions by Steven Smith, Evan Sperber,
 *  and Josep-Maria Huguet.  Code base started in 2004.
 *
 *  To view the full license with a list of additional authors and to download or
 *  contribute code goto http://tweezerslab.unipr.it/license.html
 */

 #include <Carbon/Carbon.h>
#include "ltdata.h"

void	InitControlData(pData data)
{
	int i, j;
	
	data->control.upperCase = FALSE;						//should reset caps lock key, debug
	
	data->control.altColor = 0;
	
	data->control.mouseTrapSensitivity = 64;
	data->control.mouseMotorSensitivity = 64;
	
	for (i = 0; i < 6; i++)
		for (j = 0; j < kKeyMapSize; j++)
			data->control.keyMap[i][j] = 0;
			

	//the key map defines which command to execute for each key event
	//three types of fundamental keys, toggle, momentary, repeating
	//four event types generated, keyDown, KeyRepeat, KeyUp, KeyModifier
	
	//Fire keys, respond to keyDown only
	data->control.keyMap[kKeyDown][kKeyCodeTilda] = kGraphClear;
	data->control.keyMap[kKeyDown][kKeyCodeB] = kGraphClearFrameBuffer;
	data->control.keyMap[kKeyDown][kKeyCodeG] = kGraphGrid;
	data->control.keyMap[kKeyDown][kKeyCodeC] = kGraphCenter;
	data->control.keyMap[kKeyDown][kKeyCodeX] = kGraphScroll;
	data->control.keyMap[kKeyDown][kKeyCodeL] = kGraphLines;
	data->control.keyMap[kKeyDown][kKeyCodeP] = kGraphPoints;
	data->control.keyMap[kKeyDown][kKeyCodeU] = kGraphDrawPullLimits;
	data->control.keyMap[kKeyDown][kKeyCodeF] = kGraphFreeze;
	data->control.keyMap[kKeyDown][kKeyCodeH] = kGraphHide;
	data->control.keyMap[kKeyDown][kKeyCodeX] = kGraphSelectAxes;
	data->control.keyMap[kKeyDown][kKeyCodeT] = kGraphSampleInterval;
	data->control.keyMap[kKeyDown][kKeyCodeI] = kGraphDrawIndicators;

	data->control.keyMap[kKeyDown][kKeyCodeZero] = kEventGotoZero;
	data->control.keyMap[kKeyDown][kKeyCodeOne] = kEventGotoOne;
	data->control.keyMap[kKeyDown][kKeyCodeTwo] = kEventGotoTwo;
	data->control.keyMap[kKeyDown][kKeyCodeThree] = kEventGotoThree;
	data->control.keyMap[kKeyDown][kKeyCodeFour] = kEventGotoFour;
	data->control.keyMap[kKeyDown][kKeyCodeFive] =kEventGotoFive;
	data->control.keyMap[kKeyDown][kKeyCodeSix] = kEventGotoSix;
	data->control.keyMap[kKeyDown][kKeyCodeSeven] = kEventGotoSeven;
	data->control.keyMap[kKeyDown][kKeyCodeEight] = kEventGotoEight;
	data->control.keyMap[kKeyDown][kKeyCodeNine] =kEventGotoNine;

	data->control.keyMap[kKeyDown][kKeyCodeJ] = kEventAdjustForceRateDiv;
	data->control.keyMap[kKeyDown][kKeyCodeK] = kEventAdjustForceGain;
	data->control.keyMap[kKeyDown][kKeyCodeO] = kEventHostPositionFeedback;
	
	
	data->control.keyMap[kKeyDown][kKeyCodeLeftBracket] = kEventLowSetpoint;
	data->control.keyMap[kKeyDown][kKeyCodeRightBracket] = kEventHighSetpoint;
	
	//Repeat keys, don't usually respond to keyUp
	data->control.keyMap[kKeyDown][kKeyCodeEqual] = kGraphColorDown;		//reversed direction better for selectAll cycling
	data->control.keyMap[kKeyRepeat][kKeyCodeEqual] = kGraphColorDown;
	
	data->control.keyMap[kKeyDown][kKeyCodeMinus] = kGraphColorUp;
	data->control.keyMap[kKeyRepeat][kKeyCodeMinus] = kGraphColorUp;
	
	data->control.keyMap[kKeyDown][kKeyCodeComma] = kGraphChannelUp;		//reversed direction better for selectAll cycling
	data->control.keyMap[kKeyRepeat][kKeyCodeComma] = kGraphChannelUp;
	
	data->control.keyMap[kKeyDown][kKeyCodePeriod] = kGraphChannelDown;
	data->control.keyMap[kKeyRepeat][kKeyCodePeriod] = kGraphChannelDown;

	data->control.keyMap[kKeyDown][kKeyCodeTab] = kGraphNext;
	data->control.keyMap[kKeyRepeat][kKeyCodeTab] = kGraphNext;

	data->control.keyMap[kKeyDown][kKeyCodeN] = kGraphNew;
	data->control.keyMap[kKeyRepeat][kKeyCodeN] = kGraphNew;
	
	data->control.keyMap[kKeyDown][kKeyCodeDelete] = kGraphDelete;
	data->control.keyMap[kKeyRepeat][kKeyCodeDelete] = kGraphDelete;
	

	data->control.keyMap[kKeyDown][kKeyCodeArrowRight] = kEventMotorJogRight;
	data->control.keyMap[kKeyRepeat][kKeyCodeArrowRight] = kEventMotorJogRight;
		
	data->control.keyMap[kKeyDown][kKeyCodeArrowUp] = kEventMotorJogUp;
	data->control.keyMap[kKeyRepeat][kKeyCodeArrowUp] = kEventMotorJogUp;
	
	data->control.keyMap[kKeyDown][kKeyCodeArrowDown] = kEventMotorJogDown;
	data->control.keyMap[kKeyRepeat][kKeyCodeArrowDown] = kEventMotorJogDown;
	
	data->control.keyMap[kKeyDown][kKeyCodeArrowLeft] = kEventMotorJogLeft;
	data->control.keyMap[kKeyRepeat][kKeyCodeArrowLeft] = kEventMotorJogLeft;
	
	data->control.keyMap[kKeyDown][kKeyCodePageUp] = kEventMotorJogIn;
	data->control.keyMap[kKeyRepeat][kKeyCodePageUp] = kEventMotorJogIn;
	
	data->control.keyMap[kKeyDown][kKeyCodePageDown] = kEventMotorJogOut;
	data->control.keyMap[kKeyRepeat][kKeyCodePageDown] = kEventMotorJogOut;

	data->control.keyMap[kKeyDown][kKeyCodeEnd]	= kEventManualPause;	//SBS	
	
	data->control.keyMap[kKeyDown][kKeyCodeHome] = kEventManualReverse;		//SBS
	
	//Arrow keys for X,Y,Z translate, rotate and scale of selected objects
	data->control.keyMap[kKeyDown][kKeyCodeA] = kGraphXdecrease;
	data->control.keyMap[kKeyUp][kKeyCodeA] = kGraphXdecreaseOff;
	data->control.keyMap[kKeyDown][kKeyCodeD] = kGraphXincrease;
	data->control.keyMap[kKeyUp][kKeyCodeD] = kGraphXincreaseOff;

	data->control.keyMap[kKeyDown][kKeyCodeS] = kGraphYdecrease;
	data->control.keyMap[kKeyUp][kKeyCodeS] = kGraphYdecreaseOff;
	data->control.keyMap[kKeyDown][kKeyCodeW] = kGraphYincrease;
	data->control.keyMap[kKeyUp][kKeyCodeW] = kGraphYincreaseOff;

	//for rotating
	data->control.keyMap[kKeyDown][kKeyCodeE] = kGraphRotateIncreaseOn;
	data->control.keyMap[kKeyUp][kKeyCodeE] = kGraphRotateIncreaseOff;
	data->control.keyMap[kKeyDown][kKeyCodeQ] = kGraphRotateDecreaseOn;
	data->control.keyMap[kKeyUp][kKeyCodeQ] = kGraphRotateDecreaseOff;
	
	//Zooms by scaling the object
	data->control.keyMap[kKeyDown][kKeyCodeZ] = kGraphZoomOn;
	data->control.keyMap[kKeyUp][kKeyCodeZ] = kGraphZoomOff;
	
	data->control.keyMap[kKeyDown][kKeyCodeU] = kEventChangeWriteStatus;		//ENS
	data->control.keyMap[kKeyDown][kKeyCodeY] = kEventChangeWriteSpeed;			//ENS
	data->control.keyMap[kKeyDown][kKeyCodeSpace] = kEventShowTheTime;			//SBS
	data->control.keyMap[kKeyDown][kKeyCodeSemiColon] = kEventYFeedbackOnly;	//SBS
}


//////////////////////////////////////
void	InitQuickTime(pData data)
{
	int i, j;

	for (i = 0; i < 256; i++)
	{
		data->quicktime.byteFromTrapA[i] = 0;
		data->quicktime.wordFromTrapA[i] = 0;
		data->quicktime.byteFromTrapB[i] = 0;
		data->quicktime.wordFromTrapB[i] = 0;
	}

	for (i = 0; i < kRecentSize; i++)
		for (j = 0; j < kChannelCount; j++)
			data->quicktime.recent[i][j] = 0;

	for (i = 0; i < kChannelCount; i++)
	{
		data->quicktime.latest[i] = 0;
		data->quicktime.channelString[i] = "\0";
		data->quicktime.channelUnits[i] = "\0";
	}

	data->quicktime.recentIndex = 0;
	data->quicktime.mainFrequency = 4000;	//update using variables from comPIC
	data->quicktime.printCount = 0;

	data->quicktime.motorPosition.x = 0;
	data->quicktime.motorPosition.y = 0;
	data->quicktime.motorPosition.z = 0;
	
	//name our channels for display purposes
	data->quicktime.channelString[kChannelCycleCount] = "Cycle Count";
	data->quicktime.channelUnits[kChannelCycleCount] = "sec";
	data->quicktime.channelString[kChannelTrapAPsdX] = "A PsdX";
	data->quicktime.channelUnits[kChannelTrapAPsdX] = "";
	data->quicktime.channelString[kChannelTrapAPsdY] = "A PsdY";
	data->quicktime.channelUnits[kChannelTrapAPsdY] = "";
	data->quicktime.channelString[kChannelTrapAPsdSum] = "A PsdSum";
	data->quicktime.channelUnits[kChannelTrapAPsdSum] = "";
	data->quicktime.channelString[kChannelTrapAIris] = "A Iris";
	data->quicktime.channelUnits[kChannelTrapAIris] = "";
	data->quicktime.channelString[kChannelTrapALeverX] = "A LeverX";
	data->quicktime.channelUnits[kChannelTrapALeverX] = "";
	data->quicktime.channelString[kChannelTrapALeverY] = "A LeverY";
	data->quicktime.channelUnits[kChannelTrapALeverY] = "";
	data->quicktime.channelString[kChannelTrapALeverSum] = "A LeverSum";
	data->quicktime.channelUnits[kChannelTrapALeverSum] = "";
	
	data->quicktime.channelString[kChannelTrapBPsdX] = "B PsdX";
	data->quicktime.channelUnits[kChannelTrapBPsdX] = "";
	data->quicktime.channelString[kChannelTrapBPsdY] = "B PsdY";
	data->quicktime.channelUnits[kChannelTrapBPsdY] = "";
	data->quicktime.channelString[kChannelTrapBPsdSum] = "B PsdSum";
	data->quicktime.channelUnits[kChannelTrapBPsdSum] = "";
	data->quicktime.channelString[kChannelTrapBIris] = "B Iris";
	data->quicktime.channelUnits[kChannelTrapBIris] = "";
	data->quicktime.channelString[kChannelTrapBLeverX] = "B LeverX";
	data->quicktime.channelUnits[kChannelTrapBLeverX] = "";
	data->quicktime.channelString[kChannelTrapBLeverY] = "B LeverY";
	data->quicktime.channelUnits[kChannelTrapBLeverY] = "";
	data->quicktime.channelString[kChannelTrapBLeverSum] = "B LeverSum";
	data->quicktime.channelUnits[kChannelTrapBLeverSum] = "";
	
	data->quicktime.channelString[kChannelTrapATemp] = "A Temp";
	data->quicktime.channelUnits[kChannelTrapATemp] = "Celsius";
	data->quicktime.channelString[kChannelTrapBTemp] = "B Temp";
	data->quicktime.channelUnits[kChannelTrapBTemp] = "Celsius";
	
	data->quicktime.channelString[kChannelNetForceX] = "X force";
	data->quicktime.channelUnits[kChannelNetForceX] = "pN";
	data->quicktime.channelString[kChannelNetForceY] = "Y force";
	data->quicktime.channelUnits[kChannelNetForceY] = "pN";
	data->quicktime.channelString[kChannelNetForceZ] = "Z force";
	data->quicktime.channelUnits[kChannelNetForceZ] = "pN";
	data->quicktime.channelString[kChannelTension] = "Tension";
	data->quicktime.channelUnits[kChannelTension] = "pN";
	
	data->quicktime.channelString[kChannelTrapANormLeverX] = "A distance-X";
	data->quicktime.channelUnits[kChannelTrapANormLeverX] = "nm";
	data->quicktime.channelString[kChannelTrapANormLeverY] = "A distance-Y";
	data->quicktime.channelUnits[kChannelTrapANormLeverY] = "nm";
	data->quicktime.channelString[kChannelTrapBNormLeverX] = "B distance-X";
	data->quicktime.channelUnits[kChannelTrapBNormLeverX] = "nm";
	data->quicktime.channelString[kChannelTrapBNormLeverY] = "B distance-Y";
	data->quicktime.channelUnits[kChannelTrapBNormLeverY] = "nm";
	
	data->quicktime.channelString[kChannelMotorX] = "Motor X";		//JMH
	data->quicktime.channelUnits[kChannelMotorX] = "um";			//JMH
	data->quicktime.channelString[kChannelMotorY] = "Motor Y";		//JMH
	data->quicktime.channelUnits[kChannelMotorY] = "um";			//JMH
	data->quicktime.channelString[kChannelMotorZ] = "Motor Z";		//JMH
	data->quicktime.channelUnits[kChannelMotorZ] = "um";			//JMH
	
	data->quicktime.channelString[kChannelMotorVelocityX] = "Motor Velocity X";		
	data->quicktime.channelUnits[kChannelMotorVelocityX] = "um/sec";				
	data->quicktime.channelString[kChannelMotorVelocityY] = "Motor Velocity Y";		
	data->quicktime.channelUnits[kChannelMotorVelocityY] = "um/sec";				
	data->quicktime.channelString[kChannelMotorVelocityZ] = "Motor Velocity Z";		
	data->quicktime.channelUnits[kChannelMotorVelocityZ] = "um/sec";				
		
	data->quicktime.channelString[kChannelErrorComPIC] = "comPIC Err";
	data->quicktime.channelUnits[kChannelErrorComPIC] = "";
	data->quicktime.channelString[kChannelErrorTrapA] = "A trapPIC Err";
	data->quicktime.channelUnits[kChannelErrorTrapA] = "";
	data->quicktime.channelString[kChannelErrorTrapB] = "B trapPIC Err";
	data->quicktime.channelUnits[kChannelErrorTrapB] = "";
	data->quicktime.channelString[kChannelTrapACycleCount] = "A CycleCount";
	data->quicktime.channelUnits[kChannelTrapACycleCount] = "";
	data->quicktime.channelString[kChannelTrapBCycleCount] = "B CycleCount";
	data->quicktime.channelUnits[kChannelTrapBCycleCount] = "";
	data->quicktime.channelString[kChannelMotorCycleCount] = "Motor CycleCount";
	data->quicktime.channelUnits[kChannelMotorCycleCount] = "";
	data->quicktime.channelString[kChannelPICtime] = " main PIC time";	
	data->quicktime.channelUnits[kChannelPICtime] = "sec";	
	data->quicktime.channelString[kChannelTweezStatus] = "Status";	
	data->quicktime.channelUnits[kChannelTweezStatus] = "";	
	data->quicktime.channelString[kChannelNull] = "Null";
	data->quicktime.channelUnits[kChannelNull] = "zero";
}


void	InitInstrument(pData data)
{
	int i, j;
	
	data->instrument.name = 0;
	
	for (i = 0; i < kInstrumentReadBufferSize; i++)
		data->instrument.readBuffer[i] = 0;	
	
	for (i = 0; i < kInstrumentWriteBufferSize; i++)
		data->instrument.writeBuffer[i] = 0;

	for (i = 0; i < kCommandBufferSize; i++)
		for (j = 0; j < kInstrumentWriteBufferSize; j++)
			data->instrument.commandBuffer[i][j] = 0;

	data->instrument.readBufferIndex = 0;
	data->instrument.readBufferEndIndex = 0;
	data->instrument.commandBufferIndex = 0;
	data->instrument.commandBufferSentIndex = 0;
	data->instrument.sendCommand = 0;
	data->instrument.LED = TRUE;
	
	data->instrument.moveTrap = FALSE;
	data->instrument.trapA = FALSE;
	data->instrument.trapAB = TRUE;
	data->instrument.trapB = FALSE;
	data->instrument.moveMotors = FALSE;

	data->instrument.motorAxes.x = TRUE;
	data->instrument.motorAxes.y = TRUE;
	data->instrument.motorAxes.z = TRUE;
	
	data->instrument.jogDuration = 2;
	
	data->instrument.motorGain.x = 1.5;
	data->instrument.motorGain.y = 1.5;
	data->instrument.motorGain.z = 1.5;
	
	data->instrument.motorThreshold.x = data->instrument.calibXYZint[kMotorThresh].value.x;	
	data->instrument.motorThreshold.y = data->instrument.calibXYZint[kMotorThresh].value.y;	
	data->instrument.motorThreshold.z = data->instrument.calibXYZint[kMotorThresh].value.z;	
	
	data->instrument.trapAxes.x = TRUE;
	data->instrument.trapAxes.y = TRUE;
	data->instrument.trapAxes.z = FALSE;
	data->instrument.hopping = FALSE;
	data->instrument.functionGeneratorOn = FALSE;
	data->instrument.zeroingPSDs = FALSE;
	data->instrument.zeroingForce = FALSE;
	data->instrument.manualPausing = FALSE;		
	data->instrument.rasteringMotors = FALSE;		
	data->instrument.zeroingPSDsCount = 0;
	data->instrument.zeroingForceCount = 0;
	data->instrument.hostPositionFeedbackOn = 0;
	data->instrument.smoothingNum  = 4.0;

	
	data->instrument.trapAZeroingPSDsSum.x = 0.0;
	data->instrument.trapAZeroingPSDsSum.y = 0.0;
	data->instrument.trapAZeroingPSDsSum.z = 0.0;
	
	data->instrument.trapBZeroingPSDsSum.x = 0.0;
	data->instrument.trapBZeroingPSDsSum.y = 0.0;
	data->instrument.trapBZeroingPSDsSum.z = 0.0;
	
	data->instrument.zeroingForceSum.x = 0.0;
	data->instrument.zeroingForceSum.y = 0.0;
	data->instrument.zeroingForceSum.z = 0.0;
	
	data->instrument.writeBufferEndIndex = kInstrumentWriteBufferSize - 1;

	data->instrument.motorMicroMeterConversion = 1.0;
	
	data->instrument.forceOffset.x = 0.0;
	data->instrument.forceOffset.y = 0.0;
	data->instrument.forceOffset.z = 0.0;

	/*ENS
	data->instrument.trapAForceSensitivity.x = 0.0066;
	data->instrument.trapAForceSensitivity.y = 0.0066;
	data->instrument.trapAForceSensitivity.z = 0.0030;
	
	data->instrument.trapBForceSensitivity.x = 0.0066;
	data->instrument.trapBForceSensitivity.y = 0.0066;
	data->instrument.trapBForceSensitivity.z = 0.0030;
	*/
	
	data->instrument.trapAForceSensitivity.x = data->instrument.calibXYZfloat[kTrapAForceSens].value.x;	//ENS
	data->instrument.trapAForceSensitivity.y = data->instrument.calibXYZfloat[kTrapAForceSens].value.y;	//ENS
	data->instrument.trapAForceSensitivity.z = data->instrument.calibXYZfloat[kTrapAForceSens].value.z;	//ENS
	
	data->instrument.trapBForceSensitivity.x = data->instrument.calibXYZfloat[kTrapBForceSens].value.x;	//ENS
	data->instrument.trapBForceSensitivity.y = data->instrument.calibXYZfloat[kTrapBForceSens].value.y;	//ENS
	data->instrument.trapBForceSensitivity.z = data->instrument.calibXYZfloat[kTrapBForceSens].value.z;	//ENS
	
	/*ENS
	data->instrument.trapALeverSensitivity.x = 9400;
	data->instrument.trapALeverSensitivity.y = 9400;
	*/
	
	data->instrument.trapALeverSensitivity.x = data->instrument.calibXYZfloat[kTrapALevSens].value.x;	//ENS
	data->instrument.trapALeverSensitivity.y = data->instrument.calibXYZfloat[kTrapALevSens].value.y;	//ENS
	
	data->instrument.trapALeverOffset.x = 0.0;
	data->instrument.trapALeverOffset.y = 0.0;
	
	/*ENS
	data->instrument.trapBLeverSensitivity.x = 9400;
	data->instrument.trapBLeverSensitivity.y = 9400;
	*/
	
	data->instrument.trapBLeverSensitivity.x = data->instrument.calibXYZfloat[kTrapBLevSens].value.x;	//ENS
	data->instrument.trapBLeverSensitivity.y = data->instrument.calibXYZfloat[kTrapBLevSens].value.y;	//ENS
	
	data->instrument.trapBLeverOffset.x = 0.0;	
	data->instrument.trapBLeverOffset.y = 0.0;
	
	data->instrument.trapATempFudge = data->instrument.calibFloat[kTrapATempFudge].value;	//SBS
	data->instrument.trapBTempFudge = data->instrument.calibFloat[kTrapBTempFudge].value;
	data->instrument.tempTime = 0.0;
	
	data->instrument.runMode = kAllOff;	//SBS
	data->instrument.maxPosition = 20000.0;	//SBS
	data->instrument.minPosition = -20000;	//SBS
	data->instrument.maxForce = 0.0;	//SBS
	data->instrument.minForce = 0.0;	//SBS		
	data->instrument.pullRate = 0;		//SBS		
	data->instrument.maxPositionOn = FALSE;		//SBS
	data->instrument.minPositionOn = FALSE;		//SBS
	data->instrument.absPositionX = 0;		//SBS
	data->instrument.absPositionY = 0;		//SBS
	data->instrument.psdSumEmptyA = 0;	//SBS
	data->instrument.psdSumEmptyB = 0;	//SBS
	data->instrument.irisEmptyA = 0;	//SBS
	data->instrument.irisEmptyB = 0;	//SBS
	data->instrument.psdSumFullA = 0;	//SBS
	data->instrument.psdSumFullB = 0;	//SBS
	data->instrument.irisFullA = 0;		//SBS
	data->instrument.irisFullB = 0;		//SBS
	
			
	data->instrument.fakeDistance = 900; //used by FunctionGenerator	
}


void	InitOpenGL(pData data)
{
	data->gl.threadRef = 0;
}


//ENS
void InitCFileData( pData data )
{
	data->cFileData.commentsString = (char*)malloc( 512 );
	//data->cFileData.customEventString = (char*)malloc( 512 );
	data->cFileData.updateCommentsFile = 0;
}

//ENS
void InitDFileData( pData data )
{
	int i;
	
	data->dFileData.dFilePath = (char*)malloc( 64 );
	memset( data->dFileData.dFilePath, 0, strlen( data->dFileData.dFilePath ) );
	
	data->dFileData.dFileIsOpen = 0;
	
	data->dFileData.setWriteSpeedFastOnNextCycle = 0;
	data->dFileData.setWriteSpeedSlowOnNextCycle = 0;
	
	data->dFileData.ccNumRollover = 0;
	data->dFileData.ccOffset = 0;
	data->dFileData.ccOffsetIsSet = 0;
		
	//Number of data packets per data point
	//data->dFileData.n = kNHigh;	//Initialize to slow write state
	data->instrument.nHigh;
	
	data->dFileData.currentWriteState = kNotWriting;

	data->dFileData.dFileChannelString[kChannelCycleCount] =      "CycleCount/n";
	data->dFileData.dFileChannelFormat[kChannelCycleCount] =      "%0.0f";
	data->dFileData.dFileChannelString[kChannelTrapAPsdX] =	      "A_PsdX";
	data->dFileData.dFileChannelFormat[kChannelTrapAPsdX] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelTrapAPsdY] =       "A_PsdY";
	data->dFileData.dFileChannelFormat[kChannelTrapAPsdY] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelTrapAPsdSum] =     "A_PsdSum";
	data->dFileData.dFileChannelFormat[kChannelTrapAPsdSum] =     "%0.2f";
	data->dFileData.dFileChannelString[kChannelTrapAIris] =       "A_Iris";
	data->dFileData.dFileChannelFormat[kChannelTrapAIris] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelTrapALeverX] =     "A_LeverX";
	data->dFileData.dFileChannelFormat[kChannelTrapALeverX] =     "%0.2f";
	data->dFileData.dFileChannelString[kChannelTrapALeverY] =     "A_LeverY";
	data->dFileData.dFileChannelFormat[kChannelTrapALeverY] =     "%0.2f";
	data->dFileData.dFileChannelString[kChannelTrapALeverSum] =   "A_LeverSum";
	data->dFileData.dFileChannelFormat[kChannelTrapALeverSum] =   "%0.2f";
	data->dFileData.dFileChannelString[kChannelTrapBPsdX] =       "B_PsdX";
	data->dFileData.dFileChannelFormat[kChannelTrapBPsdX] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelTrapBPsdY] =       "B_PsdY";
	data->dFileData.dFileChannelFormat[kChannelTrapBPsdY] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelTrapBPsdSum] =     "B_PsdSum";
	data->dFileData.dFileChannelFormat[kChannelTrapBPsdSum] =     "%0.2f";
	data->dFileData.dFileChannelString[kChannelTrapBIris] =       "B_Iris";
	data->dFileData.dFileChannelFormat[kChannelTrapBIris] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelTrapBLeverX] =     "B_LeverX";
	data->dFileData.dFileChannelFormat[kChannelTrapBLeverX] =     "%0.2f";
	data->dFileData.dFileChannelString[kChannelTrapBLeverY] =     "B_LeverY";
	data->dFileData.dFileChannelFormat[kChannelTrapBLeverY] =     "%0.2f";
	data->dFileData.dFileChannelString[kChannelTrapBLeverSum] =   "B_LeverSum";
	data->dFileData.dFileChannelFormat[kChannelTrapBLeverSum] =   "%0.2f";
	data->dFileData.dFileChannelString[kChannelTrapATemp] =       "A_Temperature";
	data->dFileData.dFileChannelFormat[kChannelTrapATemp] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelTrapBTemp] =       "B_Temperature";
	data->dFileData.dFileChannelFormat[kChannelTrapBTemp] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelNetForceX] =       "X_force";
	data->dFileData.dFileChannelFormat[kChannelNetForceX] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelNetForceY] =       "Y_force";
	data->dFileData.dFileChannelFormat[kChannelNetForceY] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelNetForceZ] =       "Z_force";
	data->dFileData.dFileChannelFormat[kChannelNetForceZ] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelTension] =         "Tension";
	data->dFileData.dFileChannelFormat[kChannelTension] =         "%0.2f";
	data->dFileData.dFileChannelString[kChannelTrapANormLeverX] = "A_dist-X";
	data->dFileData.dFileChannelFormat[kChannelTrapANormLeverX] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelTrapANormLeverY] = "A_dist-Y";
	data->dFileData.dFileChannelFormat[kChannelTrapANormLeverY] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelTrapBNormLeverX] = "B_dist-X";
	data->dFileData.dFileChannelFormat[kChannelTrapBNormLeverX] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelTrapBNormLeverY] = "B_dist-Y";
	data->dFileData.dFileChannelFormat[kChannelTrapBNormLeverY] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelMotorX] =          "Motor_X";
	data->dFileData.dFileChannelFormat[kChannelMotorX] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelMotorY] =          "Motor_Y";
	data->dFileData.dFileChannelFormat[kChannelMotorY] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelMotorZ] =          "Motor_Z";
	data->dFileData.dFileChannelFormat[kChannelMotorZ] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelMotorVelocityX] =  "MotorVel_X";
	data->dFileData.dFileChannelFormat[kChannelMotorVelocityX] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelMotorVelocityY] =  "MotorVel_Y";
	data->dFileData.dFileChannelFormat[kChannelMotorVelocityY] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelMotorVelocityZ] =  "MotorVel_Z";
	data->dFileData.dFileChannelFormat[kChannelMotorVelocityZ] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelErrorComPIC] =     "comPIC_Err";
	data->dFileData.dFileChannelFormat[kChannelErrorComPIC] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelErrorTrapA] =      "A_trapPIC_Err";
	data->dFileData.dFileChannelFormat[kChannelErrorTrapA] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelErrorTrapB] =      "B_trapPIC_Err";
	data->dFileData.dFileChannelFormat[kChannelErrorTrapB] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelTrapACycleCount] = "A_CycleCount";
	data->dFileData.dFileChannelFormat[kChannelTrapACycleCount] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelTrapBCycleCount] = "B_CycleCount";
	data->dFileData.dFileChannelFormat[kChannelTrapBCycleCount] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelMotorCycleCount] = "Motor_CycleCount";
	data->dFileData.dFileChannelFormat[kChannelMotorCycleCount] =       "%0.2f";
	data->dFileData.dFileChannelString[kChannelPICtime]     =	  "time(sec)";	//SBS
	data->dFileData.dFileChannelFormat[kChannelPICtime] =	"%0.3f";		//SBS
	data->dFileData.dFileChannelString[kChannelTweezStatus]     = "Status";	//SBS
	data->dFileData.dFileChannelFormat[kChannelTweezStatus] =	"%0.0f";		//SBS
	data->dFileData.dFileChannelString[kChannelNull]            = "Null";
	data->dFileData.dFileChannelFormat[kChannelNull] =       "%0.2f";
	
	//Locate user's home directory :: http://developer.apple.com/samplecode/CFPrefTopScores/listing1.html
	//This requires Carbon/Carbon.h so we might want to move it somewhere else.
	
	OSStatus status = noErr;
	
	FSRef homeFSRef;
	if( noErr == status ) {
		status = FSFindFolder( kUserDomain, kDomainTopLevelFolderType, TRUE, &homeFSRef );
	}
	
	//Convert homeFSRef to a C-string
	
	char homePath[PATH_MAX];
	if( noErr == status ){
		status = FSRefMakePath( &homeFSRef, ( UInt8 * )homePath, sizeof( homePath ) );
	}
	
	data->dFileData.prefFilePath = (char*)malloc(PATH_MAX);
	strcpy( data->dFileData.prefFilePath, homePath );
	strcat( data->dFileData.prefFilePath, "/pref" );
	printf( "%s\n", data->dFileData.prefFilePath );
}
/////////////////////////////////////////////////////////////	//SBS
int defaultInteger( void* dataRef, int index )
{
	pData data = (pData) dataRef;
	int temp;
	switch (index)
		{
		case kForceRateDivider:	temp = 1;  break;
		case kForceGain:	temp = 32; break;
		case kPositionRateDivA: temp = 3; break;
		case kPositionRateDivB: temp = 3; break;
		case kPositionGainA: temp = 32; break;
		case kPositionGainB: temp = 32; break;
		case kGotoSpeedX:	temp = 10; break;
		case kGotoSpeedY:	temp = 10; break;
		case kGotoSpeedZ:	temp = 5; break;
		case kMaxDataFileSize: temp = 10000000; break;
		case kHopDistance:  temp = 60; break;  
		default : temp = 0; break;
		};
	return(temp);
}
/////////////////////////////////////////////////////////	//SBS
XYZinteger defaultXYZint( void* dataRef, int index )
{	
	pData data = (pData) dataRef;
	XYZinteger nullVector, temp;	
	nullVector.x = 0;  nullVector.y = 0;  nullVector.z = 0;
	switch (index)
		{
		case kYourXYZint : temp.x = 123; temp.y = 456; temp.z = 789; break;	//example
		default: temp = nullVector; break;
		};
	return(temp);
}
//////////////////////////////////////////////////////////
float defaultFloat( void* dataRef, int index )
{	
	pData data = (pData) dataRef;
	float temp;	
	switch (index)
		{
		case kYourFloat: temp = 1.234;	break;	//example
		default : temp = 0.0; break;
		};
	return(temp);
}
/////////////////////////////////////////////////////////
XYZfloat defaultXYZfloat( void* dataRef, int index )
{	
	pData data = (pData) dataRef;
	XYZfloat nullVector, temp;	
	nullVector.x = 0.0;  nullVector.y = 0.0;  nullVector.z = 0.0;
	switch (index)
		{
		case kYourXYZfloat : temp.x = 1.0; temp.y = 2.0; temp.z = 3.0; break;	//example
		default: temp = nullVector; break;
		};
	return(temp);
}

//////////////////////////////////////////////////////////	//SBS
void loadDefaultUserVariables( void* dataRef )
{	// to allocate space, associate string label with variable name, set initial values
	int i, j;

	pData data = (pData) dataRef;
	
	for( i = 0; i < kUserXYZintSize; i++ ) // initialize XYZinteger variables
	{	data->instrument.userXYZinteger[i].label = (char*)malloc( 15 );
	  	data->instrument.userXYZinteger[i].value = defaultXYZint(data,i);	}		
			//initialize userXYZinteger labels
	sprintf( data->instrument.userXYZinteger[kGoto0].label, "goto0" ); //motor locations
	sprintf( data->instrument.userXYZinteger[kGoto1].label, "goto1" );
	sprintf( data->instrument.userXYZinteger[kGoto2].label, "goto2" );
	sprintf( data->instrument.userXYZinteger[kGoto3].label, "goto3" );
	sprintf( data->instrument.userXYZinteger[kGoto4].label, "goto4" );
	sprintf( data->instrument.userXYZinteger[kGoto5].label, "goto5" );
	sprintf( data->instrument.userXYZinteger[kGoto6].label, "goto6" );
	sprintf( data->instrument.userXYZinteger[kGoto7].label, "goto7" );
	sprintf( data->instrument.userXYZinteger[kGoto8].label, "goto8" );
	sprintf( data->instrument.userXYZinteger[kGoto9].label, "goto9" );
	sprintf( data->instrument.userXYZinteger[kYourXYZint].label,"yourXYZint");	//example
	
	for (i = 0; i < kUserIntSize; i++)	// initialize integer variables
	{	data->instrument.userInteger[i].label = (char*)malloc( 15 );
		data->instrument.userInteger[i].value = defaultInteger(data,i);	}		
					//initialize userInt labels
	sprintf( data->instrument.userInteger[kForceRateDivider].label,"ForceRateDiv");
	sprintf( data->instrument.userInteger[kForceGain].label, "ForceGain" );
	sprintf( data->instrument.userInteger[kPositionRateDivA].label,"PosRateDivA");
	sprintf( data->instrument.userInteger[kPositionRateDivB].label,"PosRateDivB");
	sprintf( data->instrument.userInteger[kPositionGainA].label, "PositionGainA" );
	sprintf( data->instrument.userInteger[kPositionGainB].label, "PositionGainB" );
	sprintf( data->instrument.userInteger[kGotoSpeedX].label, "GotoSpeedX" );
	sprintf( data->instrument.userInteger[kGotoSpeedY].label, "GotoSpeedY" );
	sprintf( data->instrument.userInteger[kGotoSpeedZ].label, "GotoSpeedZ" );
	sprintf( data->instrument.userInteger[kMaxDataFileSize].label, "MaxDataFileSize" );
	sprintf( data->instrument.userInteger[kHopDistance].label, "HopDistance" );
	
	
	for (i = 0; i < kUserFloatSize; i++)	// initialize float variables
	{	data->instrument.userFloat[i].label = (char*)malloc( 15 );
		data->instrument.userFloat[i].value = defaultFloat(data,i);	}		
					//initialize userFloat labels
	sprintf( data->instrument.userFloat[kMaxForceP1].label,  "MaxForceP1");
	sprintf( data->instrument.userFloat[kMinForceP1].label,  "MinForceP1");	
	sprintf( data->instrument.userFloat[kPullRateP1].label,  "PullRateP1");	
	sprintf( data->instrument.userFloat[kRefoldTime1].label,"refoldTime1");	
	sprintf( data->instrument.userFloat[kMaxForceP2].label,  "MaxForceP2");
	sprintf( data->instrument.userFloat[kMinForceP2].label,  "MinForceP2");	
	sprintf( data->instrument.userFloat[kPullRateP2].label,  "PullRateP2");	
	sprintf( data->instrument.userFloat[kRefoldTime2].label,"refoldTime2");	
	sprintf( data->instrument.userFloat[kMaxForceP3].label,  "MaxForceP3");
	sprintf( data->instrument.userFloat[kMinForceP3].label,  "MinForceP3");	
	sprintf( data->instrument.userFloat[kPullRateP3].label,  "PullRateP3");	
	sprintf( data->instrument.userFloat[kRefoldTime3].label,"refoldTime3");		
	sprintf( data->instrument.userFloat[kconstForce1].label,"constForce1");	
	sprintf( data->instrument.userFloat[kconstForce2].label,"constForce2");	
	sprintf( data->instrument.userFloat[kYourFloat].label,"yourFloat");
	
	for( i = 0; i < kChannelCount; i++ )
	{
		data->instrument.userInteger[kUserIntSize + i].label = (char*)malloc( 18 );
		sprintf( data->instrument.userInteger[kUserIntSize + i].label, "*%s", data->dFileData.dFileChannelString[i] );
		
		if( strlen( data->dFileData.dFileChannelString[i] ) < 16 )
		{
			for( j = 0; j < 16 - strlen( data->dFileData.dFileChannelString[i] ); j++ )
				strcat( data->instrument.userInteger[kUserIntSize + i].label, "_" );
		}
	
	}
	
	for (i = 0; i < kUserXYZfloatSize; i++)		// initialize XYZfloat userVars
	{	data->instrument.userXYZfloat[i].label = (char*)malloc( 15 );
		data->instrument.userXYZfloat[i].value = defaultXYZfloat(data,i);	}	
	sprintf (data->instrument.userXYZfloat[kYourXYZfloat].label,  "yourXYZfloat");
	
	data->instrument.userInteger[kUserIntSize + kChannelCount + kNHigh].label = (char*)malloc(24);
	sprintf( data->instrument.userInteger[kUserIntSize + kChannelCount + kNHigh].label, "samples/line_HI" );
	data->instrument.userInteger[kUserIntSize + kChannelCount + kNHigh].value = 400;
	
	data->instrument.userInteger[kUserIntSize + kChannelCount + kNLow].label = (char*)malloc(24);
	sprintf( data->instrument.userInteger[kUserIntSize + kChannelCount + kNLow].label, "samples/line_LO" );
	data->instrument.userInteger[kUserIntSize + kChannelCount + kNLow].value = 20;
						
}
//////////////////////////////////////////////////////////	//SBS
void InitUserVariables( void* dataRef )
{	
	int i;
	int err;	
	pData data = (pData) dataRef;
	loadDefaultUserVariables(data);
					// load default values into user-accessable variables
	err = ltFileIO(data, kPrefRead ); 
					// read PREF file and overwrite variables when present
					
	data->control.mouseMotorSensitivity = data->instrument.userInteger[kGotoSpeedX].value;	
	
	for( i = 0; i < kChannelCount; i++ )
	data->dFileData.dFileActiveChannels[i] = data->instrument.userInteger[kUserIntSize + i].value;
		
	data->dFileData.dFileHighestActiveChannel = 0;
	for( i = 0; i < kChannelCount; i++ )
	{
		if( data->dFileData.dFileActiveChannels[i] == 1 )
			data->dFileData.dFileHighestActiveChannel = i;
	}
	
	data->instrument.nHigh = data->instrument.userInteger[kUserIntSize + kChannelCount + kNHigh].value;
	data->instrument.nLow = data->instrument.userInteger[kUserIntSize + kChannelCount + kNLow].value;
	
	if( data->dFileData.currentWriteState == kWritingFast )		//ENS
		data->dFileData.n = data->instrument.nLow;
	else
		data->dFileData.n = data->instrument.nHigh;
	
}

///////////////////////////////////////////////////////////// //ENS
void InitCalibVariables( void* dataRef )
{
	int err;
	pData data = (pData) dataRef;
	
	loadDefaultCalibVariables( data );
	err = ltFileIO( data, kCalibRead );
}

/////////////////////////////////////////////////////////////	//ENS
void loadDefaultCalibVariables( void* dataRef )
{	// Close enough so the software will run. 
	// Intended to be overwritten by values from ltCalibration file that are specific to optics device.
	pData data = (pData) dataRef;
	
	data->instrument.deviceName = (char*)malloc( 64 );	
	data->instrument.deviceName = "Unknown...use calibration defaults"; //will overwrite with name from calibration file
	
	data->instrument.calibFloat[kTrapATempFudge].label = (char*)malloc( 64 );
	sprintf( data->instrument.calibFloat[kTrapATempFudge].label, "TrapA Temperature Fudge" );
	data->instrument.calibFloat[kTrapATempFudge].value= 0.0;

	data->instrument.calibFloat[kTrapBTempFudge].label = (char*)malloc( 64 );
	sprintf( data->instrument.calibFloat[kTrapBTempFudge].label, "TrapB Temperature Fudge" );
	data->instrument.calibFloat[kTrapBTempFudge].value= 0.0;

	data->instrument.calibXYZfloat[kTrapAForceSens].label = (char*)malloc( 64 );
	sprintf( data->instrument.calibXYZfloat[kTrapAForceSens].label, "TrapA Force Sensitivity" );
	data->instrument.calibXYZfloat[kTrapAForceSens].value.x= 0.007;
	data->instrument.calibXYZfloat[kTrapAForceSens].value.y = 0.007;
	data->instrument.calibXYZfloat[kTrapAForceSens].value.z = 0.003;
	
	data->instrument.calibXYZfloat[kTrapBForceSens].label = (char*)malloc( 64 );
	sprintf( data->instrument.calibXYZfloat[kTrapBForceSens].label, "TrapB Force Sensitivity" );
	data->instrument.calibXYZfloat[kTrapBForceSens].value.x = 0.007;
	data->instrument.calibXYZfloat[kTrapBForceSens].value.y = 0.007;
	data->instrument.calibXYZfloat[kTrapBForceSens].value.z = 0.003;
	
	data->instrument.calibXYZint[kMotorThresh].label = (char*)malloc( 64 );
	sprintf( data->instrument.calibXYZint[kMotorThresh].label, "Motor Threshold" );
	data->instrument.calibXYZint[kMotorThresh].value.x = 20;
	data->instrument.calibXYZint[kMotorThresh].value.y = 20;
	data->instrument.calibXYZint[kMotorThresh].value.z = 20;
	
	data->instrument.calibXYZfloat[kTrapALevSens].label = (char*)malloc( 64 );
	sprintf( data->instrument.calibXYZfloat[kTrapALevSens].label, "TrapA Lever Sensitivity" );
	data->instrument.calibXYZfloat[kTrapALevSens].value.x = 9000;
	data->instrument.calibXYZfloat[kTrapALevSens].value.y = 9000;
	
	data->instrument.calibXYZfloat[kTrapBLevSens].label = (char*)malloc( 64 );
	sprintf( data->instrument.calibXYZfloat[kTrapBLevSens].label, "TrapB Lever Sensitivity" );
	data->instrument.calibXYZfloat[kTrapBLevSens].value.x = 9000;
	data->instrument.calibXYZfloat[kTrapBLevSens].value.y = 9000;
}

void InitData (pData data)
{
	InitControlData (data);
	InitQuickTime (data);
	InitCalibVariables( data );		//ENS
	InitInstrument (data);
	InitOpenGL (data);
	InitDFileData( data );		//ENS
	InitUserVariables( data );	
	InitCFileData( data );		//ENS
}

/*
void UpdateNIB(void* data)
{
//	data.readBufferIndex++;
}
*/