classdef ObservedPrecisionExtractionInterface < handle
    %% OBSERVEDPRECISIONEXTRACTIONINTERFACE class
    % This class is an interface to extract observed precision data from
    % a data type group.  The interface implements a chain of responsibility
    % pattern for each member of the group.
    % There are 3 cases for precision data
    % 1. We have instrumentation precision data
    % 2. We can use block values to derive precision data
    % 3. There are no precision data
    % The interface will run through every member of the group with these
    % strategies and extract the aggregate precision histogram of the group
    % Based on case #3, the aggregate precision histogram may be empty
    
    % Copyright 2018 The MathWorks, Inc.
    properties(SetAccess = private)
        precisionDataExtractionStrategy
    end
    
    methods
        function setStrategy(this, strategy)
            this.precisionDataExtractionStrategy = strategy;
        end
        
        function finalPrecisionHistogram = getPrecisionHistogram(this, group)
            
            members = group.getGroupMembers;
            finalPrecisionHistogram = struct('BinData', [],'WholeNumber', false);
            
            if numel(members) > 0
                isWholeNumber = true;
                for mIndex = 1:numel(members)
                    [memberData, memberIsWholeNumber] = this.getMemberData(members{mIndex});
                    finalPrecisionHistogram = fxptds.HistogramUtil.mergeHistogramData(memberData, finalPrecisionHistogram);
                    isWholeNumber = isWholeNumber & memberIsWholeNumber;
                    
                end
                finalPrecisionHistogram.WholeNumber = isWholeNumber;
                if isfield(finalPrecisionHistogram, 'numZeros')
                    finalPrecisionHistogram = rmfield(finalPrecisionHistogram, 'numZeros');
                end
            end
        end
        
    end
    
    methods(Hidden)
        function [memberData, isWholeNumber] = getMemberData(this, member)
            [memberData, isWholeNumber] = this.precisionDataExtractionStrategy.getData(member);
        end
    end
end

