function [toaData] = recalculate(pFloat, pToaData, pOffsetsTable, pAppliedSoundsources)
%RECALCULATETOADATA Calculates the TOA by adding the offsets and drifts.
%   If parameter four is not available, it will only add the float offset
%   and drift, the soundsource offsets and drifts otherwise (but only for
%   applied TOAs)
%
%   Parameters:
%       pFloat (struct):        The float section from an rfb file.
%       pToaData (struct):      The toaData structure of artoa4.
%       pOffsetsTable (table):  A table containing all offsets and drifts
%                               for every soundsource and float.
%       pAppliedSoundsources (struct):  Structure containing the
%                                       soundsources that have applied TOAs
%
%   Returns:
%       toaData (struct):       The toa data structure with adjusted TOAs

%% Prepare constants
driftColumnName = 'AppliedDrift';
offsetColumnName = 'AppliedOffset';

%% Prepare return variable
toaData = pToaData;

%% Prepare required variables
floatLaunchRafosTime = artoa.convert.dmy2rd( ...
    pFloat.launchtime(3), ...
    pFloat.launchtime(2), ...
    pFloat.launchtime(1) ...
) ...
+ artoa.convert.hms2rd( ...
    pFloat.launchtime(4), ...
    pFloat.launchtime(5), ...
    0 ...
);

%% Add drift for every phase (includes offset)
stepSize = length(toaData.toa) / pFloat.toaperphase;
for i = 1:stepSize:length(toaData.toa)
    startIndex = i;
    endIndex = i + stepSize - 1;
    offset = pOffsetsTable {'Float', offsetColumnName};
    drift = pOffsetsTable{'Float', driftColumnName};
    % check if Inf
    if isinf(offset)
        offset = 0;
    end
    if isinf(drift)
        drift = 0;
    end
    toaData.toa(startIndex:endIndex) = artoa.toa.addDrift( ...
        toaData.toa(startIndex:endIndex), ...
        offset, ...
        drift, ...
        floor(min(toaData.toaDate) - floatLaunchRafosTime) ...
    );
end

if nargin == 3
    return;
end

%% Calculate soundsources
fnames = fieldnames(pAppliedSoundsources);
for i = 1:length(fnames)

    % get rafos start date
    rafosBeginEmission = artoa.convert.dmy2rd( ...
        pAppliedSoundsources.(fnames{i}).begemis(3), ...
        pAppliedSoundsources.(fnames{i}).begemis(2), ...
        pAppliedSoundsources.(fnames{i}).begemis(1) ...
    ) ...
    + artoa.convert.hms2rd( ...
        pAppliedSoundsources.(fnames{i}).begemis(4), ...
        pAppliedSoundsources.(fnames{i}).begemis(5), ...
        0 ...
    );

    toaLogical = strcmp(fnames{i}, toaData.soundSource);
    toaDate = toaData.toaDate(toaLogical);
    toa = toaData.toa(toaLogical);
    [toaDate, sortedDates] = sort(toaDate);
    toa = toa(sortedDates);

    % prepare offset and drift
    offset = pOffsetsTable {fnames{i}, offsetColumnName};
    drift = pOffsetsTable{fnames{i}, driftColumnName};
    % check if Inf
    if isinf(offset)
        offset = 0;
    end
    if isinf(drift)
        drift = 0;
    end

    % calculate drift of soundsource
    toa = artoa.toa.addDrift( ...
        toa, ...
        -1 * offset, ...
        -1 * drift, ...
        floor(toaDate - rafosBeginEmission) ...
    );

    % undo sorting
    toa(sortedDates) = toa;

    toaData.toa(toaLogical) = toa;
end

end