function [B] = subtractKnownDrifts(pA, pB, pOffsets, pSkipFloatDrift, pSkipSoundsources)
%SUBTRACTKNOWNDRIFTS Subtracts given soundsource and float drift from B.
%   The input tables MUST have 0 at missing values. NaN's are not
%   supported.
%
%   Parameters:
%       pA (table):                 Table created by
%                                   artoa.offsets.createCalculationTables
%       pB (table):                 See pA.
%       pOffsets (table):           The table containing the soundsources
%                                   as row, and the offsets to use as
%                                   column with column name "AppliedOffset".
%       pSkipFloatDrift (bool):    Default: false. If set to true, the
%                                   calculation of the float offset will be
%                                   skipped.
%       pSkipSoundsources (bool):   Default: false. If set to true, the
%                                   calculation of the soundsource offsets will be
%                                   skipped.
%   Returns:
%       B (table):      Returns the new TOA without the offsets.

%% Parameter check
if nargin == 3
    pSkipFloatDrift = false;
    pSkipSoundsources = false;
elseif nargin == 4
    pSkipSoundsources = false;
end

%% Prepare constants
driftColumnName = 'AppliedDrift';
floatRowName = 'Float';

%% Initialize return variables
B = pB;

%% Process all soundsources

if ~pSkipSoundsources
    soundsourceNames = pOffsets.Properties.RowNames;
    for i = 1:length(soundsourceNames)
        currentName = soundsourceNames{i};
        if strcmp(currentName, floatRowName) ...
                || isnan(pOffsets{currentName, driftColumnName}) ...
                || isinf(pOffsets{currentName, driftColumnName})
            continue;
        end
        % get row indices of soundsource
        rowIndices = pA{:, currentName} > 0;
        if ~any(rowIndices)
            continue;
        end
        B.toa(rowIndices) = ...
            B.toa(rowIndices) ...
            - pA{rowIndices, currentName} * pOffsets{currentName, driftColumnName};
    end
end


%% Process float offset
if pSkipFloatDrift || isnan(pOffsets{floatRowName, driftColumnName}) ...
        || isinf(pOffsets{currentName, driftColumnName})
    return;
end
B.toa = B.toa + pA.(floatRowName) * pOffsets{floatRowName, driftColumnName};

end