classdef (ConstructOnLoad, Abstract) LiveTask < handle
    % LIVETASK Base class for defining a custom Live Editor task.

    % Copyright 2021-2022 The MathWorks, Inc.

    properties (Abstract, Dependent)
        % This property must be defined in the user subclass. The subclass
        % must implement the get.Summary method to get the value of this
        % property.
        Summary

        % This property must be defined in the user subclass. The subclass
        % must implement the get.State and set.State methods to get and set
        % the value of this property.
        State
    end

    properties (SetAccess = private)
        % By default, Parent is a UIFigure.
        Parent
    end

    properties (Access = protected)
        % All graphics and UI objects for the task must be added to this
        % object. By default, LayoutManager is a GridLayout.
        LayoutManager
    end

    properties (SetObservable, AbortSet)
        % By default, the task runs automatically when task parameters are
        % modified. Set to false to disable running automatically.
        AutoRun (1,1) logical = true;
    end

    events (NotifyAccess = protected)
        % The Live Editor monitors for common changes in the task, such as
        % when the task parameters are modified, and triggers this event
        % when a change is detected. The event calls the generateCode
        % method and runs the section containing the task.
        % To manually trigger this event, use this code:
        % notify(task, "StateChanged");
        % Note: The Live Editor does not monitor events for components that
        % are created dynamically at run time.
        StateChanged
    end

    methods
        function task = LiveTask(NVPairs)
            arguments
                NVPairs.Parent matlab.ui.Figure = uifigure
            end
            task.Parent = NVPairs.Parent;
            task.LayoutManager = uigridlayout(task.Parent, [1, 1]);
            task.Parent.Name = class(task);
            task.setup();
        end
    end

    % All methods below must be defined in the user subclass.
    methods (Abstract, Access = protected)
        % Define this method in the user subclass to set the initial state
        % of the class. This method is called when the base class is
        % constructed and does not need to be called from the user
        % subclass.
        setup(task);
    end

    methods (Abstract)
        % Define this method in the user subclass to return the code and
        % output(s) that the task generates.
        %
        % CODE - Character array or string array containing the MATLAB
        % commands that correspond to the current state of the task. The
        % returned code appears and runs as a part of the host live script.
        % Surround input variable names with back ticks (``) to allow the
        % Live Editor to rename them as needed.
        %
        % OUTPUTS - Cell array containing the variables generated by the
        % task.
        [code, outputs] = generateCode(task);

        % Define this method in the user subclass to reset the task to its
        % default state while keeping the current selections. This method
        % is called when the task user selects reset in the context menu
        % or in the Live Editor toolstrip.
        reset(task);
    end

    methods
        function delete(task)
            delete(task.Parent)
        end
    end

    methods (Access = {?matlab.internal.editor.LiveTaskUtilities})
        function figure = getFigure(task)
            figure = task.Parent;
        end
        
        function layoutManager = getLayoutManager(task)
            layoutManager = task.LayoutManager;
        end
    end
end
