classdef HDLAppContext < dig.CustomContext

% HDLAppContext to store state information.

%   Copyright 2019 The MathWorks, Inc.

    properties(SetObservable=true)
        BDListener
        CSListener
    end
    
    properties( SetAccess = protected )
        OrigTypeChain
        GenCodeContext        
        ModelH
    end

    methods
        function obj = HDLAppContext(app, cbinfo)
            obj@dig.CustomContext(app);
            obj.ModelH = cbinfo.model.Handle;
            obj.OrigTypeChain = obj.TypeChain;
            setupListeners(obj, obj.ModelH);
            obj.updateTypeChain();
        end

        % Setup Listeners that the toolstrip requries
        function setupListeners(obj, modelHandle)
            cs_active = getActiveConfigSet(modelHandle);
            % listen for active config set event in case new CS is used
            obj.BDListener = handle.listener(get_param(modelHandle, 'object'), 'ActivateConfigSetEvent', @(bd, ed) obj.activeConfigChangeCB(bd, ed));
            % listen for component change in the active config set
            obj.addHDLConfigChangeListener(cs_active);
        end

        function addHDLConfigChangeListener(obj, cs_active)
            obj.CSListener = handle.listener(cs_active, 'ConfigSetComponentChanged', @(cs, ed) obj.configComponentChangeCB(cs, ed));
        end

        function configComponentChangeCB(obj, ~, ~)
            obj.updateTypeChain;
        end

        function activeConfigChangeCB(obj, bd, ~)
            cs_active = getActiveConfigSet(bd);
            obj.addHDLConfigChangeListener(cs_active);
            obj.updateTypeChain;
        end

        % Update the TypeChain with all the manual contexts
        function doContextualRefresh(obj, ~, ~)
            obj.updateTypeChain();
        end
        
        function updateTypeChain( obj )
            obj.updateGenCodeContext();
            obj.TypeChain = [{ obj.GenCodeContext}  obj.OrigTypeChain ];
        end

        % Switch between contexts based on the presence of a HDL
        % Configuration in the ConfigSet
        function updateGenCodeContext(obj)
            configSet = getActiveConfigSet( obj.ModelH );
            hasHDLConfig = ~isempty(gethdlcconfigset( configSet ));
            if hasHDLConfig
                obj.GenCodeContext = 'hdlCoderAppConfigContext';
            else
                obj.GenCodeContext = 'hdlCoderAppNoConfigContext';
            end
        end
    end
end
