function schema = slcontrolmenus(fncname,cbinfo)%
%

%   Copyright 2010-2019 The MathWorks, Inc.
    fnc = str2func(fncname);
    if nargout(fnc)
        schema = fnc(cbinfo);
    else
        schema = [];
        fnc(cbinfo);
    end
end

function res = LocalCheckLicense()
    res = license('test','Simulink_Control_Design') && license('test','Control_Toolbox');
end

function state = LocalGetControlDesignItemState(~)
    if LocalCheckLicense()
        state = 'Enabled';
    else
        state = 'Disabled';
    end
end

function res = LocalCheckControlSystemTunerInstallation() %#ok<DEFNU>
      res = ~isempty(ver('control')) && ...
          ~isempty(ver('slcontrol')) && ...
          LocalCheckControlSystemTunerLicense();
end

function res = LocalCheckControlSystemTunerLicense()
      res = license('test','Simulink_Control_Design') && ...
          license('test','Control_Toolbox');
end

function state = LocalGetControlSystemTunerItemState(~)
    if LocalCheckControlSystemTunerLicense()
        state = 'Enabled';
    else
        state = 'Disabled';
    end
end

function schema = LinearizationManager(cbinfo) %#ok<DEFNU>
    schema = DAStudio.ActionSchema;
    schema.tag      = 'Slcontrol:LinearizationManager';
    schema.label = DAStudio.message('Slcontrol:linmenus:LinearizationManager');
    schema.state    = LocalGetControlDesignItemState( cbinfo );
    schema.callback = @LinearizationManagerCB;
    schema.autoDisableWhen = 'Busy';
end

function LinearizationManagerCB(cbinfo)
    SLStudio.toolstrip.internal.toggleAppCB('linearizationPointsApp',cbinfo);
end

function schema = SteadyState(cbinfo) %#ok<DEFNU>
    schema = DAStudio.ActionSchema;
    schema.tag      = 'Slcontrol:SteadyState';
    if SLStudio.Utils.showInToolStrip(cbinfo) % from the toolstrip
        schema.label = 'Slcontrol:toolstrip:SteadyStateTS';
    else
        schema.label = DAStudio.message('Slcontrol:linmenus:SteadyStateMenu');
    end
    schema.state    = LocalGetControlDesignItemState( cbinfo );
    schema.callback = @SteadyStateCB;
    schema.autoDisableWhen = 'Busy';
end

function SteadyStateCB(cbinfo)
    mdl = cbinfo.model.Name;
    slctrlguis.steadystatesolver.launchSteadyStateSolver(mdl);
end

function schema = LinearAnalysis(cbinfo) %#ok<DEFNU>
    schema = DAStudio.ActionSchema;
    schema.tag      = 'Slcontrol:LinearAnalysis';
    if SLStudio.Utils.showInToolStrip(cbinfo) % from the toolstrip
        schema.label = 'Slcontrol:toolstrip:LinearAnalysisTS';
    else
        schema.label = DAStudio.message('Slcontrol:linmenus:LinearAnalysisMenu');
    end
    schema.state    = LocalGetControlDesignItemState( cbinfo );
    schema.callback = @LinearAnalysisCB;
    schema.autoDisableWhen = 'Busy';
end

function LinearAnalysisCB(cbinfo)
    simcontdesigner('initialize_linearize',cbinfo.model.Name);
end

function schema = FrequencyResponseEstimation(cbinfo) %#ok<DEFNU>
    schema = DAStudio.ActionSchema;
    schema.tag      = 'Slcontrol:FrequencyResponseEstimation';
    if SLStudio.Utils.showInToolStrip(cbinfo) % from the toolstrip
        schema.label = 'Slcontrol:toolstrip:FrequencyResponseEstimationTS';
    else
        schema.label = DAStudio.message('Slcontrol:linmenus:FrequencyResponseEstimationMenu');
    end
    schema.state    = LocalGetControlDesignItemState( cbinfo );
    schema.callback = @FrequencyResponseEstimationCB;
    schema.autoDisableWhen = 'Busy';
end

function FrequencyResponseEstimationCB(cbinfo)
    simcontdesigner('initialize_frestimate',cbinfo.model.Name);
end

function schema = CompensatorDesign( cbinfo ) %#ok<DEFNU>
    schema = sl_action_schema;
    schema.tag      = 'Slcontrol:CompensatorDesign';
    schema.label    = DAStudio.message('Slcontrol:linmenus:CompensatorDesignMenu');
    schema.state = LocalGetControlDesignItemState( cbinfo );
    
    schema.callback = @CompensatorDesignCB;
    schema.autoDisableWhen = 'Busy';
end

function CompensatorDesignCB( cbinfo )
Version = controllibutils.CSTCustomSettings.getControlSystemDesignerVersion;
if Version == 1
    simcontdesigner('initialize_controller_design', cbinfo.model.Name );
else
    w = warning('off','Slcontrol:sllinearizer:AddPointOpening');
    ST = slTuner(cbinfo.model.Name);
    warning(w);
    controlSystemDesigner(ST);
end
end

function schema = ControlSystemTuner( cbinfo ) %#ok<DEFNU>
    schema = sl_action_schema;
    schema.tag      = 'Slcontrol:ControlSystemTuner';
    schema.label    = DAStudio.message('Slcontrol:linmenus:ControlSystemTunerMenu');
    schema.state = LocalGetControlSystemTunerItemState( cbinfo );
    
    schema.callback = @ControlSystemTunerCB;
    schema.autoDisableWhen = 'Busy';
end

function ControlSystemTunerCB( cbinfo )
    controlSystemTuner( cbinfo.model.Name );
end

function state = loc_getLinearizeBlockState( cbinfo )
    if exist('simcontdesigner', 'file') == 2
        block = SLStudio.Utils.getOneMenuTarget( cbinfo );
        if SLStudio.Utils.objectIsValidBlock( block )
            state = LocalGetControlDesignItemState( cbinfo );
            % disable if the block linearization menu should be disabled
            if strcmp(state,'Enabled')
                state = loc_getBlockLinearAnalysisMenuState( cbinfo );
            end
        else
            state = 'Disabled';
        end
    else
        state = 'Disabled';
    end
end

function schema = LinearizeBlockDisabled( cbinfo )
    schema = sl_action_schema;
    schema.tag      = 'Slcontrol:LinearizeBlock';
    if strcmp(cbinfo.userdata,'Slcontrol:LinearizeBlock') % from the toolstrip
        schema.label = 'Slcontrol:toolstrip:LinearizeBlockTS';
    else
        schema.label = DAStudio.message('Slcontrol:linmenus:LinearizeBlockMenu');
    end
    schema.state = 'Disabled';
    schema.autoDisableWhen = 'Busy';
end

function schema = LinearizeBlock( cbinfo ) %#ok<DEFNU>
    schema = LinearizeBlockDisabled( cbinfo );
    schema.state = loc_getLinearizeBlockState( cbinfo );
    schema.callback = @LinearizeBlockCB;
end

function LinearizeBlockCB( cbinfo )
    block = SLStudio.Utils.getOneMenuTarget( cbinfo );
    if SLStudio.Utils.objectIsValidBlock( block )
        simcontdesigner( 'linearizeblock', cbinfo.model.Name, block.getFullPathName );
    end
end

function state = loc_getBlockLinearizeSpecificationState( cbinfo )
    block = SLStudio.Utils.getOneMenuTarget( cbinfo );
    if SLStudio.Utils.objectIsValidBlock( block )
        state = loc_getLinearizeBlockState( cbinfo );
        % disable if the block linearization menu should be disabled
        if strcmp(state,'Enabled')
            state = loc_getBlockLinearAnalysisMenuState( cbinfo );
        end
    else
        state = 'Disabled';
    end
end

function schema = BlockLinearizeSpecificationDisabled( cbinfo )
    schema = sl_action_schema;
    schema.tag      = 'Slcontrol:BlockLinearizeSpecification';
    if strcmp(cbinfo.userdata,'Slcontrol:BlockLinearizeSpecification') % from the toolstrip
        schema.label = 'Slcontrol:toolstrip:BlockLinearizeSpecificationTS';
    else
        schema.label = DAStudio.message('Slcontrol:linmenus:BlockLinearizeSpecificationMenu');
    end
    schema.state    = 'Disabled';
    schema.autoDisableWhen = 'Busy';
end

function schema = BlockLinearizeSpecification( cbinfo ) %#ok<DEFNU>
    schema = BlockLinearizeSpecificationDisabled( cbinfo );
    schema.state = loc_getBlockLinearizeSpecificationState( cbinfo );
    schema.callback = @BlockLinearizeSpecificationCB;
end

function BlockLinearizeSpecificationCB( cbinfo )
    block = SLStudio.Utils.getOneMenuTarget( cbinfo );
    if SLStudio.Utils.objectIsValidBlock( block )
        slctrlguis.LinearizationSpecificationDialog.getInstance( block.getFullPathName );
    end           
end

function val = LocalGetLinearizeSignalMenuState( cbinfo )
val = 'Disabled';
if strcmpi( LocalGetControlDesignItemState( cbinfo ), 'Enabled' )
    if (strcmpi ('Enabled', LocalGetLinearizationPointEnabled( cbinfo )))
        portH = LocalGetCurrentSelectedOutputPort(cbinfo);
        if(~isempty(portH))
            if cbinfo.queryMenuAttribute('Simulink:LinearizeSignalMenu', '', portH )
                val = 'Enabled';
            end
        end
    end
end
end

function val = LocalGetLinearizationPointEnabled( cbinfo )
    val = 'Disabled';
    lin = SLStudio.Utils.getSingleSelectedLine( cbinfo );
    if ( SLStudio.Utils.objectIsValidLine( lin ))
        srcPort = SLStudio.Utils.getLineSourcePort( lin );        
        bd_isLocked = SLStudio.Utils.isLockedSystem( cbinfo );
        bd_isCompiled = SLStudio.Utils.isBlockDiagramCompiled( cbinfo );
        if(~isempty(srcPort) && ~bd_isLocked && ~bd_isCompiled && ~strcmpi( lin.type, 'Connection' ))
            val = 'Enabled';  
        end
    end
end  

function schema = LinearizeSignalMenuDisabled( cbinfo )
    schema = sl_container_schema;
    schema.tag = 'Simulink:LinearizeSignalMenu';
    schema.label    = DAStudio.message('Slcontrol:linmenus:LinearAnalysisPointsMenu');
    schema.state = 'Disabled';
    im = DAStudio.InterfaceManagerHelper( cbinfo.studio, 'Simulink' );
    schema.childrenFcns = { im.getAction( 'Simulink:HiddenSchema' ) };
    schema.autoDisableWhen = 'Busy';
end

function schema = LinearizeSignalMenu( cbinfo ) %#ok<DEFNU>
    schema = LinearizeSignalMenuDisabled( cbinfo );
    schema.state = LocalGetLinearizeSignalMenuState( cbinfo );  
    schema.generateFcn = @genLinearizeSignalMenuChildren;
end

function val = localIsToolstripOn()
val = true;
end

function schema = genLinearizeSignalMenuChildren( cbinfo )    
    [curport,bushier] = LocalGetOutportInfo(cbinfo);
    im = DAStudio.InterfaceManagerHelper( cbinfo.studio, 'Simulink' );
    if isempty(bushier.Children)
        schema = horzcat(...
            LocalGetStandardLinearizationPointSet(im,cbinfo),...
            'separator', ...
            LocalGetTrimSet(im),...
            'separator',...
            {im.getAction('Slcontrol:Help')});
    else       
        schema = {{im.getAction( 'Slcontrol:SelectBusElement' ), { curport, bushier }},...
                  im.getAction( 'Slcontrol:Trim' )  };
    end
    if localIsToolstripOn()
        schema = horzcat(...
            {im.getAction('Slcontrol:LinearizationManager')},...
            'separator', ...
            schema);
    end
end

function val = LocalIsOutportBus(cbinfo)
    [~,bushier] = LocalGetOutportInfo(cbinfo);
    val = ~isempty(bushier.Children);
end

function schema = LocalDisableLinPointOnBus(cbinfo,schema)
    if strcmp(schema.state,'Enabled') && LocalIsOutportBus(cbinfo)
        schema.state = 'Disabled';
    end
end

function [curport,bushier] = LocalGetOutportInfo(cbinfo)
    strictBusLvl = cbinfo.model.StrictBusMsg;
    flag = (strcmp(strictBusLvl, 'ErrorLevel1') || ...
        strcmp(strictBusLvl, 'WarnOnBusTreatedAsVector') || ...
        strcmp(strictBusLvl, 'ErrorOnBusTreatedAsVector'));
    
    % Get the current port from selection
    curport = LocalGetCurrentSelectedOutputPort(cbinfo);
    if flag && ~isempty(curport)
        wState = warning;
        try
            warning('OFF', 'Simulink:Bus:EditTimeBusPropFailureOutputPort');
            bushier = get_param(curport,'SignalHierarchy');
            warning(wState);
        catch %#ok<CTCH>
            bushier = [];
            warning(wState);
        end
        if isempty( bushier )
            bushier.Children = [];
        end
    else
        bushier.Children = [];
    end
end

function schema = LocalGetStandardLinearizationPointSet(im,cbinfo)
schema = {
    im.getAction( 'Slcontrol:PlantInput' ), ...
    im.getAction( 'Slcontrol:PlantOutput' ), ...
    im.getAction( 'Slcontrol:LoopTransfer' ), ...
    im.getAction( 'Slcontrol:BreakLoop' ), ...
    'separator', ...
    im.getAction( 'Slcontrol:Input' ), ...
    im.getAction( 'Slcontrol:Output' ), ...
    im.getAction( 'Slcontrol:Sensitivity'), ...
    im.getAction( 'Slcontrol:ClosedLoopTransfer'), ...
    };
if LocalShowBreakInputOutput(cbinfo)
    schema{end+1} = im.getAction('Slcontrol:BreakInputOutput');
end
end

function schema = LocalGetTrimSet(im)
schema = {im.getAction('Slcontrol:Trim')};
end

function bool = LocalShowBreakInputOutput(cbinfo)
bool = false;
curport = LocalGetCurrentSelectedOutputPort(cbinfo);
if ~isempty(curport)
    io = get_param(curport,'LinearAnalysisIO');
    if (numel(io) == 1) && isempty(slcontrollib.internal.utils.getIOType(io.Type,io.OpenLoop))
        bool = true;
    end
end
end

function portH = LocalGetCurrentSelectedOutputPort(cbinfo)
% Get the 'one and only' selected line
portH = [];
lin = SLStudio.Utils.getSingleSelectedLine(cbinfo);
if(SLStudio.Utils.objectIsValidLine(lin))
    srcPort = SLStudio.Utils.getLineSourcePort(lin);
    if(SLStudio.Utils.objectIsValidPort(srcPort))
        p = srcPort.handle;
        if(ishandle(p))
            portH = p;
        end
    end
end
end

function schema = LinearizationPlantInputDisabled(cbinfo)
    schema = sl_toggle_schema;
    schema.tag      = 'Slcontrol:PlantInput';
    schema.icon     = schema.tag;
    schema.label    = LocalGetLinearPointsLabel(cbinfo,'PlantInput');
    schema.state    = 'Disabled';
    schema.autoDisableWhen = 'Busy';
end

function schema = LinearizationPlantInput(cbinfo) %#ok<DEFNU>
    schema = LinearizationPlantInputDisabled( cbinfo );
    schema.userdata = schema.tag;
    schema.state    = LocalGetLinearizationPointEnabled(cbinfo);   
    schema = LocalDisableLinPointOnBus(cbinfo,schema);
    schema.callback = @LinearizeSignalCB;
    schema.checked = LocalGetLinearizationPointCheck( cbinfo, schema.state, schema.userdata );
end

function schema = LinearizationPlantOutputDisabled(cbinfo)
    schema = sl_toggle_schema;
    schema.tag      = 'Slcontrol:PlantOutput';
    schema.icon     = schema.tag;
    schema.label    = LocalGetLinearPointsLabel(cbinfo,'PlantOutput');
    schema.state    = 'Disabled';
    schema.autoDisableWhen = 'Busy';
end

function schema = LinearizationPlantOutput( cbinfo ) %#ok<DEFNU>
    schema = LinearizationPlantOutputDisabled( cbinfo );
    schema.userdata = schema.tag;
    schema.state    = LocalGetLinearizationPointEnabled(cbinfo); 
    schema = LocalDisableLinPointOnBus(cbinfo,schema);
    schema.callback = @LinearizeSignalCB;
    schema.checked = LocalGetLinearizationPointCheck( cbinfo, schema.state, schema.userdata );
end

function schema = LinearizationLoopTransferDisabled(cbinfo)
    schema = sl_toggle_schema;
    schema.tag      = 'Slcontrol:LoopTransfer';
    schema.icon     = schema.tag;
    schema.label    = LocalGetLinearPointsLabel(cbinfo,'LoopTransfer');
    schema.state    = 'Disabled';
    schema.autoDisableWhen = 'Busy';
end

function schema = LinearizationLoopTransfer( cbinfo ) %#ok<DEFNU>
    schema = LinearizationLoopTransferDisabled( cbinfo );
    schema.userdata = schema.tag;
    schema.state    = LocalGetLinearizationPointEnabled(cbinfo);
    schema = LocalDisableLinPointOnBus(cbinfo,schema);
    schema.callback = @LinearizeSignalCB;
    schema.checked = LocalGetLinearizationPointCheck( cbinfo, schema.state, schema.userdata );
end

function schema = LinearizationInputDisabled(cbinfo)
    schema = sl_toggle_schema;
    schema.tag      = 'Slcontrol:Input';
    schema.icon     = schema.tag;
    schema.label    = LocalGetLinearPointsLabel(cbinfo,'Input');
    schema.state    = 'Disabled';
    schema.autoDisableWhen = 'Busy';
end

function schema = LinearizationInput( cbinfo ) %#ok<DEFNU>
    schema = LinearizationInputDisabled( cbinfo );
    schema.userdata = schema.tag;
    schema.state    = LocalGetLinearizationPointEnabled(cbinfo);   
    schema = LocalDisableLinPointOnBus(cbinfo,schema);
    schema.callback = @LinearizeSignalCB;
    schema.checked = LocalGetLinearizationPointCheck( cbinfo, schema.state, schema.userdata );
end

function schema = LinearizationOutputDisabled(cbinfo)
    schema = sl_toggle_schema;
    schema.tag      = 'Slcontrol:Output';
    schema.icon     = schema.tag;
    schema.label    = LocalGetLinearPointsLabel(cbinfo,'Output');
    schema.state    = 'Disabled';
    schema.autoDisableWhen = 'Busy';
end

function schema = LinearizationOutput( cbinfo ) %#ok<DEFNU>
    schema = LinearizationOutputDisabled( cbinfo );
    schema.userdata = schema.tag;
    schema.state    = LocalGetLinearizationPointEnabled(cbinfo); 
    schema = LocalDisableLinPointOnBus(cbinfo,schema);
    schema.callback = @LinearizeSignalCB;
    schema.checked = LocalGetLinearizationPointCheck( cbinfo, schema.state, schema.userdata );
end

function schema = LinearizationBreakLoopDisabled(cbinfo)
    schema = sl_toggle_schema;
    schema.tag      = 'Slcontrol:BreakLoop';
    schema.icon     = schema.tag;
    schema.label    = LocalGetLinearPointsLabel(cbinfo,'BreakLoop');
    schema.state    = 'Disabled';
    schema.autoDisableWhen = 'Busy';
end

function schema = LinearizationBreakLoop( cbinfo ) %#ok<DEFNU>
    schema = LinearizationBreakLoopDisabled( cbinfo );
    schema.userdata = schema.tag;
    schema.state    = LocalGetLinearizationPointEnabled(cbinfo);
    schema = LocalDisableLinPointOnBus(cbinfo,schema);
    schema.callback = @LinearizeSignalCB;
    schema.checked = LocalGetLinearizationPointCheck( cbinfo, schema.state, schema.userdata );
end

function schema = LinearizationSensitivityDisabled(cbinfo)
    schema = sl_toggle_schema;
    schema.tag      = 'Slcontrol:Sensitivity';
    schema.icon     = schema.tag;
    schema.label    = LocalGetLinearPointsLabel(cbinfo,'Sensitivity');
    schema.state    = 'Disabled';
    schema.autoDisableWhen = 'Busy';
end

function schema = LinearizationSensitivity( cbinfo ) %#ok<DEFNU>
    schema = LinearizationSensitivityDisabled( cbinfo );
    schema.userdata = schema.tag;
    schema.state    = LocalGetLinearizationPointEnabled(cbinfo);
    schema = LocalDisableLinPointOnBus(cbinfo,schema);
    schema.callback = @LinearizeSignalCB;
    schema.checked = LocalGetLinearizationPointCheck( cbinfo, schema.state, schema.userdata );
end

function schema = LinearizationClosedLoopTransferDisabled(cbinfo)
    schema = sl_toggle_schema;
    schema.tag      = 'Slcontrol:ClosedLoopTransfer';
    schema.icon     = schema.tag;
    schema.label    = LocalGetLinearPointsLabel(cbinfo,'ClosedLoopTransfer');
    schema.state    = 'Disabled';
    schema.autoDisableWhen = 'Busy';
end

function schema = LinearizationClosedLoopTransfer( cbinfo ) %#ok<DEFNU>
    schema = LinearizationClosedLoopTransferDisabled( cbinfo );
    schema.userdata = schema.tag;
    schema.state    = LocalGetLinearizationPointEnabled(cbinfo);
    schema = LocalDisableLinPointOnBus(cbinfo,schema);
    schema.callback = @LinearizeSignalCB;
    schema.checked = LocalGetLinearizationPointCheck( cbinfo, schema.state, schema.userdata );
end

function schema = LinearizationBreakInputOutputDisabled( ~ )
    schema = sl_toggle_schema;
    schema.tag      = 'Slcontrol:BreakInputOutput';
    schema.icon     = schema.tag;
    schema.label    = DAStudio.message('Slcontrol:linmenus:BreakInputOutputObsolete');
    schema.state    = 'Disabled';
    schema.autoDisableWhen = 'Busy';
end

function schema = LinearizationBreakInputOutput( cbinfo ) %#ok<DEFNU>
    schema = LinearizationBreakInputOutputDisabled( cbinfo );
    schema.userdata = schema.tag;
    schema.state    = LocalGetLinearizationPointEnabled(cbinfo);
    schema = LocalDisableLinPointOnBus(cbinfo,schema);
    schema.callback = @LinearizeSignalCB;
    schema.checked = LocalGetLinearizationPointCheck( cbinfo, schema.state, schema.userdata );
end

function schema = LinearizationSelectBusElementDisabled( cbinfo )
    schema          = sl_action_schema;
    schema.tag      = 'Slcontrol:SelectBusElement';
    schema.label = LocalGetLinearPointsLabel(cbinfo,'SelectBusElement');
    schema.state    = 'Disabled';
    schema.autoDisableWhen = 'Busy';
end 

function schema = LinearizationSelectBusElement( cbinfo ) %#ok<DEFNU>
    schema          = LinearizationSelectBusElementDisabled( cbinfo );    
    schema.userdata = schema.tag;
    schema.state    = LocalGetLinearizationPointEnabled(cbinfo);
    if strcmp(schema.state,'Enabled') && ~LocalIsOutportBus(cbinfo)
        schema.state = 'Disabled';
    end
    schema.userdata = cbinfo.userdata;
    schema.callback = @LinearizeSelectBusElementCB;    
end

function LinearizeSelectBusElementCB( cbinfo )
    % Extract port and bus hierarchy
    ud = cbinfo.userdata;
    if iscell(ud)
        ph = ud{1};
        bushier = ud{2}.Children;
    else
        % added for sltoolstrip support
        [ph,bushier] = LocalGetOutportInfo(cbinfo);
    end
    % Get the dialog manager
    dlgmgr = slctrlguis.selectbuselement.getSelectBusElementDialogManager();
    dlg = dlgmgr.getDialog(ph,bushier);
    dlg.show();
end

function schema = LinearizationTrimDisabled(cbinfo)
    schema = sl_toggle_schema;
    schema.tag      = 'Slcontrol:Trim';
    schema.icon     = schema.tag;
    schema.label    = LocalGetLinearPointsLabel(cbinfo,'Trim');
    schema.state    = 'Disabled';
    schema.autoDisableWhen = 'Busy';
end 

function schema = LinearizationTrim( cbinfo ) %#ok<DEFNU>
    schema = LinearizationTrimDisabled( cbinfo );
    schema.userdata = schema.tag;
    schema.state    = LocalGetLinearizationPointEnabled(cbinfo);
    schema.callback = @LinearizeTrimCB;
    schema.checked = LocalGetLinearizationPointCheck( cbinfo, schema.state, schema.userdata );
end

function schema = LinearizationHelpDisabled(cbinfo)
    schema = sl_toggle_schema;
    schema.tag      = 'Slcontrol:Help';
    if SLStudio.Utils.showInToolStrip(cbinfo)
        schema.label = 'Slcontrol:toolstrip:HelpTS';
        schema.icon  = 'help';
    else
        schema.label = DAStudio.message('Slcontrol:linmenus:Help');
        schema.icon  = schema.tag;
    end
    schema.state   = 'Disabled';
    schema.checked = 'Unchecked';
    schema.autoDisableWhen = 'Busy';
end 

function schema = LinearizationHelp( cbinfo ) %#ok<DEFNU>
    schema = LinearizationHelpDisabled( cbinfo );
    schema.userdata = schema.tag;
    if SLStudio.Utils.showInToolStrip(cbinfo)
        schema.state = 'Enabled';
    else
        schema.state = LocalGetLinearizationPointEnabled(cbinfo);
    end
    schema.callback = @LinearizeHelpCB;
end

function LinearizeHelpCB(~)
scdguihelp('select_linpoint_type');
end

function chk = LocalGetLinearizationPointCheck( cbinfo, state, tag )
chk = 'Unchecked';
if ( strcmpi (state, 'Enabled' ))
    portH = LocalGetCurrentSelectedOutputPort(cbinfo);
    if ~isempty(portH)
        % Handle trim first
        if(strcmpi(tag, 'Slcontrol:Trim') && strcmpi(get_param(portH, 'LinearAnalysisTrim'), 'on'))
            chk = 'Checked';
            return;
        end
        % Handle linearization I/Os
        io = get_param(portH,'LinearAnalysisIO');
        if isempty(io) || numel(io) > 1
            return;
        end
        newType = slcontrollib.internal.utils.getIOType(io.Type,io.OpenLoop);
        if (strcmpi (tag, 'Slcontrol:PlantInput') && strcmp(newType, 'openinput'))
            chk = 'Checked';
        elseif (strcmpi (tag, 'Slcontrol:PlantOutput') && strcmp(newType, 'openoutput'))
            chk = 'Checked';
        elseif (strcmpi (tag, 'Slcontrol:LoopTransfer') && strcmp(newType, 'looptransfer'))
            chk = 'Checked';
        elseif (strcmpi(tag, 'Slcontrol:Input') && strcmp(newType, 'input'))
            chk = 'Checked';
        elseif (strcmpi(tag, 'Slcontrol:Output') && strcmp(newType, 'output'))
            chk = 'Checked';
        elseif (strcmpi (tag, 'Slcontrol:BreakLoop') && strcmp(newType, 'loopbreak'))
            chk = 'Checked';
        elseif (strcmpi(tag, 'Slcontrol:Sensitivity') && strcmp(newType, 'sensitivity'))
            chk = 'Checked';
        elseif (strcmpi(tag, 'Slcontrol:ClosedLoopTransfer') && ...
                strcmp(newType, 'compsensitivity'))
            chk = 'Checked';
        elseif (strcmpi (tag, 'Slcontrol:BreakInputOutput') && isempty(newType))
            chk = 'Checked';
        end
    end
end
end

function LinearizeTrimCB(cbinfo,varargin)
% varargin is needed for the sl_toggle_schema with the SLToolstrip, which
% represents the new state of the toggle button.

% Get the 'one and only' selected line
portH = LocalGetCurrentSelectedOutputPort(cbinfo);
if isempty(portH)
    return;
end
assert(strcmpi(cbinfo.userdata, 'Slcontrol:Trim'));
% Enable/Disable Output Constraint for Trim
val = get_param( portH, 'LinearAnalysisTrim');
if(strcmpi(val, 'on'))
    set_param(portH, 'LinearAnalysisTrim', 'off');
else
    set_param(portH, 'LinearAnalysisTrim', 'on');
end
simcontdesigner('updatetrim', cbinfo.model.handle);
end


function LinearizeSignalCB(cbinfo,varargin)
% varargin is needed for the sl_toggle_schema with the SLToolstrip, which
% represents the new state of the toggle button.

% Get the 'one and only' selected line
portH = LocalGetCurrentSelectedOutputPort(cbinfo);
if isempty(portH)
    return;
end
io = get_param(portH,'LinearAnalysisIO');
issingleselection = (numel(io) == 1);

if (strcmpi(cbinfo.userdata, 'Slcontrol:PlantInput'))
    if (issingleselection && strcmp(slcontrollib.internal.utils.getIOType(io.Type,io.OpenLoop),'openinput'))
        % Unselecting
        set_param(portH, 'LinearAnalysisIO', []);
    else
        % Selecting
        set_param(portH, 'LinearAnalysisIO', struct('Type','in','OpenLoop','on','BusElementName',''));
    end   
elseif (strcmpi(cbinfo.userdata, 'Slcontrol:PlantOutput'))
    if (issingleselection && strcmp(slcontrollib.internal.utils.getIOType(io.Type,io.OpenLoop),'openoutput'))
        % Unselecting
        set_param(portH, 'LinearAnalysisIO', []);
    else
        % Selecting
        set_param(portH, 'LinearAnalysisIO', struct('Type','out','OpenLoop','on','BusElementName',''));
    end
elseif (strcmpi(cbinfo.userdata, 'Slcontrol:LoopTransfer'))
    if (issingleselection && strcmp(slcontrollib.internal.utils.getIOType(io.Type,io.OpenLoop),'looptransfer'))
        % Unselecting
        set_param(portH, 'LinearAnalysisIO', []);
    else
        % Selecting
        set_param(portH, 'LinearAnalysisIO', struct('Type','outin','OpenLoop','on','BusElementName',''));
    end
elseif (strcmpi(cbinfo.userdata, 'Slcontrol:Input'))
    if (issingleselection && strcmp(slcontrollib.internal.utils.getIOType(io.Type,io.OpenLoop),'input'))
        % Unselecting
        set_param(portH, 'LinearAnalysisIO', []);
    else
        % Selecting
        set_param(portH, 'LinearAnalysisIO', struct('Type','in','OpenLoop','off','BusElementName',''));
    end
elseif (strcmpi(cbinfo.userdata, 'Slcontrol:Output'))
    if (issingleselection && strcmp(slcontrollib.internal.utils.getIOType(io.Type,io.OpenLoop),'output'))
        % Unselecting output
        set_param(portH, 'LinearAnalysisIO', []);
    else
        % Selecting
        set_param(portH, 'LinearAnalysisIO', struct('Type','out','OpenLoop','off','BusElementName',''));
    end    
elseif(strcmpi(cbinfo.userdata, 'Slcontrol:BreakLoop'))
    if (issingleselection && strcmp(slcontrollib.internal.utils.getIOType(io.Type,io.OpenLoop),'loopbreak'))
        % Unselecting
        set_param(portH, 'LinearAnalysisIO', []);
    else
        set_param(portH, 'LinearAnalysisIO', struct('Type','none','OpenLoop','on','BusElementName',''));
    end
elseif (strcmpi(cbinfo.userdata, 'Slcontrol:Sensitivity'))
    if (issingleselection && strcmp(slcontrollib.internal.utils.getIOType(io.Type,io.OpenLoop),'sensitivity'))
        % Unselecting
        set_param(portH, 'LinearAnalysisIO', []);
    else
        set_param(portH, 'LinearAnalysisIO', struct('Type','inout','OpenLoop','off','BusElementName',''));
    end
elseif(strcmpi(cbinfo.userdata, 'Slcontrol:ClosedLoopTransfer'))
    if (issingleselection && strcmp(slcontrollib.internal.utils.getIOType(io.Type,io.OpenLoop),'compsensitivity'))
        set_param(portH, 'LinearAnalysisIO', []);
    else
        set_param(portH, 'LinearAnalysisIO', struct('Type','outin','OpenLoop','off','BusElementName',''));
    end
elseif(strcmpi(cbinfo.userdata, 'Slcontrol:BreakInputOutput'))
    % This can be only for unselecting
    set_param(portH, 'LinearAnalysisIO', []);
end

modelH = cbinfo.model.handle;
set_param(modelH, 'dirty', 'on');
simcontdesigner('updateio', modelH);
end

function str = LocalGetLinearPointsLabel(cbinfo,name)
if SLStudio.Utils.showInToolStrip(cbinfo) % for toolstrip
    % the toolstrip resources have TS appended to them for convenience
    str = sprintf('Slcontrol:toolstrip:%sTS',name);
else
    str = DAStudio.message(sprintf('Slcontrol:linmenus:%s',name));
end
end

function state = loc_getBlockLinearAnalysisMenuState( cbinfo )
    state = 'Hidden';
    if license('test','Simulink_Control_Design') && exist('simcontdesigner', 'file') == 2
        block = SLStudio.Utils.getOneMenuTarget( cbinfo );
        if SLStudio.Utils.objectIsValidBlock( block )
            port_handles = get_param( block.handle, 'PortHandles' );
            num_inports = length( port_handles.Inport );
            num_outports = length( port_handles.Outport );
            if (num_inports > 0 ) && ( num_outports > 0 ) && ...
               ~SLStudio.Utils.isLockedSystem( cbinfo )
                state = 'Enabled';
            end
        end
    end    
end

function schema = BlockLinearAnalysisMenu( cbinfo ) %#ok<DEFNU>
    schema = sl_container_schema;
    schema.label = getString(message('Slcontrol:linmenus:BlockLinearAnalysisMenu'));
    schema.tag = 'Simulink:BlockLinearAnalysisMenu';
        
    schema.state = loc_getBlockLinearAnalysisMenuState( cbinfo );
    
    im = DAStudio.InterfaceManagerHelper( cbinfo.studio, 'Simulink' );
    schema.childrenFcns = { im.getAction( 'Slcontrol:LinearizeBlock' ), ...
                            im.getAction( 'Slcontrol:BlockLinearizeSpecification' )
                          };
    if localIsToolstripOn()
        schema.childrenFcns = horzcat(...
            {im.getAction('Slcontrol:LinearizationManager')},...
            'separator', ...
            schema.childrenFcns);
    end
    schema.autoDisableWhen = 'Busy';
end
% EOF
