function hPoints = accordPlotSingleObservation(hAxes, data, actorInd, molStruct, ...
    obsInd, realization, scale)
%
% The AcCoRD Simulator
% (Actor-based Communication via Reaction-Diffusion)
%
% Copyright 2016 Adam Noel. All rights reserved.
% 
% For license details, read LICENSE.txt in the root AcCoRD directory
% For user documentation, read README.txt in the root AcCoRD directory
%
% accordPlotObservation.m - plot AcCoRD simulation observations made at one
%   time step. Assume that axes already exists (as created by
%   accordPlotEnvironment)
%
% INPUTS
% hAxes - handle to axes in plotted figure. Generated by accordPlotEnvironment
% data - structure with simulation output. Generated by accordImport
% actorInd - index of the actor in the list of passive actors that recorded
%   observations
% molStruct - structure defining how each type of molecule should appear.
%   Initialized by accordBuildMarkerStruct
% obsInd - index of the observation to plot
% realization - index of the realization to plot
% scale - scaling of physical dimensions of coordinates.
%   Needed to mitigate patch display problems. Recommend that smallest
%   object to plot has dimension of order 1
%
% OUTPUTS
% hPoints - cell array of handles to plots made at this observation point
%
% Last revised for AcCoRD v1.4.2 (2020-02-12)
%
% Revision history:
%
% Revision v1.4.2 (2020-02-12)
% - corrected indexing of plots where markers are used to draw the
% molecules
%
% Revision v1.2 (2018-05-30)
% - added plotting molecules as shapes instead of only as markers. Added
% the sphere shape
%
% Revision v0.6 (public beta, 2016-05-30)
% - Created file
%
% Created 2016-05-17

if isempty(molStruct)
    % Plot all molecules with default parameters
    molStruct = accordBuildMarkerStruct(1:data.passiveRecordNumMolTypes);
end

hPoints = cell(1, molStruct.numToDisp);

for i = 1:molStruct.numToDisp
    curMol = molStruct.indToDisp(i);
    if ~isempty(data.passiveRecordPos{actorInd}{curMol})
        switch molStruct.shape{1}{i}
            case 'marker'
                % Plot all molecules as a scatter plot
                hPoints{i} = ...
                    scatter3(hAxes, scale*data.passiveRecordPos{actorInd}{curMol}{realization,obsInd}(:,1),...
                    scale*data.passiveRecordPos{actorInd}{curMol}{realization,obsInd}(:,2),...
                    scale*data.passiveRecordPos{actorInd}{curMol}{realization,obsInd}(:,3));
                set(hPoints{i},'DisplayName', molStruct.dispStr{1}{i});
                set(hPoints{i},'SizeData', molStruct.size(i));
                set(hPoints{i},'LineWidth', molStruct.lineWidth(i));
                set(hPoints{i},'MarkerEdgeColor', molStruct.edgeColor{1}{i});
                set(hPoints{i},'MarkerFaceColor', molStruct.faceColor{1}{i});
                set(hPoints{i},'Marker', molStruct.marker{1}{i});
            case 'sphere'
                % Plot each molecule as an individual 3D sphere
                numMol = data.passiveRecordCount{actorInd}(realization,curMol,obsInd);
                hPoints{i} = zeros(1,numMol);
                curVertices = zeros(molStruct.numVertices(i), 3);
                % Prepare 
                for n = 1:numMol
                    % TODO: Rotate?
                    for j = 1:3
                        curVertices(:,j) = scale*(molStruct.vertices{i}(:,j) + ...
                            data.passiveRecordPos{actorInd}{curMol}{realization,obsInd}(n,j));
                    end
                    hPoints{i}(n) = patch('Vertices',curVertices,'Faces', ...
                        molStruct.faces{i}, 'FaceColor', molStruct.faceColor{1}{i}, ...
                        'EdgeColor', molStruct.edgeColor{1}{i}, ...
                        'FaceAlpha', molStruct.opaque(i), ...
                        'LineWidth', molStruct.lineWidth(i), ...
                        'LineStyle', molStruct.lineStyle{1}{i}, ...
                        'DisplayName', molStruct.dispStr{1}{i});
                end
        end
    else
        hPoints{i} = scatter3(hAxes, NaN, NaN, NaN);
    end
end