% read carbon waveglider (CWG) zrecord summary log]
function[] = read_zbin(logpath)
    global serr;
    serr = 2;
    fid = -1;
    errmsg='';
    status=0;

    try
    fprintf(serr,"loading %s...\n",logpath);
    [fid,errmsg] = fopen(logpath,'r');
    if fid >= 0 
        fprintf(serr,"fopen OK fid[%d] %s\n",fid,errmsg);
        status = load_records(fid);
        if ~(status == 0)
         fprintf(serr,"load_records returned [%d]\n",status);           
        end
        fclose(fid);
    else
        fprintf(serr,"fopen failed [%s]\n",errmsg);
    end
    catch OE
        fprintf(serr,"open failed [%s]\n",OE.identifier);
    end
end

% load records
function status = load_records(fd)
    global serr;
    sync_err = 0;
    record_count = 1;
    load_err=0;
    status=0;
    lerr_count=0;
    serr_count=0;

    if fd >= 0 
        while feof(fd)==0
        sync_err=-1;
        ofs=0;
        [sync_err,ofs] = find_sync(fd);
        if sync_err==0 
            fseek(fd,ofs,-1);
            % load next record
            [record,load_err] = load_record(fd);
            if load_err == 0
%            fprintf(serr,"read_log stat_n[%hu] ts[%lu/%u]\n",record(1).data(1).stat_n,record(1).data(1).timestamps(1),record(1).data(1).timestamps(2));
                % add record to array and increment count
                record_arr(record_count)=record;
                record_count=record_count+1;
            else
                status=-1;
                lerr_count=lerr_count+1;
            end
        else
            if sync_err==-2
                status=0;
            else
                status=-1;
                serr_count=serr_count+1;
            end
        end
%         fprintf(serr,"read_log sync_err[%d] ofs[%d] load_err[%d] records[%u]\n",sync_err,ofs,load_err,record_count);
        end
    end
    if ~( status==0 )
        fprintf(serr,"read_records errors load_errors[%d] sync_errors[%d]\n",lerr_count,serr_count);
    end
    assignin('base','records',record_arr);
end

% load one record
function [logrec,err] = load_record(fd)
    global serr;
    logrec=struct('header',{},'data',{});
    header=struct('sync',[],'type_id',[],'meas_id',[],'timestamp',[],'seq_n',[],'cycle_id',[],'meas_count',[],'len',[]);
    err=0;

    % read header
    try
        header(1).sync=fread(fd,1,'uint32',0,'l');
        header(1).type_id=fread(fd,1,'uint16',0,'l');
        header(1).meas_id=fread(fd,1,'uint16',0,'l');
        header(1).timestamp=fread(fd,1,'uint64',0,'l');
        header(1).seq_n=fread(fd,1,'uint32',0,'l');
		header(1).cycle_id=fread(fd,1,'uint32',0,'l');
        header(1).meas_count=fread(fd,1,'uint16',0,'l');
        header(1).len=fread(fd,1,'uint32',0,'l');
        fprintf(serr,"load_record sync[%08lX] type_id[%04hX] meas_id[%04hX] ts[%lu] seq_n[%lu] cycle_id[%lu] len[%lu] meas_count[%hu]\n",header(1).sync,header(1).type_id,header(1).meas_id,header(1).timestamp,header(1).seq_n,header(1).cycle_id,header(1).len,header(1).meas_count);
    catch HE
        fprintf(serr,"header read error %s\n",HE.identifier);
        err=-1;
    end

    if err==0
       % read data
        meas=struct('timestamps',{},'meas_id',[],'stat_n',[],'period',[],'M',{},'S',{},'min',{},'max',{},'X',{});
        for i = 1:header(1).meas_count
            try
                meas(1).timestamps(1)=fread(fd,1,'uint64',0,'l');
                meas(1).timestamps(2)=fread(fd,1,'uint64',0,'l');
                meas(1).meas_id=fread(fd,1,'uint16',0,'l');
                meas(1).stat_n=fread(fd,1,'uint16',0,'l');
                meas(1).period=fread(fd,1,'float',0,'l');

                for j=1:13
                   meas(1).M(j)=fread(fd,1,'float',0,'l');
                end
                for j=1:13
                    meas(1).S(j)=fread(fd,1,'float',0,'l');
                end
                for j=1:13
                    meas(1).min(j)=fread(fd,1,'float',0,'l');
                end
                for j=1:13
                    meas(1).max(j)=fread(fd,1,'float',0,'l');
                end
                for j=1:6
                    meas(1).X(j)=fread(fd,1,'float',0,'l');
                end
                % add measurement to array
                meas_arr(i)=meas;
            catch DE
                fprintf(serr,"data read error %s\n",DE.identifier);
                err=-1;
                break;
            end
        end

        if err==0
            % populate struct
            logrec(1).header=header;
            logrec(1).data=meas_arr;
        end
    end
%     fprintf("data end ofs[%d]\n",ftell(fd));
end

% find record sync pattern
function [r_err,r_ofs] = find_sync(fd)
     global serr;
     r_err=-1;
     r_ofs=-1;
     sync_valid=int32(0);
     sync_byte=uint8(0);
    if (fd>0) 
%         fprintf(2,"find_sync ENTER fd[%d] ofs[%ld]\n",fd,ftell(fd));
        while feof(fd)==0 && sync_valid==0
            sync_start = ftell(fd);
            sync_byte=uint8(0);
            [sync_byte,count]=fread(fd,1,'uint8');
            if count==1 && sync_byte==uint8(2)
               sync_byte=fread(fd,1,'uint8');
               if count==1 && sync_byte==uint8(76)
                   sync_byte=fread(fd,1,'uint8');
                   if count==1 && sync_byte==uint8(234)  
                       sync_byte=fread(fd,1,'uint8');
                       if count==1 && sync_byte==uint8(12) 
                           sync_valid=1;
                           break;
                       else
%                             fprintf(serr,"err[3] read %02X\n",sync_byte);
                       end
                   else
%                         fprintf(serr,"err[2] read %02X\n",sync_byte);
                   end
               else
%                     fprintf(serr,"err[1] read %02X\n",sync_byte);
               end
            else
%                 fprintf(serr,"err[0] read %02X\n",sync_byte);
            end
        end

        if sync_valid == 1
            r_ofs = sync_start;
            r_err = 0;
        elseif feof(fd)==1
            r_err = -2;
        elseif ferror(fd)==1
            r_err = -3;
        else
            r_err = -4;
        end
    else
        fprintf(serr,"invalid arg\n");   
    end
%     fprintf(serr,"find_sync EXIT r_ofs[%ld] r_err[%d]\n",r_ofs,r_err);

end

