classdef(Hidden, Sealed) ModelList < internal.EconModeler.AbstractList
    %MODELLIST Storage for model objectsin the econModeler Class
    
    %Copyright 2017 The MathWorks, Inc.
    
    properties(Access = private)
        Listeners
    end
    
    methods(Access = {?internal.EconModeler.econModelerSession,...
            ?internal.EconModeler.AbstractList})
        function this = ModelList(session)
            this = this@internal.EconModeler.AbstractList(session);
            this.Listeners{end+1} =  event.listener(this.Session,'NewModelCreated',@(s,e)add(this,s,e));
            this.Listeners{end+1} = event.listener(this.Session,'ModelRenameRequest',@(s,e)updateName(this,s,e));
            this.Listeners{end+1} = event.listener(this.Session,'ModelClearDeleteRequest',@(s,e)removeClearedVariables(this,s,e));
        end
        
        function add(this,~,e)
            %Add am odel to the list
            model = e.Model;
            validateattributes(model,{'internal.EconModeler.EconComponents.AbstractModel'},{'column'});
            this.List = [this.List; model];
            [~,sortIdx] = sort({this.List.Name});
            this.List = this.List(sortIdx);
            
            notify(this.Session,'ModelRegistered',e);
        end
        
        function item = getItem(this,identifier)
            %Find a model based on an identifier
            item = getItem@internal.EconModeler.AbstractList(this,identifier);
            if isempty(item)
                item = internal.EconModeler.EconComponents.AbstractModel.empty();
            end
        end
        
        function items = getAllItems(this)
            %Get all models
            items = getAllItems@internal.EconModeler.AbstractList(this);
            if isempty(items)
                items = internal.EconModeler.EconComponents.AbstractModel.empty();
            end
        end
        
        function clearAll(this)
            %Clear all models
            if ~isempty(this.List)
                names = getNames(this);
                eventData = internal.EconModeler.EventData.VarListEventData(names);
                this.List = [];
                notify(this.Session,'ModelClearRegistered',eventData);
            end
        end
    end
    
    methods(Access = private)

        function updateName(this,~,e)
            %Change the name of a model in the list
            if strcmp(e.NewName,e.OldName)
                return;
            end
            idx = strcmp({this.List.Name},e.NewName);
            if any(idx)
                this.List(idx).Name = [e.NewName 'Old'];
            end
            idx = strcmp({this.List.Name},e.OldName);
            if any(idx)
                this.List(idx).Name = e.NewName;
            end
            [~,sortIdx] = sort({this.List.Name});
            this.List = this.List(sortIdx);
            notify(this.Session,'ModelRenameRegistered',e);
        end

        function removeClearedVariables(this,~,e)
            %Given list of variables, clear them from thel ist
            variables = e.Variables;
            [~,idx] = intersect({this.List.Name},variables);
            this.List(idx) = [];
            notify(this.Session,'ModelClearRegistered',e);
        end
    end
end

