function [] = run(~, ~)
%RUN Summary of this function goes here
%   Detailed explanation goes here


global artoaWorkspace artoaConfig;

%% Validate soundsource table input
[success, message] = artoa.controller.track.parameter.validateCombinationsInput( ...
    artoaWorkspace.trackParameter.soundsourceCombinations ...
);
if ~success
    errordlg(message, 'Input error');
    return;
end

%% Prepare variable if required
if ~artoa.data.hasMember(artoaWorkspace, {'trajectoryOutput', 'trajectories'})
    artoaWorkspace.trajectoryOutput.trajectories = {};
end

%% Prepare sound velocity
soundVelocity = NaN( ...
    size(artoaWorkspace.trackParameter.soundsourceCombinations, 1), ...
    3 ...
);

%% Get sound velocity
% select a sound velocity for every soundsource available
selectedVelocity = artoa.controller.selectSoundspeed();
% filter the sound velocities that are required for calcucations
for i = 1:size(soundVelocity, 1)
    if strcmpi( ...
        artoaWorkspace.trackParameter.soundspeedMethodString, ...
        'soundsource file' ...
        )
        % get soundsource names
        soundsourceNames = strsplit(artoaWorkspace.trackParameter.soundsourceCombinations.soundsources{i});
        % get soundspeed for every soundsource
        for oName = 1:length(soundsourceNames)
            soundVelocity(i, oName) = selectedVelocity{soundsourceNames{oName}, 1};
        end
    else
        soundVelocity(i, :) = selectedVelocity{1, 1};
    end
end

%% Calculate and append track

pressureAndDate = { ...
    artoaWorkspace.pressure(artoaWorkspace.statusPressure == 1), ...
    artoaWorkspace.rafosDate(artoaWorkspace.statusPressure == 1) ...
};

% restore initial toa, because it is required by the calculate function
toaData = artoaWorkspace.toaData;
toaData.toa = artoaDataInput.toaData.toa;

[ ...
    trajectory, ...
    trajectoryDates, ...
    trajectoryClockError, ...
    trajectoryResiduals, ...
    trajectoryVelocities, ...
    trajectoryTimeDivergenceToGps, ...
    trajectorySegmentSize ...
] = artoa.trajectory.calculate( ...
    artoaWorkspace.float, ...
    pressureAndDate, ...
    artoaWorkspace.satData, ...
    toaData, ...
    artoaWorkspace.filteredSoundsources, ...
    artoaWorkspace.trackParameter, ...
    artoaWorkspace.editOffsets, ...
    soundVelocity, ...
    artoaConfig.leapseconds ...
);

if trajectory == false
    errordlg( [ ...
        'The trajectory could not be calculated. ' ...
        'Please check the inputs of the tracking parameter window and make sure ' ...
        ' the combinations you chose have applied TOAs!' ...
        ], ...
        'Trajectory error' ...
    );
    return;
end

%% Setup trajectory object
trajectoryObject = struct();
trajectoryObject.trackParameter = artoaWorkspace.trackParameter;
trajectoryObject.offsets = artoaWorkspace.editOffsets.offsets;
% trajectory contains [lat lon]
trajectoryObject.latitude = trajectory(:, 1);
trajectoryObject.longitude = trajectory(:, 2);
trajectoryObject.date = trajectoryDates;
trajectoryObject.clockError = trajectoryClockError;
trajectoryObject.residuals = trajectoryResiduals;
trajectoryObject.velocities = trajectoryVelocities;
trajectoryObject.timeDivergenceToGps = trajectoryTimeDivergenceToGps;
trajectoryObject.segmentSize = trajectorySegmentSize;
% find pressure and temperature values
selectedIndices = (artoaWorkspace.statusPressure == 1) & (artoaWorkspace.statusTemperature == 1);
[~, dateIndices, indices] = intersect(trajectoryDates, artoaWorkspace.rafosDate(selectedIndices));
trajectoryObject.pressure = NaN(size(trajectoryDates));
trajectoryObject.pressure(dateIndices) = artoaWorkspace.pressure(indices);
trajectoryObject.temperature = NaN(size(trajectoryDates));
trajectoryObject.temperature(dateIndices) = artoaWorkspace.temperature(indices);

%% Generate trajectory id
if isempty(artoaWorkspace.trajectoryOutput.trajectories)
    trajectoryObject.id = 1;
else
    trajectoryObject.id = artoaWorkspace.trajectoryOutput.trajectories{end}.id + 1;
end
trajectoryObject.hidden = false;

% store to workspace
artoaWorkspace.trajectoryOutput.trajectories{end + 1} = trajectoryObject;

%% Open track gui
artoa.controller.track.trajectoryOutput.open();

end