function hfi = eml_private_sfiufi_constructor(issigned,varargin)
% EML_PRIVATE_SFIUFI_CONSTRUCTOR
%#codegen

%   Copyright 2008-2014 The MathWorks, Inc.

% Always inline
coder.inline('always');
eml_invariant((nargin > 1), 'fixed:coder:notEnoughInputArguments');

coder.extrinsic('eml_sfiufi_constructor_helper');

coder.internal.prefer_const(varargin);

% Check for ambiguous types
if eml_ambiguous_types
    if isnumeric(varargin{1}) || islogical(varargin{1})
        hfi = varargin{1};
    else
        hfi = coder.ignoreConst(0);
    end
    hfi = eml_guessdouble(hfi);
    return;
end

emlInputFimath = eml_fimath;

maxWL = getFixedPointWidthLimit();
% DTO: Get Simulink DTO setting to set fipref accordingly in calls to eml_fi_constructor_helper.
slDTOStr = coder.internal.get_eml_option('FixptDatatypeOverride');
slDTOAppliesToStr = coder.internal.get_eml_option('FixptDatatypeOverrideAppliesTo');
lVar = length(varargin);

for idx = 1:lVar
    if ~isnumeric(varargin{idx})
        eml_invariant(false, 'fixed:coder:inputMustBeNumeric');
    end
end

% Fimath is not local in the ufi & sfi case
isfimathlocal = false;

switch lVar
    case 1 % sfi(val) or sfi(a_fi)
        if isfi(varargin{1}) && ~eml_is_const(varargin{1})
            % non-const fi
            Tin = numerictype(varargin{1});
            data = 0;
            if coder.const(strcmpi(Tin.Scaling,'SlopeBias'))
                [T,F] = coder.const(@eml_sfiufi_constructor_helper,maxWL,slDTOStr,slDTOAppliesToStr,emlInputFimath,issigned,data,Tin.WordLength,Tin.Slope,Tin.Bias);
            else
                [T,F] = coder.const(@eml_sfiufi_constructor_helper,maxWL,slDTOStr,slDTOAppliesToStr,emlInputFimath,issigned,data,Tin.WordLength,Tin.FractionLength);
            end
            hfi = eml_fi_checkforerror(varargin{1},T,F,isfimathlocal);
        elseif eml_is_const(varargin{1});
            [T,F] = coder.const(@eml_sfiufi_constructor_helper,maxWL,slDTOStr,slDTOAppliesToStr,emlInputFimath,issigned,varargin{1});
            hfi = eml_fi_checkforerror(varargin{1},T,F,isfimathlocal);
        elseif isinteger(varargin{1})
            % Cast built-in integer to fi and recurse once
            hfi = eml_private_sfiufi_constructor(issigned,fi(varargin{1}));
            return
        else
            eml_invariant(eml_is_const(varargin{1}), ...
                'fixed:coder:inputMustBeConstantOrAFI', ...
                'v', 'sfi(v), ufi(v)');
        end
    otherwise
        if eml_is_const(varargin{1})
            eml_fi_checkforconst(varargin{2:end});
            [T,F,val] = coder.const(@eml_sfiufi_constructor_helper,maxWL,slDTOStr,slDTOAppliesToStr,emlInputFimath,issigned,varargin{:});
            hfi = eml_fi_checkforerror(val,T,F,isfimathlocal);
        elseif ~isfi(varargin{1}) && isinteger(varargin{1})
            % Cast built-in integer to fi and recurse once
            hfi = eml_private_sfiufi_constructor(issigned,fi(varargin{1}),varargin{2:end});
            return
        else % ~eml_is_const(varargin{1})
            eml_invariant(isnumeric(varargin{1}),...
                'fixed:coder:fiVar1InpMustBeNumericOrAConstant');
            eml_fi_checkforconst(varargin{2:end});
            % Check to see if var2-varN give a numerictype
            % Create some temp data
            if eml_is_const(size(varargin{1}))
                data = zeros(size(varargin{1}));%local_createConstDataFromInput(varargin{1});
            else
                data = 0;
            end
            [T,F,~,isautoscaled] = coder.const(@eml_sfiufi_constructor_helper,maxWL,slDTOStr,slDTOAppliesToStr,emlInputFimath,issigned,data,varargin{2:end});
            hfi = eml_fi_checkforntype(varargin{1},T,F,isautoscaled,isfimathlocal);
        end
end

%------------------------------------------------------------------------------------------------
function data = local_createConstDataFromInput(varin) %#ok unused
% Create const data from varin (a variable input).
% If varin is a fi return a fi of value 0 with the same type a& fimath
% Other wise just return 0.

if isfi(varin)
    data = eml_cast(0,numerictype(varin),fimath(varin));
else
    data = 0;
end
