Files
Work/aladin/aladin.cpp
2024-08-07 09:12:07 -04:00

294 lines
9.1 KiB
C++

#include <aladin/aladin.hpp>
#include <aladin/appreg.hpp>
#include <aladin/bitmanip.hpp>
#include <worksht/worksht.hpp>
#include <common/file.hpp>
#include <common/openfile.hpp>
#include <common/array.hpp>
#include <common/console.hpp>
#include <commctrl/commctrl.hpp>
#include <commctrl/fmtlines.hpp>
#include <common/guiwnd.hpp>
#include <common/progress.hpp>
Aladin::Aladin()
: mIsOkay(false)
{
mRawData.size(2046);
}
Aladin::~Aladin()
{
}
bool Aladin::openRaw(const String &strPathFileName)
{
BYTE header[4];
FileHandle inFile;
if(!inFile.open(strPathFileName,FileHandle::Read,FileHandle::ShareRead,FileHandle::Open,FileHandle::Normal))return false;
if(inFile.size()!=mRawData.size()+sizeof(header))return false;
if(!inFile.read(header,sizeof(header)))return false;
if(::memcmp(header,"UUU\0",sizeof(header)))return false;
if(!inFile.read(&mRawData[0],mRawData.size()))return false;
mIsOkay=readRaw(mRawData);
return mIsOkay;
}
bool Aladin::openLog(const String &strPathFileName)
{
File inFile;
char header[]={'L','O','G','1'};
char rdHeader[sizeof(header)];
if(!inFile.open(strPathFileName,"rb"))return false;
if(!inFile.read(&rdHeader,sizeof(rdHeader)))return false;
if(::memcmp(rdHeader,header,sizeof(rdHeader)))return false;
if(!mStatus.readFrom(inFile))return false;
if(!mInformation.readFrom(inFile))return false;
if(!mLogBook.readFrom(inFile))return false;
if(!mProfiles.readFrom(inFile))return false;
inFile.close();
mIsOkay=true;
return true;
}
bool Aladin::openDevice(const String &port,GUIWindow &parent)
{
DeviceControlBlock dcb;
CommControl control;
String strCommState;
AppReg appReg;
Block<String> iconNames;
mIsOkay=false;
if(IDCANCEL==::MessageBox(parent,"Place computer in Log Book mode and press OK to continue.","Prompt",MB_OKCANCEL))return false;
if(port.isNull())return false;
if(!control.open(CommControl::stringToPort(port)))return false;
strCommState+=String("baud=")+appReg.getBaud()+String(" ");
strCommState+=String("parity=")+appReg.getParity()+String(" ");
strCommState+=String("data=")+appReg.getDataBits()+String(" ");
strCommState+=String("stop=")+appReg.getStopBits()+String(" ");
control.setDeviceControlBlock(strCommState);
control.getDeviceControlBlock(dcb);
dcb.dtrControl(DeviceControlBlock::DtrControlEnable);
dcb.rtsControl(DeviceControlBlock::RtsControlDisable);
control.setDeviceControlBlock(dcb);
iconNames.insert(&String("ASM1"));
iconNames.insert(&String("ASM2"));
iconNames.insert(&String("ASM3"));
iconNames.insert(&String("ASM4"));
iconNames.insert(&String("ASM5"));
iconNames.insert(&String("ASM6"));
iconNames.insert(&String("ASM7"));
iconNames.insert(&String("ASM8"));
iconNames.insert(&String("ASM9"));
iconNames.insert(&String("ASM10"));
Progress progress(parent,"Sync..., (Press ESC to cancel)",iconNames);
progress.range(3);
progress.canCancel(true);
progress.show(true);
progress.setText("Performing sync-point on device...");
progress++;
while(!(mIsOkay=getControlData(control,progress)))
{
progress.setText("Performing sync-point on device...");
progress.yieldTask();
parent.update();
if(!progress.isOkay())break;
progress.reset();
progress.range(3);
progress++;
}
progress.destroy();
::MessageBeep(0);
::MessageBox(parent,"Please disconnect the device","Acquisition",MB_OK);
dcb.dtrControl(DeviceControlBlock::DtrControlDisable);
dcb.rtsControl(DeviceControlBlock::RtsControlDisable);
control.setDeviceControlBlock(dcb);
control.close();
if(mIsOkay)return mIsOkay=readRaw(mRawData);
::MessageBox(parent,"Capture Failed","Acquisition",MB_OK);
return mIsOkay;
}
bool Aladin::saveRaw(const String &strPathFileName)
{
char header[]={'U','U','U','\0'};
File outFile;
if(!outFile.open(strPathFileName,"wb"))return false;
if(!outFile.write(header,sizeof(header)))return false;
if(!outFile.write(&mRawData[0],mRawData.size()))return false;
return true;
}
bool Aladin::saveText(const String &strPathFileName)
{
File outFile;
if(!outFile.open(strPathFileName,"wb"))return false;
outFile.writeLine("Entry Time Max Depth Bottom Time Surface Time Temperature (C)");
outFile.writeLine("-----------------------------------------------------------------------");
for(int index=0;index<mLogBook.size();index++)
{
const DiveLog &diveLog=((LogBook&)mLogBook)[index];
SystemTime systemTime=diveLog.getEntryTime();
String strLine;
::sprintf(strLine,"%02d-%02d-%4d ",systemTime.month(),systemTime.day(),systemTime.year());
strLine+=String().fromInt(diveLog.getMaxDepth())+String(" ");
strLine+=String().fromInt(diveLog.getBottomTime())+String(" ");
strLine+=diveLog.getSurfaceTime().toString()+String(" ");
strLine+=String().fromInt(diveLog.getWaterTemperature());
outFile.writeLine(strLine);
}
for(int pIndex=0;pIndex<mProfiles.size();pIndex++)
{
DiveProfile &diveProfile=((Block<DiveProfile>&)mProfiles)[pIndex];
outFile.writeLine(" ");
outFile.writeLine(" ");
outFile.writeLine(String("Profile_")+String().fromInt(pIndex+1));
outFile.writeLine("Time Depth");
for(int diveIndex=0;diveIndex<diveProfile.size();diveIndex++)
{
ProfileData &profileData=diveProfile[diveIndex];
outFile.writeLine(String().fromInt(profileData.getStageTime())+String(" ")+String().fromInt(profileData.getDepth()));
}
}
return true;
}
bool Aladin::saveWorksheet(const String &strPathFileName)
{
Worksheet worksheet;
worksheet.setDimensions(100,100);
addDiveLog(worksheet,getLogBook(),0,1);
addProfile(worksheet,getProfile(),0,7);
return worksheet.save(strPathFileName);
}
bool Aladin::saveLog(const String &strPathFileName)
{
File outFile;
char header[]={'L','O','G','1'};
if(!outFile.open(strPathFileName,"wb"))return false;
outFile.write(header,sizeof(header));
if(!mStatus.writeTo(outFile))return false;
if(!mInformation.writeTo(outFile))return false;
if(!mLogBook.writeTo(outFile))return false;
if(!mProfiles.writeTo(outFile))return false;
outFile.close();
return true;
}
const CurrentStatus &Aladin::getStatus(void)const
{
return mStatus;
}
const Information &Aladin::getInformation(void)const
{
return mInformation;
}
const Profiles &Aladin::getProfile(void)const
{
return mProfiles;
}
const LogBook &Aladin::getLogBook(void)const
{
return mLogBook;
}
bool Aladin::getControlData(CommControl &control,Progress &progress)
{
char rcvChar;
char syncBuff[]={'U','U','U','\0'};
int index=0;
int skipped=0;
int waitTime=0;
while(!control.hasData()&&waitTime<500)
{
progress.yieldTask();
::Sleep(100);
waitTime+=100;
}
if(!control.hasData())return false;
::memset(&mRawData[0],0,mRawData.size());
while((sizeof(syncBuff)!=index)&&(skipped<mRawData.size()+4))
{
progress.yieldTask();
if(!progress.isOkay())return false;
control.read(&rcvChar,sizeof(rcvChar));
if(0==rcvChar&&!index){continue;}
if(rcvChar==syncBuff[index])index++;
else {index=0;skipped++;}
}
progress.setCaption("Acquire..., (Press ESC to cancel)");
progress.setText("Acquiring data...");
progress++;
if(sizeof(syncBuff)!=index)return false;
control.readFully((unsigned char*)&mRawData[0],mRawData.size());
for(index=0;index<mRawData.size();index++)mRawData[index]=BitManip::reverse(mRawData[index]);
progress.setCaption("Success");
progress.setText("Data acquisition complete.");
progress++;
return true;
}
bool Aladin::readRaw(Array<BYTE> &body)
{
if(!mStatus.readFrom(body))return false;
if(!mInformation.readFrom(body))return false;
if(!mProfiles.readFrom(body,mInformation,mStatus))return false;
if(!mLogBook.readFrom(body,mStatus))return false;
return true;
}
void Aladin::addDiveLog(Worksheet &worksheet,const LogBook &logBook,int startRow,int startCol)
{
worksheet.setAt(startRow,startCol+(5/2),"DiveLog");
worksheet.setAt(startRow,startCol,"Entry Time");
worksheet.setAt(startRow,startCol+1,"Max Depth");
worksheet.setAt(startRow,startCol+2,"Bottom Time");
worksheet.setAt(startRow,startCol+3,"Surface Time");
worksheet.setAt(startRow,startCol+4,"Temperature");
for(int index=0;index<logBook.size();index++)
{
const DiveLog &diveLog=((LogBook&)logBook)[index];
startRow++;
worksheet.setAt(startRow,startCol,diveLog.getEntryTime().toString());
worksheet.setAt(startRow,startCol+1,diveLog.getMaxDepth());
worksheet.setAt(startRow,startCol+2,diveLog.getBottomTime());
worksheet.setAt(startRow,startCol+3,diveLog.getSurfaceTime().toString());
worksheet.setAt(startRow,startCol+4,diveLog.getWaterTemperature());
}
}
void Aladin::addProfile(Worksheet &worksheet,const Profiles &profiles,int startRow,int startCol)
{
int sRow(startRow);
for(int pIndex=0;pIndex<profiles.size();pIndex++)
{
DiveProfile &diveProfile=((Block<DiveProfile>&)profiles)[pIndex];
sRow=startRow;
String strTitle(String("Profile_")+String().fromInt(pIndex+1));
worksheet.setAt(sRow++,startCol,strTitle);
worksheet.setAt(sRow,startCol,"Time");
worksheet.setAt(sRow++,startCol+1,"Depth");
for(int diveIndex=0;diveIndex<diveProfile.size();diveIndex++)
{
ProfileData &profileData=diveProfile[diveIndex];
worksheet.setAt(sRow,startCol,profileData.getStageTime());
worksheet.setAt(sRow++,startCol+1,profileData.getDepth());
}
startCol+=2;
}
}