%#codegen
%#internal
function out = range_dsp_maximum(h, in1)
    eml_prefer_const(h);
    if h.RunningMaximum
        [rangeLow, rangeHigh] = range_running_dsp_maximum_impl(in1);
        out = [rangeLow, rangeHigh];
    else
        [rangeLow, rangeHigh] = range_dsp_maximum_impl(in1);
        out = [rangeLow, rangeHigh];
    end
end

function [rangeLow, rangeHigh] = range_running_dsp_maximum_impl(in1)
    persistent runMaxLow runMaxHigh
    if isempty(runMaxLow)
        % First call to the step.
        [rangeLow, rangeHigh] = range_dsp_maximum_impl(in1);        
        runMaxLow = rangeLow;
        runMaxHigh = rangeHigh;
    else
        % Subsequence calls to step
        [rangeLow, rangeHigh] = range_dsp_maximum_impl(in1);
        
        % The new low cannot be less the previous low.
        rangeLow = max(rangeLow, runMaxLow);
        % The new high is maximum of current and previous high
        rangeHigh = max(rangeHigh, runMaxHigh);

        runMaxLow = rangeLow;
        runMaxHigh = rangeHigh;        
    end
end

function [rangeLow, rangeHigh] = range_dsp_maximum_impl(in1)
    coder.inline('always');
    % Return both maximum and minimum values.
    % This is needed for cases where dsp.Maximum returns a vector.
    % See g944472    
    values = in1(:);
    if isreal(values)     
        rangeLow = min(values);
        rangeHigh = max(values);
    else
        % Take minimum and maximum of real and imaginary parts separately.
        % Otherwise constructs like sqrt, exp etc will be introduced.
        values_re = real(values);
        values_im = imag(values);
        rangeLow = min(min(values_re), min(values_im));
        rangeHigh = max(max(values_re), max(values_im));
    end
end

