function utilSelectVariants(sys,dlgSett)
%

%   Copyright 2017-2020 The MathWorks, Inc.

%% Do Not Run code if model is simulating
invalidStatus = {'external','running','compiled','paused','terminating'};
if any(strcmpi(get_param(bdroot(sys),'SimulationStatus'),invalidStatus))
    return
end

%% Determine if PIDN gains are internal or external
if dlgSett.isDialogExternal
    paramSource = 'ExternalParameters';
else
    paramSource = 'InternalParameters';
end

%% Select Summing Junction
% Note: 2DOF Controller does not contain P or I Controller Types and, thus,
% has no passthrough variant(s)
switch dlgSett.Controller
    case 'P'
        set_param(sys,'SumVariant','Passthrough_P')
    case 'I'
        set_param(sys,'SumVariant','Passthrough_I')
    case 'PI'
        set_param(sys,'SumVariant','Sum_PI')
    case 'PD'
        set_param(sys,'SumVariant','Sum_PD')
    case 'PID'
        set_param(sys,'SumVariant','Sum_PID')
end

%% Select Proportional Source
if dlgSett.isDialogProportional
   if dlgSett.Form == 2 % Parallel
       parallelPVariant = paramSource;
       idealPVariant = 'Disabled';
   elseif strcmp(dlgSett.Controller, 'P')
       parallelPVariant = paramSource;
       idealPVariant = 'Disabled';
   elseif dlgSett.Form == 1
       parallelPVariant = 'Passthrough';
       idealPVariant = paramSource;
   end
    
else
    parallelPVariant = 'Disabled';
    idealPVariant = 'Disabled';
end
set_param(sys,'ParallelPVariant',parallelPVariant)
set_param(sys,'IdealPVariant',idealPVariant)

%% Select Integral Source
if dlgSett.isDialogIntegral
    set_param(sys,'IVariant',paramSource)
else
    set_param(sys,'IVariant','Disabled')
end

if dlgSett.isDialogIntegral
    if dlgSett.TimeDomain == 1 % Continuous
       set_param(sys,'IntegratorVariant','Continuous')
    else      % Discrete
        set_param(sys,'IntegratorVariant','Discrete')
    end
else
    set_param(sys,'IntegratorVariant','Disabled')
end

% External Ts for Integral
if dlgSett.isDialogExternalTs
    if dlgSett.isDialogIntegral
        set_param(sys,'TsampIntegralVariant','ExternalTs')
    else
        set_param(sys,'TsampIntegralVariant','Disabled')
    end
else
    if dlgSett.isDialogIntegral
        set_param(sys,'TsampIntegralVariant','Passthrough')
    else
        set_param(sys,'TsampIntegralVariant','Disabled_SignalSpec')
    end
end

%% Select Derivative Source
if dlgSett.isDialogDerivative
    set_param(sys,'DVariant',paramSource)
else
    set_param(sys,'DVariant','Disabled')
end

if dlgSett.isDialogFilter
    if dlgSett.TimeDomain == 1 % Continuous
        set_param(sys,'DerivativeFilterVariant', 'ContFilter');
    elseif dlgSett.FilterMethod == 1 % Forward Euler
        set_param(sys,'DerivativeFilterVariant', 'ForwardEulerFilter');
    elseif dlgSett.FilterMethod == 2 % Backward Euler
        set_param(sys,'DerivativeFilterVariant', 'BackwardEulerFilter');
    elseif dlgSett.FilterMethod == 3 % Trapezoidal
        set_param(sys,'DerivativeFilterVariant', 'TrapezoidalFilter');
    else
        set_param(sys,'DerivativeFilterVariant', 'Disabled');
    end
    
elseif dlgSett.isDialogDerivative && dlgSett.isDialogDiscrete
    set_param(sys,'DerivativeFilterVariant', 'Differentiator');
else
    set_param(sys,'DerivativeFilterVariant', 'Disabled');
end

% External Ts for Derivative
if dlgSett.isDialogDiscrete && dlgSett.isDialogDerivative
    if dlgSett.isDialogExternalTs
        set_param(sys,'TsampFilterVariant','ExternalTs')
    else
        set_param(sys,'TsampFilterVariant','InternalTs')
    end
else
    set_param(sys,'TsampFilterVariant','InternalTs')
end

%% Select Filter Coefficient Source
if dlgSett.isDialogFilter
    set_param(sys,'NVariant',paramSource)
elseif dlgSett.isDialogDifferentiator
    set_param(sys,'NVariant','Passthrough')
else
    set_param(sys,'NVariant','Disabled')
end

if dlgSett.isDialogFilter
    if ~dlgSett.isDialogDiscrete || (dlgSett.isDialogDiscrete && dlgSett.FilterMethod == 1)
        % For internal parameters, the signal for N gain is set in the "N
        % Gain" subsystem so the variant Disabled_SignalSpec does not need
        % to be set here
        set_param(sys,'NCopyVariant','Disabled')
    else
        set_param(sys,'NCopyVariant',paramSource)
    end
else
    set_param(sys,'NCopyVariant','Disabled_SignalSpec')
end

% External Ts for N Gain
if dlgSett.isDialogDiscrete && dlgSett.isDialogDerivative
    if dlgSett.isDialogExternalTs && dlgSett.isDialogFilter &&  dlgSett.FilterMethod == 1
        set_param(sys,'TsampNgainVariant','ExternalTs')
    else
        set_param(sys,'TsampNgainVariant','Passthrough')
    end
else
    set_param(sys,'TsampNgainVariant','Passthrough')
end

%% 2-DOF Sources
if dlgSett.is2DOF
    set_param(sys,'bVariant',paramSource)
    if dlgSett.isDialogDerivative
        set_param(sys,'cVariant',paramSource)
    else
        set_param(sys,'cVariant','Disabled')
    end
end

%% Select Integrator Initial Conditions
if dlgSett.isDialogIntegral
    if dlgSett.isDialogExtICs
        set_param(sys,'IntegratorICVariant','ExternalICs')
    else
        set_param(sys,'IntegratorICVariant','InternalICs')
    end
else
    set_param(sys,'IntegratorICVariant','Disabled')
end

%% Select Derivative Initial Conditions
if dlgSett.isDialogFilter
    if dlgSett.isDialogExtICs
        set_param(sys,'FilterICVariant','ExternalICs')
    else
        set_param(sys,'FilterICVariant','InternalICsFilter')
    end
elseif dlgSett.isDialogDifferentiator
    if dlgSett.isDialogExtICs
         set_param(sys,'FilterICVariant','ExternalICs')
    else
         set_param(sys,'FilterICVariant','InternalICsDifferentiator')
    end
else
    set_param(sys,'FilterICVariant','Disabled')
end

%% Get Active Variants for Integrator/Filter

% Integrator Blocks
intSubsystems = strcat([sys '/Integrator/'],{'Continuous', 'Discrete'});
intBlocks = {'Integrator', 'Integrator'};

% Filter Blocks
filtSubsystems = strcat([sys '/Filter/'],{'Differentiator','Cont. Filter',...
    'Disc. Forward Euler Filter','Disc. Backward Euler Filter',...
    'Disc. Trapezoidal Filter'});
filtBlocks = {'UD','Filter','Filter','Filter Differentiator TF',...
    'Filter Differentiator TF'};
filtICParamName = {'InitialConditionSource','InitialConditionSource',...
    'InitialConditionSource','InitialStatesSource','InitialStatesSource'};
filtICSettingsExt = {'Input Port', 'external','external','Input Port','Input Port','Input Port'};
filtICSettingsInt = {'Dialog', 'internal','internal','Dialog','Dialog','Dialog'};
filtResetPorts = [2 2 2 3 3];

% Get active variant for integrator
if dlgSett.isDialogIntegral
    if dlgSett.isDialogDiscrete
        activeVariantIntegrator = 2;
    else
        activeVariantIntegrator = 1;
    end
else
    activeVariantIntegrator = 0;
end

% Get active variant for filter
if dlgSett.isDialogDifferentiator
    activeVariantFilter = 1;
elseif dlgSett.isDialogDiscreteFilter
    if dlgSett.FilterMethod==1 % Forward Euler
        activeVariantFilter = 3;
    elseif dlgSett.FilterMethod==2 % Backward Euler
        activeVariantFilter = 4;
    else % Trapezoidal
        activeVariantFilter = 5;
    end
elseif dlgSett.isDialogFilter % Continuous
    activeVariantFilter = 2;
else
    activeVariantFilter = 0;
end

%% Select Reset
set_param([sys '/Reset Signal/Out1'],'OutDataTypeStr','Inherit: auto')
set_param([sys '/Integrator/Reset'],'OutDataTypeStr','Inherit: auto')
set_param([sys '/Integrator/Disabled/Reset'],'OutDataTypeStr','Inherit: auto')
if dlgSett.isDialogExtReset
    set_param(sys,'ExternalResetVariant','ExternalReset')
    portOffset = 1;
else
    set_param(sys,'ExternalResetVariant','Disabled')
    portOffset = 0;
end
blkReset = get_param(sys,'ExternalReset');

%% Connect Reset for integrator
% Only do set param on active variant due to possible Sample Time Issues
activeVariant = activeVariantIntegrator;
if activeVariant
    currBlock = horzcat(intSubsystems{activeVariant},'/',intBlocks{activeVariant});
    if dlgSett.isDialogExtReset
        set_param(currBlock,'ExternalReset',blkReset)
        try %#ok<TRYNC>
            add_line(intSubsystems{activeVariant},'Reset/1',[intBlocks{activeVariant} '/2'],'autorouting','on')
        end
    else
        try %#ok<TRYNC>
            delete_line(intSubsystems{activeVariant},'Reset/1',[intBlocks{activeVariant} '/2'])
        end
        set_param(currBlock,'ExternalReset','none')
    end
end

%% Connect Reset for filter
% Only do set param on active variant due to possible Sample Time Issues
activeVariant = activeVariantFilter;
if activeVariant
    port = horzcat('/',num2str(filtResetPorts(activeVariant)));
    currBlock = horzcat(filtSubsystems{activeVariant},'/',filtBlocks{activeVariant});
    if dlgSett.isDialogExtReset
        set_param(currBlock,'ExternalReset',blkReset)
        try %#ok<TRYNC>
            add_line(filtSubsystems{activeVariant},'Reset/1',[filtBlocks{activeVariant} port],'autorouting','on')
        end
    else
        try %#ok<TRYNC>
            delete_line(filtSubsystems{activeVariant},'Reset/1',[filtBlocks{activeVariant} port])
        end
        set_param(currBlock,'ExternalReset','none')
    end
end


%% Enable/Disable external initial conditions for the integrator blocks

% Only do set param on active variant due to possible Sample Time Issues
activeVariant = activeVariantIntegrator;
if activeVariant
    port = horzcat('/',num2str(2 + portOffset));
    currBlock = horzcat(intSubsystems{activeVariant},'/',intBlocks{activeVariant});
    if dlgSett.isDialogExtICs
        set_param(currBlock,'InitialConditionSource','external')
        try %#ok<TRYNC>
            add_line(intSubsystems{activeVariant},'I0in/1',[intBlocks{activeVariant} port],'autorouting','on')
        end
    else
        try %#ok<TRYNC>
            delete_line(intSubsystems{activeVariant},'I0in/1',[intBlocks{activeVariant} port])
        end
        set_param(currBlock,'InitialConditionSource','internal')
    end
end

%% Enable/Disable external initial conditions for the filter blocks

% Connect/Disconnect External IC Port for Filter
activeVariant = activeVariantFilter;
if activeVariant
    port = horzcat('/',num2str(filtResetPorts(activeVariant) + portOffset));
    currBlock = horzcat(filtSubsystems{activeVariant},'/',filtBlocks{activeVariant});
    if dlgSett.isDialogExtICs
        set_param(currBlock,filtICParamName{activeVariant},filtICSettingsExt{activeVariant})
        try %#ok<TRYNC>
            add_line(filtSubsystems{activeVariant},'D0in/1',[filtBlocks{activeVariant} port],'autorouting','on')
        end
    else
        try %#ok<TRYNC>
            delete_line(filtSubsystems{activeVariant},'D0in/1',[filtBlocks{activeVariant} port])
        end
        set_param(currBlock,filtICParamName{activeVariant},filtICSettingsInt{activeVariant})
    end
end
