function varargout = numericDisplay(data, input_data_subset, namedargs)
    % This helper function is used to get the formatted display output for
    % the given numeric/logical data. It returns a couple of outputs:
    % 1) A string array representation of the display output. 
    % 2) The scaling factor for the given data
    %
    % This helper function only works with 2 dimensional data.
    % 
    % It takes in an additional optional input which corresponds to a
    % subset of the input data. If no value is specified, the input data is
    % used
    %
    % In also takes in a set of optional Name-Value pairs that provide 
    % additional information for processing the data. These additional 
    % inputs are:
    %
    % 'Format': This specifies the numeric display format. It can be one of
    % these - +, bank, hex, long, longE, longEng, longG, rat short, shortE,
    % shortEng, shortG. The default is the current format.
    %
    % 'ScalarOutput': This is a logical value. If this is set to true, the
    % output is returned as a 1x1 string array. Otherwise, the output is
    % returned as a string array which has the same dimensions as that of
    % the input. The default value is false.   
    
    %Copyright 2017-2021 The MathWorks, Inc.
    
    arguments
        data {mustBeNumericOrLogical, mustBeTwoDimensional}
        input_data_subset = data
        namedargs.ScalarOutput (1,1) logical = false
        namedargs.Format (1,:) char {mustBeNonempty} = matlab.internal.display.format
    end
    
    % If optional second input is a formatter, get the format and
    % complexity information from it
    if isa(input_data_subset, 'matlab.display.internal.NumericDisplayFormatter')        
        % Get format information
        namedargs.Format = input_data_subset.Format;
        
        % Get complexity information and update the sub-array
         if input_data_subset.Complex && isreal(data)
             data = complex(data);
         end
    elseif isnumeric(input_data_subset) || islogical(input_data_subset)
        isValidSubNumericDataOrFormatter(input_data_subset, data);
    else
         error('MATLAB:class:RequireNumeric', message('MATLAB:class:RequireNumeric').getString());
    end
    
    [out, scale] = matlab.internal.display.numericDisplayHelper(data, ...
        input_data_subset, ...
        namedargs);
    
    if (nargout == 0 || nargout ==1)
        varargout{1} = out;
    elseif nargout == 2
        varargout{1} = out;
        varargout{2} = scale;
    end
end


function isValidNumericData(data)
    if ~(isnumeric(data) || islogical(data))
        error('MATLAB:class:RequireNumeric', message('MATLAB:class:RequireNumeric').getString());
    end
    
     if numel(size(data)) > 2
         error('MATLAB:class:RequireNDims', message('MATLAB:class:RequireNDims', 2).getString());
     end
end

function isValidSubNumericDataOrFormatter(data, superset_data)
    if ~isa(data, 'matlab.display.internal.NumericDisplayFormatter')
        % Option second input is a numeric data
        isValidNumericData(data);
     
        if ~strcmp(class(data), class(superset_data))
            error('MATLAB:class:RequireClass', message('MATLAB:class:RequireClass', class(superset_data)).getString());
        end

        orig_data_sparseness = issparse(superset_data);
        orig_data_complexity = isreal(superset_data);
        sub_data_sparseness = issparse(data);
        sub_data_complexity = isreal(data);    

        if orig_data_sparseness ~= sub_data_sparseness
            if orig_data_sparseness
                error('MATLAB:services:printmat:mustBeSparse', message('MATLAB:services:printmat:mustBeSparse').getString());
            else
                error('MATLAB:class:RequireClass', message('MATLAB:class:RequireClass', class(superset_data)).getString());
            end         
        end

        if orig_data_complexity ~= sub_data_complexity
            if orig_data_complexity
                error('MATLAB:validators:mustBeReal', message('MATLAB:validators:mustBeReal').getString());
            else
                error('MATLAB:services:printmat:mustBeComplex', message('MATLAB:services:printmat:mustBeComplex').getString());            
            end        
        end    
    end        
end

function mustBeTwoDimensional(data)
     if numel(size(data)) > 2
         error('MATLAB:class:RequireNDims', message('MATLAB:class:RequireNDims', 2).getString());
     end
end