function rdifiles=adcphex2bin(ifile,ofile,sst)
%---------------------------------------------------------------------
% General:  Program to convert HEX ADCP data to Binary for .rdi file
% Input:    ifile [String] - NEPTUNE Canada log file
%           ofile1 [String] - rdi file name
%           sst (datenum vector) - start times for rdi files
% Output:   .rdi 
% Modify Date/Author: 20100819, R.Jenkyns
%---------------------------------------------------------------------
if nargin<3,  error('Inputs missing'); end

[isz,is,isr,br]=createBufferedReader(ifile);

ds='yyyymmddTHHMMSS.FFF';
ds2='yyyymmddTHHMMSS';

% init
fileOpened=0;
jcnt=0; rdifiles=''; 
line=char(readLine(br));
ts=line(1:19); tnum=datenum(ts,ds); stTime=tnum;
dpe=0; numfiles=0;

while ~isempty(line)    
    if stTime>=sst(1) && tnum<sst(2)
        if length(line)>25 % minimum length to include identifying reading header
            % start new rdi file if restart occurs 
            s1=line(22:26);
            if strcmp(s1,'START') || strcmp(s1,'[ALT-') || strcmp(s1,'[ALAR')
                stLast=stTime;
                stTime=tnum;
                if jcnt>0
                    fclose(fidb);
                    disp(['RDI output file',ofile,' closed, ',num2str(jcnt),' records converted.'])
                else
                    if fileOpened
                        fclose(fidb);
                        numfiles=numfiles-1;
                        rdifiles=rdifiles(1:numfiles,:);
                    end    
                    disp(['RDI has a data gap from', datestr(stLast,ds),' to ',ts])
                end    
                jcnt=0;
                fileOpened=0;
            end    
            if  strcmp(line(22:25),'7F7F')% confirm header ID code, numeric representation is "55 70 55 70"
                if fileOpened==0
                    ofile=[ofile(1:end-19),datestr(tnum,ds2),'.rdi'];
                    numfiles=numfiles+1;
                    rdifiles(numfiles,:)=ofile;
                    fidb=fopen(ofile,'w'); % open binary file as write
                    fileOpened=1;
                end
                lineHEX=line(22:end); % strip off leading time stamp
                cs=checksum(lineHEX);% routine below
                if strcmp(lineHEX(end-3:end),cs)% ensemble is valid
                    jcnt=jcnt+1;
                    
                    % insert observatory time 
                    if jcnt==1
                        numtypes=hex2dec(lineHEX(11:12)); 
                        dpe=getDPE(lineHEX(57:86));
                        t0=12+4*numtypes+59*2;
                        t1=t0+9;      t2=t0+22; %163,176
                        t3=t0+117;    t4=t0+130; %271,284
                        t5=t0+5;      t6=t0+8; %159,162
                    end
                    newHEXtime=HEXtime2(tnum);  
                    lineHEX(t1:t2)=newHEXtime;                
                    lineHEX(t3:t4)=newHEXtime; 

                    % fix ensemble number
                    lineHEX(t5:t6)=getEnsHex(jcnt);
                    
                    % fix checksum
                    lineHEX(end-3:end)=checksum(lineHEX);  
                    
                    % write to file
                    if mod(length(lineHEX),2)==0, %
                        nhex=fix(length(lineHEX)/2); % get the actual size of the data block read
                        linebyte=reshape(lineHEX(1:nhex*2),2,nhex); % resize HEX vector string into 2xN matrix
                        dec=hex2dec(linebyte'); % use internal hex to decimal conversion for each HEX pair
                        fwrite(fidb,dec,'ubit8'); % write the decimal data to file in ubit8 integer binary
                    end
                end    
                if jcnt>0 && mod(jcnt,10000)==0, disp([num2str(jcnt),' ensembles read so far. ',ts]); end 
                line=char(readLine(br));
                if ~isempty(line),ts=line(1:19); tnum=datenum(ts,ds); end
            else
                %display(line(1:26));
                line=char(readLine(br));  
                if ~isempty(line), ts=line(1:19); tnum=datenum(ts,ds);  end
            end
        else
            line=char(readLine(br));   
            if ~isempty(line), ts=line(1:19); tnum=datenum(ts,ds); end
        end   
    else
        line=char(readLine(br));   
        if ~isempty(line)
            ts=line(1:19); tnum=datenum(ts,ds); stTime=tnum;
        end    
    end     
    if tnum>sst(2), line=''; end %no point reading further in datafile
end

if jcnt>0, fclose(fidb); end % close output binary file     
br.close; isr.close; is.close; isz.close;
disp(['RDI output file',ofile,' closed, ',num2str(jcnt),' records converted. '])

function newHEXtime=HEXtime2(newtime)
adjustTime=0; 
enstime=newtime;  
enstvec=datevec(enstime);
HEX(1:2)=dec2hex(enstvec(1)-2000,2);  % routine below
HEX(3:4)=dec2hex(enstvec(2),2);
HEX(5:6)=dec2hex(enstvec(3),2);
HEX(7:8)=dec2hex(enstvec(4),2);
HEX(9:10)=dec2hex(enstvec(5),2);
sec=floor(enstvec(6));
HEX(11:12)=dec2hex(sec,2);
HEX(13:14)=dec2hex(floor((enstvec(6)-sec)*100),2);
newHEXtime=HEX;

function dpe=getDPE(plineHEX)
ppe=hex2dec(plineHEX(1:2));  % pings per ensemble
mpp=hex2dec(plineHEX(25:26)); % minutes between ping
spp=hex2dec(plineHEX(27:28)); % seconds between ping
hsp=hex2dec(plineHEX(29:30)); % 100s between ping
dpe=ppe*((mpp/(1440))+(spp/(86400))+(hsp/(8640000))); % days per ensemble

function hexcs=checksum(lineHEX)
pline=lineHEX(1:end-4);
nhex=fix(length(pline)/2); % get the actual size of the data block read
plinebyte=reshape(pline(1:nhex*2),2,nhex); % resize HEX vector string into 2xN matrix
dec=hex2dec(plinebyte'); % use internal hex to decimal conversion for each HEX pair
ncs=mod(sum(dec),65536);
mlhexcs=dec2hex(ncs,4);
hexcs(1:2)=mlhexcs(3:4);
hexcs(3:4)=mlhexcs(1:2);

function lmhexens=getEnsHex(jcnt)
lmhexens='0000';
mlhexens=dec2hex(jcnt);
if length(mlhexens)>4, mlhexens=mlhexens(end-3:end); end % only take the last 4 hex char
if length(mlhexens)==4
    lmhexens(1:2)=mlhexens(3:4);
    lmhexens(3:4)=mlhexens(1:2);
elseif length(mlhexens)==3
    lmhexens(1:2)=mlhexens(2:3);
    lmhexens(4)=mlhexens(1);
elseif length(mlhexens)==2
    lmhexens(1:2)=mlhexens(1:2);
elseif length(mlhexens)==1
    lmhexens(2)=mlhexens(1);
end