function accblock_utilParameterCheck(blk)
% Check mask dialog parameters for Adaptive Cruise Control System Block.
%
%   Author: Meng Xia, Rong Chen

%   Copyright 2017-2018 The MathWorks, Inc.

%% get parameter values from mask workspace
maskWSVars = get_param(blk,'MaskWSVariables');
blkWSVarNames = {maskWSVars.Name};
G = maskWSVars(strcmp(blkWSVarNames,'EgoModel')).Value;
L0 = maskWSVars(strcmp(blkWSVarNames,'DefaultSpacing')).Value;
vmax = maskWSVars(strcmp(blkWSVarNames,'MaxVelocity')).Value;
amin = maskWSVars(strcmp(blkWSVarNames,'MinAcceleration')).Value;
amax = maskWSVars(strcmp(blkWSVarNames,'MaxAcceleration')).Value;
Ts = maskWSVars(strcmp(blkWSVarNames,'Ts')).Value;
psteps = maskWSVars(strcmp(blkWSVarNames,'PredictionHorizon')).Value;
weightratio = maskWSVars(strcmp(blkWSVarNames,'ControllerBehavior')).Value;
maxiter = maskWSVars(strcmp(blkWSVarNames,'maxiter')).Value;
vel0 = maskWSVars(strcmp(blkWSVarNames,'InitialEgoVelocity')).Value;

%% get default status of checkboxes
amin_ext = strcmp(get_param(blk,'amin_ext'),'on');
amax_ext = strcmp(get_param(blk,'amax_ext'),'on');
suboptimal = strcmp(get_param(blk,'suboptimal'),'off');

%% check parameters

% check on system
checkLinearModel(G)

% check on default spacing L0: non-negative, finite, real, scalar
checkNonnegativeParam(L0,getString(message('MPC:adasblocks:varnameACCDefaultSpacing')))

% check on maximum velocity vmax: positive, finite, real, scalar
checkPositiveParam(vmax,getString(message('MPC:adasblocks:varnameACCMaxVel')))

% check on minimum acceleration amin: negative, finite, real, scalar
if ~amin_ext && ~isempty(amin)
    checkNegativeParam(amin,getString(message('MPC:adasblocks:varnameACCMinAccel')))
end

% check on maximum acceleration amax: non-negative, finite, real, scalar
if ~amax_ext && ~isempty(amax)
    checkNonnegativeParam(amax,getString(message('MPC:adasblocks:varnameACCMaxAccel')))
end
% check on sampling time Ts: non-negative, finite, real, scalar
checkPositiveParam(Ts,getString(message('MPC:adasblocks:varnameACCSampleTime')))

% check on prediction steps psteps: positive, finite, real, scalar
checkPositiveParam(psteps,getString(message('MPC:adasblocks:varnameACCPSteps')))

% check on weight ratio weightratio: between zero and one, finite, real, scalar
checkInRangeParam(weightratio,getString(message('MPC:adasblocks:varnameACCWeight')),0,1)

% check on maximum iteration number maxiter: positive, finite, real, scalar, integer
if ~suboptimal && ~isempty(maxiter)
    checkPositiveParam(maxiter,getString(message('MPC:adasblocks:varnameACCMaxIter')))
end

% check on initial ego longitudinal velocity vel0: non-negative, finite, real, scalar
checkNonnegativeParam(vel0,getString(message('MPC:adasblocks:varnameACCInitEgoVel')))



%% local functions
% Local function: non-negative, finite, real, scalar
function checkNonnegativeParam(var,varname)
if ~(isnumeric(var) && isscalar(var) && isreal(var) && isfinite(var) && (var>=0))
    error((message('MPC:adasblocks:errACCParamNonNegScalarFiniteReal',varname)));
end
   
% Local function: positive, finite, real, scalar
function checkPositiveParam(var,varname)
if ~(isnumeric(var) && isscalar(var) && isreal(var) && isfinite(var) && (var>0))
    error((message('MPC:adasblocks:errACCParamPosScalarFiniteReal',varname)));
end   
   
% Local function: finite, real, scalar
function checkFiniteParam(var,varname)
if ~(isnumeric(var) && isscalar(var) && isreal(var) && isfinite(var))
    error((message('MPC:adasblocks:errACCParamScalarFiniteReal',varname)));
end 

% Local function: negative, finite, real, scalar
function checkNegativeParam(var,varname)
if ~(isnumeric(var) && isscalar(var) && isreal(var) && isfinite(var) && (var<0))
    error((message('MPC:adasblocks:errACCParamNegScalarFiniteReal',varname)));
end

% Local function: finite, real, scalar between min and max values
function checkInRangeParam(var,varname,varmin,varmax)
if ~(isnumeric(var) && isscalar(var) && isreal(var) && isfinite(var) && (var>=varmin) && (var<=varmax))
%     error(['The parameter ''',varname,''' must be a real, finite scalar between ' num2str(varmin) ' and ' num2str(varmax)]);
    error((message('MPC:adasblocks:errACCParamRangeScalarFiniteReal',varname,num2str(varmin),num2str(varmax))));
end

% Local function: model has to be SISO and pass the mpc plant check (see mpcapp.util.checkPlant)
function checkLinearModel(plant)
% check siso
if ~issiso(plant)
    error((message('MPC:adasblocks:errACCLinearModelSize')));
end
%% check tf, zpk, ss or identified model
if ~(any(strcmp(class(plant),{'tf','zpk','ss'})) || isa(plant,'idParametric'))
    error((message('MPC:adasblocks:errACCLinearModelType')));
end
%% check single plant
if length(size(plant))>2
    error((message('MPC:adasblocks:errACCLinearModelNum')));
end
%% check real coefficients
if ~isreal(plant)
    error((message('MPC:adasblocks:errACCLinearModelRealCoeff')));
end
%% check no direct feedthrough 
D = evalfr(plant, inf);
if ~(norm(D,1)==0)
    error((message('MPC:adasblocks:errACCLinearModelNoD')));
end





    
