% static method
function dialogCallback( subCallback, varargin )

%   Copyright 2014-2018 The MathWorks, Inc.

    switch lower(subCallback)
        case {'codingstandards'}
            codingStandards(varargin{:});
        case {'floatingpoint'}
            floatingPoint(varargin{:});
        case {'noresetsim'}
            noresetSimSupport(varargin{:});
        case {'scalarizeports'}
            scalarizePorts(varargin{:});
        otherwise
            error('Invalid widget callback requested');
    end
end

function scalarizePorts(hObjCLI, hDlg, tag)
val = hDlg.getWidgetValue(tag);

switch val
    case 0
        valStr = 'off';
    case 1
        valStr = 'on';
    case 2
         valStr = 'DUTLevel';
    otherwise
        error('Invalid option for Scalarize Ports');
end
 hObjCLI.ScalarizePorts = valStr;

end

function noresetSimSupport(hObjCLI, hDlg, tag)
val = hDlg.getWidgetValue(tag);

switch val
    case 0
        valStr = 'None';
    case 1
        valStr = 'Script';
    case 2
         valStr = 'InsideModule';
    otherwise
        error('Invalid option generated during Native floating-point global settings widget action');
end
 hObjCLI.NoResetInitializationMode = valStr;

end
function floatingPoint( hObjCLI, hDlg, tag )
    fc = hObjCLI.FloatingPointTargetConfiguration;
    switch tag
        case {'ConfigSet_HDLCoder_FloatingPointPanel_FloatingPointLib'}
            val = hDlg.getWidgetValue(tag);
            switch val
                case 0 % {'None'}
                    fc = [];
                case 1 % {'Native Floating Point'}
                    if(isempty(fc) || ~strcmpi(fc.Library, 'NATIVEFLOATINGPOINT'))
                        fc = hdlcoder.createFloatingPointTargetConfig('NativeFloatingPoint');
                    end
                case 2 % {'Altera Megafunctions (ALTERA FP)'}
                    if(isempty(fc) || ~strcmpi(fc.Library, 'ALTERAFPFUNCTIONS'))
                        fc = hdlcoder.createFloatingPointTargetConfig('ALTERAFPFUNCTIONS');
                    end
                case 3 % {'Altera Megafunctions (ALTFP)'}
                    if(isempty(fc) || ~strcmpi(fc.Library, 'ALTFP'))
                        fc = hdlcoder.createFloatingPointTargetConfig('ALTFP');
                    end
                case 4 % {'Xilinx LogiCORE'}
                    if(isempty(fc) || ~strcmpi(fc.Library, 'XILINXLOGICORE'))
                        fc = hdlcoder.createFloatingPointTargetConfig('XILINXLOGICORE');
                    end
                otherwise
                    error('Invalid option generated during Native floating-point global settings widget action');
            end
            hObjCLI.FloatingPointTargetConfiguration = fc;
        case {'ConfigSet_HDLCoder_FloatingPointPanel_LatencyStrategy'}
            val = hDlg.getWidgetValue(tag);
            switch val
                case 0 % {'MIN'}
                    ls = 'MIN';
                case 1 % {'MAX'}
                    ls = 'MAX';
                otherwise
                    error('Invalid option generated during Native floating-point global settings widget action');
            end
            fc.LibrarySettings.LatencyStrategy = ls;
       case {'ConfigSet_HDLCoder_FloatingPointPanel_NFPLatencyStrategy'}
            val = hDlg.getWidgetValue(tag);
            switch val
                case 0 % {'MAX'}
                    ls = 'Max';
                case 1 % {'MIN'}
                    ls = 'Min';
                case 2 % {'ZERO'}
                    ls = 'Zero';
                otherwise
                    error('Invalid option generated during Native floating-point global settings widget action');
            end
            fc.LibrarySettings.LatencyStrategy = ls;
       case {'ConfigSet_HDLCoder_FloatingPointPanel_NFPAlgoMultStrategy'}
            val = hDlg.getWidgetValue(tag);
            switch val
                case 0 
                    ls = 'Auto';
                case 1 
                    ls = 'FULLMULTIPLIER';
                case 2 
                    ls = 'PARTMULTIPLIERPARTADDSHIFT';
                case 3 
                    ls = 'NOMULTIPLIERFULLADDSHIFT';
                otherwise
                    assert(false);
            end
            fc.LibrarySettings.MantissaMultiplyStrategy = ls;
        case {'ConfigSet_HDLCoder_FloatingPointPanel_Objective'}
            val = hDlg.getWidgetValue(tag);
            switch val
                case 0 % {'NONE'}
                    ls = 'NONE';
                case 1 % {'SPEED'}
                    ls = 'SPEED';
                case 2 % {'AREA'}
                    ls = 'AREA';
                otherwise
                    error('Invalid option generated during Native floating-point global settings widget action');
            end
            fc.LibrarySettings.Objective = ls;
        case {'ConfigSet_HDLCoder_FloatingPointPanel_HandleDenormals'}
            val = hDlg.getWidgetValue(tag);
            switch val
                case 0 % {'NO'}
                    ls = 'off';
                case 1 % {'YES'}
                    ls = 'on';
                otherwise
                    error('Invalid option generated during Native floating-point global settings widget action');
            end
            fc.LibrarySettings.HandleDenormals = ls;
        case {'ConfigSet_HDLCoder_FloatingPointPanel_Frequency'}
            val = hDlg.getWidgetValue(tag);
            hObjCLI.TargetFrequency = str2double(val);
        case {'ConfigSet_HDLCoder_FloatingPointPanel_InitLogic'}
            val = hDlg.getWidgetValue(tag);
            fc.LibrarySettings.InitializeIPPipelinesToZero = val;
        case {'ConfigSet_HDLCoder_FloatingPointPanel_DataTypeInsert'}
            val = hDlg.getWidgetValue('ConfigSet_HDLCoder_FloatingPointPanel_DataTypeString');
            newfc = fc.copy();
            newfc.IPConfig.customizeOrInsert('Convert', val);
            hObjCLI.FloatingPointTargetConfiguration = newfc;
    end
end

% s.InputTypes = {'handle', 'handle', 'string','handle', 'string'};
%               %     this,    hCSO,  property,    hDlg,     tag
function codingStandards(hCSO, property, hDlg, tag)   
   function [flag,arg,err] = positive_only( arg )
        flag = true; err = [];
        if ( any([arg <= 0,isinf(arg),isnan(arg),~isnumeric(arg)]) )
            flag = false;
            err = message('HDLShared:hdldialog:CannotBeNegative');
        end
   end
   
   function [flag,arg,err] = positive_or_0( arg )
        flag = true; err = [];
        if ( any([arg < 0,isinf(arg),isnan(arg),~isnumeric(arg)]) )
            flag = false;
            err = message('HDLShared:hdldialog:CannotBeNegative');
        end
    end

    function [flag,arg,err] = positive_min_max( arg )
        flag = true; err = [];
        if ( any([arg < 0,isinf(arg),isnan(arg),~isnumeric(arg)] ) )
            flag = false;
            err = message('HDLShared:hdldialog:CannotBeNegative');
            return;
        end
        %min and max are positionally encoded
        min_val = arg(1);
        max_val = arg(2);
        if ( min_val >= max_val )
            flag = false;
            err = message('HDLShared:hdldialog:CannotBeMinMax');
            return;
        elseif ( min_val <= 0 ) 
            flag = false;
            err = message('HDLShared:hdldialog:CannotBeNegative');
            return;
        end
    end

    cmntag = 'ConfigSet_HDLCoder_GlbSettingsPanel_CodingStandards_';

    % munge : FilterPassingRules -> ShowPassingRules and NEGATVE value
    
    if ( strcmpi(property,'FilterPassingRules') )
        property = 'ShowPassingRules';
        hCSO.(property).enable = ~ hDlg.getWidgetValue( tag );
    else
        hCSO.(property).enable = hDlg.getWidgetValue( tag );
    end
    

    switch( property )

        %% 2-param properties
        case 'ModuleInstanceEntityNameLength'
            min_length = hDlg.getWidgetValue([cmntag,'ModuleInstanceEntityNameLength_min']);
            max_length = hDlg.getWidgetValue([cmntag,'ModuleInstanceEntityNameLength_max']);
            [flag,min_max,err] = positive_min_max([str2double(min_length), str2double(max_length)]);
            if ( flag )
                hCSO.(property).length = min_max;
            else
                min_max = hCSO.(property).length;
                hDlg.setWidgetValue([cmntag,'ModuleInstanceEntityNameLength_min'],num2str(min_max(1)));
                hDlg.setWidgetValue([cmntag,'ModuleInstanceEntityNameLength_max'],num2str(min_max(2)));
                error( err );
                return;
            end

        case 'SignalPortParamNameLength'
            min_length = hDlg.getWidgetValue([cmntag,'SignalPortParamNameLength_min']);
            max_length = hDlg.getWidgetValue([cmntag,'SignalPortParamNameLength_max']);
            
            [flag,min_max,err] = positive_min_max([str2double(min_length), str2double(max_length)]);            
            if ( flag )
                hCSO.(property).length = min_max;
            else
                min_max = hCSO.(property).length;
                hDlg.setWidgetValue([cmntag,'SignalPortParamNameLength_min'],num2str(min_max(1)));
                hDlg.setWidgetValue([cmntag,'SignalPortParamNameLength_max'],num2str(min_max(2)));
                error( err );
                return;
            end

        %% 1-param properties
        case 'MultiplierBitWidth'
            mul_width = hDlg.getWidgetValue([cmntag,'MultiplierBitWidth_width']);
            [flag,mul_width_str,err] = positive_only( str2double( mul_width ) );
            if ( flag )
                hCSO.(property).width = mul_width_str;
            else
                mul_width = hCSO.(property).width;
                hDlg.setWidgetValue([cmntag,'MultiplierBitWidth_width'],num2str(mul_width));
                error( err );                
            end

        case 'LineLength'
            line_length = hDlg.getWidgetValue([cmntag,'LineLength_length']);
            [flag,line_length,err] = positive_only( str2double( line_length ) );
            if ( flag )
                hCSO.(property).length = line_length;
            else
                line_length = num2str( hCSO.(property).length );
                hDlg.setWidgetValue([cmntag,'LineLength_length'],num2str(line_length));
                error( err );                
            end
        case 'IfElseChain'
            chain_length = hDlg.getWidgetValue([cmntag,'IfElseChain_length']);

            [flag,param,err]=positive_or_0( str2double( chain_length ) );

            if ( flag )
                hCSO.(property).length = param;
            else
                param = hCSO.(property).length;
                hDlg.setWidgetValue([cmntag,'IfElseChain_length'],num2str(param));
                error( err );                
            end
        
        case 'ConditionalRegionCheck'
            condregion_length = hDlg.getWidgetValue([cmntag,'ConditionalRegionCheck_length']);
            
            [flag,param,err]=positive_or_0( str2double( condregion_length ) );

            if ( flag )
                hCSO.(property).length = param;
            else
                param = hCSO.(property).length;
                hDlg.setWidgetValue([cmntag,'IfElseChain_length'],num2str(param));
                error( err );                
            end
        
        case 'IfElseNesting'
            chain_depth = hDlg.getWidgetValue([cmntag,'IfElseNesting_depth']);

            [flag,param,err]=positive_or_0( str2double( chain_depth ) );

            if ( flag )
                hCSO.(property).depth = param;
            else
                param = hCSO.(property).depth;
                hDlg.setWidgetValue([cmntag,'IfElseNesting_depth'],num2str(param));
                error( err );                
            end
            
        %% 0-param properties - only enable property - others are good
        otherwise
            %disp(['parameter ',property,' does not have additional tunability.'])
%         case 'MinimizeVariableUsage'
%         case 'NonIntegerTypes'
%         case 'HDLKeywords'
%         case 'InitialStatements'
%         case 'DetectDuplicateNamesCheck'
%         case 'ShowPassingRules'

        %% hidden properties
        %{'RulesBasicCodingPractices',
        %'RulesRTLDescriptionTechniques',
        % 'RulesDesignMethodologyGuidelines'}

    end    
end

% LocalWords:  codingstandards floatingpoint Glb FP ALTERAFPFUNCTIONS ALTFP
% LocalWords:  XILCOREGEN CSO munge NEGATVE
