classdef container
   
   methods
      
      function this = container(varargin)
         if nargin == 1
            if isa(this,'container')
               this = varargin{1};
            end
         end
      end
      
      function x = list(this)
         x = container.request('list');
      end
      
      function lock(this,varargin)
         container.request('lock',varargin{:});
      end
      
      function unlock(this,varargin)
         container.request('unlock',varargin{:});
      end
      
      function flag = islocked(this,varargin)
         flag = container.request('islocked',varargin{:});
      end
      
      function list = locked(this)
         list = container.request('locked');
      end
      
      function list = unlocked(this)
         list = container.request('unlocked');
      end
      
      function this = remove(this,varargin)
         container.request('remove',varargin{:});
      end
      
      function this = clear(this)
         container.request('clear');
         munlock('container.request');
      end
      
      function x = saveobj(this)
         x = container.request('save');
      end
      
      function varargout = get(this,varargin)
         if ~isempty(varargin)
            [varargout{1},flag] = container.request('get',varargin{1});
            if ~flag
               container.error(2,varargin{1});
            end
            [varargout{2:length(varargin)}] = get(this,varargin{2:end});
         end
      end
      
      function this = put(this,varargin)
         if ~isempty(varargin)
            P = inputParser();
            P.addRequired('c',@(x) isa(x,'container'));
            P.addRequired('name',@ischar);
            P.parse(this,varargin{1});
            if ~isempty(varargin)
               flag = container.request('set',varargin{1},varargin{2});
               if ~flag
                  container.error(1,varargin{1});
               end
               this = put(this,varargin{3:end});
            end
         end
      end      
      
      function disp(this)
         list = container.request('list');
         status = get(0,'formatSpacing');
         fprintf('\tcontainer object: 1-by-1\n');
         set(0,'formatSpacing','compact');
         disp(list);
         set(0,'formatSpacing',status);
      end
      
      function display(this)
         if isequal(get(0,'FormatSpacing'),'compact')
            disp([inputname(1),' =']);
         else
            disp(' ')
            disp([inputname(1),' =']);
            disp(' ');
         end
         disp(this);
      end
      
   end
   
   methods (Static)
      
      function this = loadobj(this)
         container.request('load',this);
         this = container();
      end
      
   end
   
   methods (Static,Access=private)
      
      varargout = request(action,varargin)
      
      function error(code,list,varargin)
         switch code
            case 1
               msg = 'Cannot re-write container entry ''%s''. This entry is locked.';
            case 2
               msg = 'Reference to non-existent container entry: ''%s''.';
         end
         if nargin == 1
            list = {};
         elseif ~iscell(list)
            list = {list};
         end
         printmsg('container','error',msg,list,code);
      end
   end
   
end