%HELP for function OTCOLLECTBUFFER (to be completed).
%
%Author: Rob Whitwell v. 1.1
%
%This function serves as the main function to run optotrak based
%experiments. It relies on a configuration text file pre-saved by the user
%to administer the trial order.
%
%@PARAMS:
%       'ssPrfx' - the subject's prefix to be used in the stored file name
%       'tTot' - the trial total.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                          %
% COLLECT OPTOTRAK DATA USING NDI'S BUFFER % 
%                                          %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

function [rawData dataReorg setupInfo] = OTCollectBuffer(ssPfx,tTot)

%CONSTANTS
MISSINGDATACUTOFFVALUE = -3.6972e28; %an 'anything less than' cutoff value for missing data, 
OPTO = '_opto_';
TXT = '.txt';
DAT = '.dat';
FNRAWDATA = 'RawNDIDatFiles';
FNOTCREORG = 'OTCReorganized';

%Initialize the following Psychtoolbox functions
GetSecs;
WaitSecs;
KbCheck;

%store the current directory to return to it when finsihed.
oldDir = pwd;

%SETUP OPTOTRAK
%initialize optotrak
optotrak_init

%setup collection parameters, 'setupInfo' is a data structure comprising
%three variables: 'numMarkers', 'frameRate', and 'collectionTime'
setupInfo = setup_optotrak;

%Raw data
A = {};

%Reorganized Data
B = {};

t = 1; %current trial number
smpRt = 100; %sample rate (in Hz)
ISI = (1/setupInfo.frameRate); %inter-sample-interval (in seconds).
fTotPerTrial = setupInfo.collectionTime/ISI; %the total number of sample frames to collect per trial
ITI = 1; %time from the end of one trial to the start of the next (in seconds) 

%select the experimental directory and navigate to it
expDir = uigetdir;
cd(expDir)

%create a new file folder to store the NDI raw data if the folder does not exist
if exist(FNRAWDATA, 'dir') == 7
else
    mkdir(expDir,FNRAWDATA);
end

%create a new file folder to store the reorganized data if the folder does not exist
if exist(FNOTCREORG, 'dir') == 7
else
    mkdir(expDir,FNOTCREORG);
end

%loop through the trials
for t = 1:tTot
    
%re-initialize the reorganized data
dataReorg = zeros(fTotPerTrial, setupInfo.numMarkers*3);
    
    %determine the trial number text
    if t > 99 && t < 1000
        txtTrial = [int2str(t)];
    elseif t > 9 && t < 100
        txtTrial = ['0' int2str(t)];
    elseif t > 0 && t < 10
        txtTrial = ['00' int2str(t)];
    else
        txtTrial = '000';
    end
    
    
    %ensure that the keyboard is not being touched before preoceeding any
    %further
    touch = 1;
    while touch
        touch = KbCheck;
    end   
    
    disp('Hit the spacebar to start the trial')
        
    %wait for a keyboard press to start the next trial
    %while 'touch' does not equal 0, continue the loop
    while ~touch
        
        %KbCheck returns touch (boolean), tStart (floating computer time
        %stamp) and keyCode (the key hit)
        [touch,tStart,keyCode] = KbCheck; 
        
        %if the user hits the spacebar, continue with the current trial
        if find(keyCode) == 32      % SPACE BAR
            touch = 1;
            disp('Trial Started')
        end
        
        %if the user hits the escape key, end the program
        if find(keyCode) == 27      % ESCAPE KEY
            return;
        end

    end

    %navigate to the NDI Raw data file
    cd([expDir '\' FNRAWDATA]);

    %Store the current NDI dat file name
    NDIFName = [ssPfx OPTO txtTrial DAT];

    %activate the IREDs
    OptotrakActivateMarkers;

    %initialize the file for spooling
    DataBufferInitializeFile(0,NDIFName);

    %start collecting data
    DataBufferStart();
            
    %spool data from buffer to file
    puRealtimeData=0;
    puSpoolComplete=0;
    puSpoolStatus=0;
    pulFramesBuffered=0;

    while (puSpoolComplete == 0)
        [puRealtimeData,puSpoolComplete,puSpoolStatus,pulFramesBuffered]=DataBufferWriteData(puRealtimeData,puSpoolComplete,puSpoolStatus,pulFramesBuffered);
        WaitSecs(.1);
        if puSpoolStatus ~= 0
            disp('Spooling Error');
            break;
        end
    end

    %Deactivate the Markers
    OptotrakDeActivateMarkers();

    %open the .dat file stored by Optotrak
    [fid, message] = fopen(deblank(NDIFName),'r+','l'); % little endian byte ordering

    %Read the header portion of the file
    [filetype,items,subitems,numframes,frequency,user_comments,sys_comments,descrip_file,cutoff,coll_time,coll_date,frame_start,extended_header,character_subitems,integer_subitems,double_subitems,item_size,padding] = read_nd_c_file_header(fid);

    %Read the data portion of the file
    rawData = read_nd_c_file_data(fid, items, subitems, numframes);
    fclose(fid);

    %Convert the data to a format OTCTextWrite accepts
    for i = 1:setupInfo.numMarkers
    
        %append the marker data to dataReorg and delete the 
        dataReorg = [dataReorg transpose(squeeze(rawData(i,:,:)))];
        dataReorg(:,1:3) = [];
    end
    
    %Convert missing data to NaNs
    dataReorg(dataReorg == MISSINGDATAVALUE) = NaN;
    
    %navigate to the 'OTCReorganized' file folder
    cd([expDir '\' FNOTCREORG]);

    %ALWAYS STORE A RAW DATA SET
    disp(['Saving file: ' ssPfx OPTO txtTrial TXT '...'])
    fid = fopen([ssPfx OPTO txtTrial TXT], 'w');
    %fprintf(fid, hdr);
    fclose(fid);
    dlmwrite([ssPfx OPTO txtTrial TXT],dataReorg,'-append','delimiter','\t','newline','pc');
    disp('Success!')

    %OTCTextWrite({dataReorg}, MDM, fDir, ssPfx, [trailText '.txt'], GAIndx,
    %setupInfo.frameRate, fltRt);
end
cd(oldDir);
return;