function [minval,indx] = min(x0,y0,dim)
% MATLAB Code Generation Library fixed-point function for min.
%
% Limitations:
% 1) Does not support complex.

%   Copyright 2004-2020 The MathWorks, Inc.
%#codegen

coder.internal.implicitExpansionBuiltin;
coder.noImplicitExpansionInFunction;
coder.internal.prefer_const(x0,y0,dim);
eml_allow_mx_inputs;

eml_invariant(nargin > 0, 'fixed:coder:notEnoughInputArguments');
eml_invariant(isreal(x0), 'fixed:fi:unsupportedComplexInput','MIN');
if (nargin >= 2)
    eml_invariant(isreal(y0), 'fixed:fi:unsupportedComplexInput','MIN');
end

% Check for ambiguous types and return with the correct size output
if eml_ambiguous_types
    if nargin == 1
        if nargout == 1
            minval = coder.internal.minOrMax('min',double(x0));
        else
            [minval,iindx] = coder.internal.minOrMax('min',double(x0));
            indx = double(iindx);
        end
    elseif nargin == 2
        if nargout == 1
            minval = coder.internal.minOrMax('min',double(x0),double(y0));
        else
            [minval,iindx] = coder.internal.minOrMax('min',double(x0),double(y0));
            indx = double(iindx);
        end
    else
        if nargout == 1
            minval = coder.internal.minOrMax('min',double(x0),double(y0),double(dim));
        else
            [minval,iindx] = coder.internal.minOrMax('min',double(x0),double(y0),double(dim));
            indx = double(iindx);
        end
    end
    return
end

if nargin==1
    % minval     = min(x)
    % [minval,indx] = min(x)
    
    if isscaledtype(x0)
        % Fixed-point FI
        if nargout <= 1
            minval = coder.internal.minOrMax('min',x0);
        else
            [minval,iindx] = coder.internal.minOrMax('min',x0);
            indx = double(iindx);
        end
    elseif isfloat(x0)
        % True Double or True Single FI
        dType  = eml_fi_getDType(x0);
        x      = eml_cast(x0,dType);
        T      = eml_typeof(x0);
        F      = eml_fimath(x0);
        if nargout <= 1
            minval = eml_cast(coder.internal.minOrMax('min',x),T,F);
        else
            [minvalTemp,iindx] = coder.internal.minOrMax('min',x);
            indx = double(iindx);
            minval = eml_fimathislocal(eml_cast(minvalTemp,T,F),false);
        end
    else
        % FI datatype not supported
        eml_fi_assert_dataTypeNotSupported('MIN');
    end
    
elseif nargin==2
    % minval = min(x,y)
    if (isinteger(x0) || (isfi(x0) && isscalingbinarypoint(x0))) && ...
            (isinteger(y0) || (isfi(y0) && isscalingbinarypoint(y0)))
        % Binary point scaled fixed-point (including Scaled doubles, ints)
        
        if (isfi(x0) && isfi(y0) && ...
                isequal(eml_typeof(x0), eml_typeof(y0)) && ...
                isequal(eml_fimath(x0), eml_fimath(y0)) && ...
                isequal(eml_fimathislocal(x0), eml_fimathislocal(y0)))
            % x0,y0: same data types AND same fimath
            if nargout <= 1
                minval = coder.internal.minOrMax('min',x0,y0);
            else
                % This will produce an assertion for nargout>1
                [minval,iindx] = coder.internal.minOrMax('min',x0,y0);
                indx = double(iindx);
            end
        else
            % x0,y0: different data types and/or different fimaths
            [x, y] = fixed.aggregateTypeAndFimath(x0, y0);
            if nargout <= 1
                minval = coder.internal.minOrMax('min',x,y);
            else
                % This will produce an assertion for nargout>1
                [minval,iindx] = coder.internal.minOrMax('min',x,y);
                indx = double(iindx);
            end
        end
        
    elseif ( (isfi(x0) && isscaledtype(x0)) || ...
            (isfi(y0) && isscaledtype(y0)) )
        % Fixed-point FI (NOT binary point scaling, e.g., slope-bias)
        
        if ~isfi(y0) % fi , non-fi
            tx = eml_typeof(x0);
            % Cast y0 to x0's type
            f = eml_fimath(x0);
            x = x0; y = eml_fimathislocal(eml_cast(y0,tx,f),eml_fimathislocal(x0));
        elseif ~isfi(x0) % non-fi , fi
            ty = eml_typeof(y0);
            % Cast x0 to y0's type
            f = eml_fimath(y0);
            y = y0; x = eml_fimathislocal(eml_cast(x0,ty,f),eml_fimathislocal(y0));
        else % fi , fi
            % FI, but NOT binary point scaled
            % Check for numerictypes to be equal.
            tx = eml_typeof(x0); ty = eml_typeof(y0);
            eml_invariant(coder.const(isequal(tx,ty)), ...
                'fixed:fi:numerictypeMismatch');
            x = x0; y = y0;
        end
        
        if nargout <= 1
            minval = coder.internal.minOrMax('min',x,y);
        else
            % This will produce an assertion for nargout>1
            [minval,iindx] = coder.internal.minOrMax('min',x,y);
            indx = double(iindx);
        end
        
    elseif ( isfi(x0) && isfloat(x0) ) || ...
            ( isfi(y0) && isfloat(y0) )
        % True Double or True Single FI
        
        if ~isfi(x0) % non-fi , fi
            dType = eml_fi_getDType(y0);
            T     = eml_typeof(y0);
            F     = eml_fimath(y0);
        else % fi , non-fi or fi , fi
            dType = eml_fi_getDType(x0);
            T     = eml_typeof(x0);
            F     = eml_fimath(x0);
        end
        x = eml_cast(x0,dType);
        y = eml_cast(y0,dType);
        
        if nargout <= 1
            minval = eml_fimathislocal(eml_cast(coder.internal.minOrMax('min',x,y),T,F),false);
        else
            % This will produce an assertion for nargout>1
            [minvalTemp,iindx] = coder.internal.minOrMax('min',x,y);
            indx = double(iindx);
            minval = eml_fimathislocal(eml_cast(minvalTemp,T,F),false);
        end
        
    else
        % FI datatype not supported
        eml_fi_assert_dataTypeNotSupported('MIN');
    end
    
else
    % [minval,indx] = min(A,[],DIM)
    
    if isscaledtype(x0)
        % Fixed-point FI
        if nargout <= 1
            minval = coder.internal.minOrMax('min',x0,y0,double(dim));
        else
            [minval,iindx] = coder.internal.minOrMax('min',x0,y0,double(dim));
            indx = double(iindx);
        end
    elseif isfloat(x0)
        % True Double or True Single FI
        dType  = eml_fi_getDType(x0);
        x      = eml_cast(x0,dType);
        T      = eml_typeof(x0);
        F      = eml_fimath(x0);
        
        if nargout <= 1
            minval = eml_cast(coder.internal.minOrMax('min',x,y0,double(dim)),T,F);
        else
            [minvalTemp,iindx] = coder.internal.minOrMax('min',x,y0,double(dim));
            indx = double(iindx);
            minval            = eml_cast(minvalTemp,T,F);
        end
    else
        % FI datatype not supported
        eml_fi_assert_dataTypeNotSupported('MIN');
    end
    
end

% LocalWords:  minval indx
