function commblkampmod(block, action, varargin)
% COMMBLKAMPMOD Mask helper function for amplitude modulation blocks.
%   VARARGOUT = COMMBLKAMPMOD(BLOCK, ACTION, VARARGIN) passes in BLOCK as
%   the current block, ACTION as the desired block action to perform, and
%   VARARGIN as optional arguments to complete the action.

%   Copyright 1996-2015 The MathWorks, Inc.

%**************************************************************************
% Switch on ACTION to determine which of the callback functions to execute
%**************************************************************************
switch action
    case 'dsbmodinit'
        % If called by DSB block, only check Offset parameter. The other
        % parameters will be checked by DSBSC block.
        if (nargin == 3)
            Offset = varargin{1};
            if (~isnumeric(Offset) || ~isreal(Offset) || ~isscalar(Offset))
                error(message('comm:commblkampmod:InvalidInpSigOffset'));
            end
            return;
        end
        
        [Fc, Ph] = deal(varargin{:});
        isRealPositiveScalar(Fc,Ph);
        
    case  'ssbmodinit'
        [Fc, Ph, Ho] = deal(varargin{:});
        
        % Check block parameters 
        isRealPositiveScalar(Fc,Ph);
        
        if (~isnumeric(Ho) || ~isreal(Ho) || ~isscalar(Ho) ||...
                 mod(Ho,2) || (Ho <= 2)) 
            error(message('comm:commblkampmod:InvalidFilterOrder'));
        end

        
  case 'dsbdemodinit'
    % If called by DSB block, only check Offset parameter. The other
    % parameters will be checked by DSBSC block.
    if (nargin == 3)
        Offset = varargin{1};
        % required for g316522 fix  
        feval(mfilename,block,'dynamic', 1);
        if (~isnumeric(Offset) || ~isreal(Offset) || ~isscalar(Offset))
            error(message('comm:commblkampmod:InpSigOffsetNotScalar'));
        end
        % Update the filter method of the underlying DSBSC block
        set_param([block, '/DSBSC AM Demodulator Passband'], ...
                  'method', get_param(block, 'method'));
        return;
    end
    
    % required for g316522 fix  
    feval(mfilename,block,'dynamic', 0);
    
    [Fc, Ph, method, n, cf, Rp, Rs] = deal(varargin{:});
                
        % Check block parameters
        isRealPositiveScalar(Fc,Ph);
        
        if (~isnumeric(n) || ~isreal(n) || ~isscalar(n) || ... 
                (ceil(n) ~= n) || (n < 0)) 
            error(message('comm:commblkampmod:FilterOrdNotAnInt'));
        end
        
        if (~isnumeric(cf) || ~isreal(cf) || ~isscalar(cf) || (cf < 0)) 
            error(message('comm:commblkampmod:InvalidCutOffFreq'));
        end

        % Obtain the Sample Time 
        Ts = get_param(gcb,'compiledSampleTime');
        if iscell(Ts)
            if ((length(Ts) == 2) && Ts{2}(1) == inf)
                sampleTime = Ts{1}(1);
            else 
                error(message('comm:commblkampmod:InternalErrorMultiRateBlock'));
            end
        else
            sampleTime = Ts(1);
        end
        
        % Note: The filter is designed if and when the filter block is NOT
        %       virtual, i.e., 
        %       isNotFilterVirtual = strcmp(...
        %                get_param([block '/Discrete Filter'],'Virtual'),'off');
        %       is 'true'
    
        isNotFilterVirtual = strcmp(... 
            get_param([block, '/Discrete Filter'],'Virtual'),'off');
        if isNotFilterVirtual
            % Design lowpass filter based on method selected
            switch method
                case 'Butterworth'

                    % Only specify the filter coefficients if we have a sample time
                    % bigger than 0. This is to avoid errors earlier on when the sample
                    % time is not yet available such as on opening of the model.

                    if (sampleTime > 0)
                        [b,a] = butter(n,cf*sampleTime*2);
                    else
                        %Set default number of coefficients of the filter equal 
                        %to thecurrent mask variable (n). The filter block
                        %does not allow changing the number of coefficients of 
                        %the filter at run time, only their values.
                        [b,a] = butter(n,0.01);
                    end

                    Hd = dfilt.df2(b,a);
                    set_param([block, '/Discrete Filter'],'Numerator',mat2str(Hd.Numerator));
                    set_param([block, '/Discrete Filter'],'Denominator',mat2str(Hd.Denominator));

                case 'Chebyshev I'
                    if (~isnumeric(Rp) || ~isreal(Rp) || ~isscalar(Rp) || ...
                            (Rp <= 0))
                        error(message('comm:commblkampmod:InvalidPassBandRipple'));
                    end

                    % Only specify the filter coefficients if we have a sample time
                    % bigger than 0. This is to avoid errors earlier on when the sample
                    % time is not yet available such as on opening of the model.

                    if (sampleTime > 0)
                        [b,a] = cheby1(n,Rp,cf*sampleTime*2);
                    else
                        %Set default number of coefficients of the filter equal 
                        %to thecurrent mask variable (n). The filter block
                        %does not allow changing the number of coefficients of 
                        %the filter at run time, only their values.
                        [b,a] = cheby1(n,Rp,0.01);
                    end

                    Hd = dfilt.df2(b,a);
                    set_param([block, '/Discrete Filter'],'Numerator',mat2str(Hd.Numerator));
                    set_param([block, '/Discrete Filter'],'Denominator',mat2str(Hd.Denominator));

                case 'Chebyshev II'

                    if (~isnumeric(Rs) || ~isreal(Rs) || ~isscalar(Rs) || ...
                            (Rs <= 0))
                        error(message('comm:commblkampmod:InvalidStopBandAtten'));
                    end

                    % Only specify the filter coefficients if we have a sample time
                    % bigger than 0. This is to avoid errors earlier on when the sample
                    % time is not yet available such as on opening of the model.

                    if (sampleTime > 0)
                        [b,a] = cheby2(n,Rs,cf*sampleTime*2);
                    else
                        %Set default number of coefficients of the filter equal 
                        %to thecurrent mask variable (n). The filter block
                        %does not allow changing the number of coefficients of 
                        %the filter at run time, only their values.
                        [b,a] = cheby2(n,Rs,0.01);
                    end

                    Hd = dfilt.df2(b,a);
                    set_param([block, '/Discrete Filter'],'Numerator',mat2str(Hd.Numerator));
                    set_param([block, '/Discrete Filter'],'Denominator',mat2str(Hd.Denominator));

                case 'Elliptic'

                    if (~isnumeric(Rp) || ~isreal(Rp) || ~isscalar(Rp) || ...
                            (Rp <= 0))
                        error(message('comm:commblkampmod:InvalidPassBandRipple'));
                    end
                    if (~isnumeric(Rs) || ~isreal(Rs) || ~isscalar(Rs) || ...
                            (Rs <= 0))
                        error(message('comm:commblkampmod:InvalidStopBandAtten'));
                    end

                    % Only specify the filter coefficients if we have a sample time
                    % bigger than 0. This is to avoid errors earlier on when the sample
                    % time is not yet available such as on opening of the model.

                    if (sampleTime > 0)
                        [b,a] = ellip(n,Rp,Rs,cf*sampleTime*2);
                    else
                        %Set default number of coefficients of the filter equal 
                        %to thecurrent mask variable (n). The filter block
                        %does not allow changing the number of coefficients of 
                        %the filter at run time, only their values.
                        [b,a] = ellip(n,Rp,Rs,0.01);
                    end

                    Hd = dfilt.df2(b,a);
                    set_param([block, '/Discrete Filter'],'Numerator',mat2str(Hd.Numerator));
                    set_param([block, '/Discrete Filter'],'Denominator',mat2str(Hd.Denominator));
                    
            end
        else % Discrete Filter is a virtual block (there is no point of designing the filter)
            return;
        end
        

    % Depending on the filter method, display or hide the prompt for
    % passband ripple
    case 'dynamic'
        mask_visibilities = get_param(block, 'maskvisibilities');     
        mask_en = get_param(block, 'maskenables');     
        method = get_param(block, 'method');
        
        % Position of the passband ripple and stopband attenuation prompt
        % can vary for DSB, DSBSC
        pos = varargin{1};
        
        if(strcmp(method, 'Chebyshev I')) 
            mask_visibilities{6+pos} = 'on';
            mask_en{6+pos} = 'on';
            mask_visibilities{7+pos} = 'off';
            mask_en{7+pos} = 'off';

        elseif(strcmp(method, 'Chebyshev II'))
            mask_visibilities{6+pos} = 'off';
            mask_en{6+pos} = 'off';
            mask_visibilities{7+pos} = 'on';
            mask_en{7+pos} = 'on';

        elseif(strcmp(method, 'Elliptic'))
            mask_visibilities{6+pos} = 'on';
            mask_en{6+pos} = 'on';
            mask_visibilities{7+pos} = 'on';
            mask_en{7+pos} = 'on';

        else
            mask_visibilities{6+pos} = 'off';
            mask_en{6+pos} = 'off';
            mask_visibilities{7+pos} = 'off';
            mask_en{7+pos} = 'off';
        end
        
        set_param(block, 'maskvisibilities', mask_visibilities,...
                'maskEnables', mask_en);
end
    

function isRealPositiveScalar(Fc,Ph)
% isRealPositiveScalar Mask helper function for amplitude modulation blocks.
%  Validates Carrier Frequencies and Phase  
        
% Check block parameters
if (~isnumeric(Fc) || ~isreal(Fc) || ~isscalar(Fc) || (Fc < 0))
    error(message('comm:commblkampmod:InvalidCarrierFreq'));
end
        
if (~isnumeric(Ph) || ~isreal(Ph) || ~isscalar(Ph)) 
    error(message('comm:commblkampmod:InvalidIniPhase'));
end

% End isRealPositiveScalar
 
% EOF - commblkampmod.m
