classdef GenericBTSpec < mor.GenericSpec
    % Base class for Balanced Truncation objects created by REDUCESPEC.

    % Copyright 2020-2023 The MathWorks, Inc.
    properties (SetAccess=protected, Dependent)
        Sigma
        Energy
        Error  % Warning: Errors for orders 0:nx-1
        Lr
        Lo
    end

    methods

        function value = get.Sigma(this)
            if isempty(this.Cache_)
                value = [];
            else
                value = this.Cache_.Sigma;
            end
        end

        function value = get.Energy(this)
            if isempty(this.Cache_)
                value = [];
            else
                value = this.Cache_.Energy;
            end
        end

        function value = get.Error(this)
            if isempty(this.Cache_)
                value = [];
            else
                value = this.Cache_.Error;
            end
        end

        function value = get.Lr(this)
            if isempty(this.Cache_)
                value = [];
            else
                value = this.Cache_.Lr;
            end
        end

        function value = get.Lo(this)
            if isempty(this.Cache_)
                value = [];
            else
                value = this.Cache_.Lo;
            end
        end

    end


    methods

        function varargout = view(R,plotType,optArgs)
            %VIEW  Graphically select order of reduced model.
            %
            %   VIEW(R,PLOTTYPE) creates visual helpers for selecting the order of
            %   the reduced model. Available plot types for this MOR spec include
            %     'sigma'    Bar chart of Hankel singular values and associated
            %                error bound.
            %     'energy'   Bar chart of normalized energies.
            %
            %   VIEW(R) is equivalent to VIEW(R,'sigma').
            %
            %   VIEW(R,...,Name1=Value1,Name2=Value2,...) specifies additional
            %   options for customizing the plot appearance. See HSVOPTIONS for
            %   available options. For example,
            %      view(R,'sigma',Axes=AX,Yscale='linear')
            %   plots the Hankel singular values into the axes with handle AX
            %   using a linear Y scale.
            %
            %   H = VIEW(R,...) returns the plot handle H.
            %
            %   See also HSVOPTIONS, REDUCESPEC.
            arguments
                R
                plotType = 'sigma';
                optArgs.?mor.view.BalancedTruncationOptions;
            end
            nargoutchk(0,1)
            % Handle help request view(R,'-help')
            if strcmp(plotType,'-help')
                if nargout>0
                    error(message('Control:transformation:view1'))
                end
                help mor.GenericBTSpec.view
                return
            end
            % Resolve plot type
            plotType = ltipack.matchKey(plotType,{'sigma','energy'});
            if isempty(plotType)
                error(message('Control:transformation:BALROM13'))
            end
            % Resolve plot options
            plotOpt = hsvoptions;
            F = fieldnames(optArgs);
            F = F(~strcmp(F,'Axes'),:);
            for ct=1:numel(F)
                plotOpt.(F{ct}) = optArgs.(F{ct});
            end
            % Update data
            try
                R = process(R);
            catch ME
                throw(ME)
            end
            % Create plot
            if isfield(optArgs,'Axes') && isgraphics(optArgs.Axes,'axes')
                ax = optArgs.Axes;
            else
                ax = gca;
            end

            if controllibutils.CSTCustomSettings.getCSTPlotsVersion == 2 && ...
                    ~matlab.internal.editor.figure.FigureUtils.isEditorFigure(ancestor(ax,'figure'))
                systemData.ReduceSpec = R;
                systemData.Style = [];
                systemData.PlotType = plotType;
                if strcmp(plotType,'energy')
                    plotOpt.YLabel.String = getString(message('Control:transformation:BALROM16'));
                    plotOpt.Title.String = getString(message('Control:transformation:BALROM15'));
                end
                try
                    h = controllib.chart.internal.utils.ltiplot("hsv",ax,...
                        SystemData=systemData,Options=plotOpt);
                catch ME
                    throw(ME)
                end
            else
                try
                    h = ltiplot(ax,'hsv',[],[],plotOpt,cstprefs.tbxprefs);
                catch ME
                    throw(ME)
                end
                % Add HSV "response"
                r = h.addresponse(1,1,1);
                if strcmp(plotType,'sigma')
                    r.Data.HSV  = R.Sigma;
                else
                    h.AxesGrid.YLabel = getString(message('Control:transformation:BALROM16'));
                    h.AxesGrid.Title = getString(message('Control:transformation:BALROM15'));
                    r.Data.HSV  = R.Energy;
                end
                r.Data.ErrorBound  = [R.Error;0];
                if any(isprop(R.Options_,'Goal'))
                    r.Data.ErrorType = R.Options_.Goal(1:3);
                else
                    r.Data.ErrorType = 'abs';
                end
                % Make plot visible
                h.Visible = 'on';
                legend(ax,'show')  % Legend on by default
                % Add menu
                h.addHSVMenu('yscale');
                h.AxesGrid.addMenu('grid');
                h.addMenu('fullview');
                % Add properties menu
                if usejava('MWT')
                    h.addMenu('properties','Separator','on');
                end
            end

            % Return handle if requested
            if nargout>0
                varargout = {h};
            end
        end

    end

    methods (Hidden, Access = ?mrtool.data.BalancedTruncationData)
        function cache = getCache(this)
            cache = this.Cache_;
        end
    end

end

