function [ success ] = rfc(pFilename, pFloatDetails, pData)
%RFC Saves the given data to the filename in RFC format.
%
%   Parameters:
%       pFilename (string) The destination filename.
%       pFloatDetails (struct) The FLOAT section that is stored in an RFB
%       file.
%       pData (matrix) The data that should be written to the RFC file.
%           Each line contains one set of data. The matrix format needs to
%           be the following:
%           IFLAG MESSAGE_NUMBER MESSAGE_DATE TEMP PRES LAT LON u v w


%% Initialize return variables
success = false;

%% Initialize variables required for processing
headerLineIndicator = "** ";

%% Parameter check

parameterError = false;

if (~isstring(pFilename) && ~ischar(pFilename))
    warning([mfilename ': Given filename is neither a string nor a char!']);
    parameterError = true;
end
if (~isstruct(pFloatDetails))
    warning([mfilename ': Given float details is not a struct!']);
    parameterError = true;
end
expectedDataColumns = 10;
if (size(pData, 2) ~= expectedDataColumns)
    warning([mfilename ': Given data has ' site(pData, 2) ' columns, but ' ...
        num2str(expectedDataColumns) ' expected!']);
    parameterError = true;
end

if (parameterError)
    return;
else
    clear parameterError;
end

%% Replace all NaN with default values
defaultValues = repmat(-999, 10);
defaultValues(4) = -9.99; % temperature default value
% start at index 4 because the first three do not have default values
for i = 4:size(pData, 2)
    nanIndex = find(isnan(pData(:, i)));
    if ~isempty(nanIndex)
        pData(nanIndex, i) = repmat(defaultValues(i), 1, size(pData, 1));
    end
    clear nanIndex;
end

%% Prepare header and add it to the file string

% FLOAT NAME
floatname = num2str(pFloatDetails.floatname);
% FLOAT CYCLE
cycle = num2str(pFloatDetails.cycle(1));
% LAUNCH PARAMETER
launchPositionLat = num2str(pFloatDetails.cycle(2), '%3.2f');
launchPositionLon = num2str(pFloatDetails.cycle(3), '%3.2f');
launchTime = [pFloatDetails.launchtime, 0];
launchTimeRafosDays = num2str( ...
    artoa.convert.dmy2rd(launchTime(3), launchTime(2), launchTime(1)) ...
);
launchTime = num2str(launchTime);
% RECOVER PARAMETER
recoverTime = [pFloatDetails.recovertime, 0];
recoverTimeRafosDays = num2str( ...
    artoa.convert.dmy2rd(recoverTime(3), recoverTime(2), recoverTime(1)) ...
);
recoverTime = num2str(recoverTime);
% FIRST SURFACE POSITION
surfacePositionLat = num2str(pFloatDetails.cycle(9), '%3.2f');
surfacePositionLon = num2str(pFloatDetails.cycle(10), '%3.2f');
% CYCLE PARAMETER
floatCycleStartTime = [pFloatDetails.cycle(4:8), 0]; % seconds always zero
floatCycleStartTimeRafosDays = num2str( ...
    artoa.convert.dmy2rd(floatCycleStartTime(3), floatCycleStartTime(2), floatCycleStartTime(1)) ...
    + artoa.convert.hms2rd(floatCycleStartTime(4), floatCycleStartTime(5), 0) ...
);
floatCycleStartTime = num2str(floatCycleStartTime);
floatCycleEndTime = [pFloatDetails.cycle(11:15), 0]; % seconds always zero
floatCycleEndTimeRafosDays = num2str( ...
    artoa.convert.dmy2rd(floatCycleEndTime(3), floatCycleEndTime(2), floatCycleEndTime(1)) ...
    + artoa.convert.hms2rd(floatCycleEndTime(4), floatCycleEndTime(5), 0) ...
);
floatCycleEndTime = num2str(floatCycleEndTime);

header = { ...
    ['** Float: ' floatname], ...
    ['** Variables: InterpFlag LineNum RafosDay  Temp  Pres  Lat  Lon  U     V     W'], ...
    ['** Units    : #          #       #         degC  dbar  deg  deg  cm/s  cm/s  mm/s'], ...
    ['** Dummies  : NA         NA      NA        -9.99 -999  999  999   999   999   999'], ...
    ['** Cycle    : ' cycle], ...
    ['** Launch position (Cycle Start position): ' ...
        launchPositionLat ' ' launchPositionLon], ...
    ['** Surface position (Cycle End position) : ' ...
        surfacePositionLat ' ' surfacePositionLat], ...
    ['** Cycle Start time             : ' floatCycleStartTime ' (RAFOS day ' floatCycleStartTimeRafosDays ')'], ...
    ['** Launch time                  : ' launchTime ' (RAFOS day ' launchTimeRafosDays ')'], ...
    ['** Cycle End time               : ' floatCycleEndTime ' (RAFOS day ' floatCycleEndTimeRafosDays ')'], ...
    ['** First surface Position time  : ' recoverTime ' (RAFOS day ' recoverTimeRafosDays ')'] ...
};

fileString = [strjoin(header, newline) newline];


%% Generate file format

for i = 1:size(pData, 1)
    line = { ...
        num2str(pData(i, 1), '%2d') ...
        num2str(pData(i, 2), '%3d') ...
        num2str(pData(i, 3), '%8.2f') ...
        num2str(pData(i, 4), '%6.3f') ...
        num2str(pData(i, 5), '%6.1f') ...
        num2str(pData(i, 6), '%9.3f') ...
        num2str(pData(i, 7), '%8.3f') ...
        num2str(pData(i, 8), '%9.2f') ...
        num2str(pData(i, 9), '%7.2f') ...
        num2str(pData(i, 10), '%7.2f')
    };
    fileString = [fileString strjoin(line) newline];
end

%% Save to file

fid = fopen(pFilename, 'w');
fprintf(fid, fileString);
fclose(fid);

%% Update return variable

success = true;

end
