classdef SCDclass_expcodecontainer
    % A container class for expcodes
    
    properties(Access = private)
        numexpcodes
        expcodes
    end
    
    methods
        function obj=SCDclass_expcodecontainer()
           obj.numexpcodes=0;
           obj.expcodes={};
        end
    
        function list = getexpcodelist(obj)
          % get numerical list of available codes;
          list = zeros(1,obj.numexpcodes);
          for ii=1:obj.numexpcodes
            list(ii) = obj.expcodes{ii}{1};
          end
        end
          
        function obj=insertexpcode(obj, maincode, definefunction)
           
            if(obj.numexpcodes==0)
                temp=cell(10,1);
                temp{1}=maincode;
                temp{2}=definefunction;
                
                obj.expcodes{end+1}=temp;
                obj.numexpcodes=obj.numexpcodes+1;
                
                fprintf('Expcode %d inserted (pos %d)\n', maincode, 1);
            else
                expcodepresent=false;
                expcodeindex=0;
        
                for(ii=1:numel(obj.expcodes))
                    if(obj.expcodes{ii}{1}==maincode || strcmp(char(obj.expcodes{ii}{2}),definefunction))
                        expcodepresent=true;
                        expcodeindex=ii;
                        break;
                    end
                end
        
                if(expcodepresent)
                    obj.expcodes{expcodeindex}=expcode;
                    
                    fprintf('Expcode %d already present (pos %d), skipped insertion.\n', maincode, expcodeindex);
                else 
                    temp=cell(10,1);
                    temp{1}=maincode;
                    temp{2}=definefunction;
                     
                    presentcodes=[];
                    for(ii=1:obj.numexpcodes)
                        presentcodes(ii)=obj.expcodes{ii}{1};
                    end
                    insertpos=min(find(presentcodes>maincode));
                    
                    %if(insertpos==obj.numexpcodes)
                    if(isempty(insertpos))    
                        obj.expcodes{end+1}=temp;
                        
                        fprintf('Expcode %d inserted (pos %d)\n', maincode, obj.numexpcodes+1);
                    else
                        for(jj=obj.numexpcodes:-1:insertpos)
                           obj.expcodes{jj+1}=obj.expcodes{jj};
                        end
                        obj.expcodes{insertpos}=temp;
                        fprintf('Expcode %d inserted (pos %d)\n', maincode, insertpos);
                    end    
                       
                    obj.numexpcodes=obj.numexpcodes+1;
                end 
            end
        end
            
        function printexpcodes(obj)
            if(obj.numexpcodes==0)
                disp('No configured expcodes.');
            else
                fprintf('------------------------------------------------------------------\n');
                fprintf('CODE\tSTATUS\tNAME\n');
                fprintf('------------------------------------------------------------------\n');
                for ii=1:obj.numexpcodes
                    try
                        expcode=obj.expcodes{ii}{2}();
                        if(~isa(expcode,'SCDclass_expcode'))
                            error('SCDclass_expcodecontainer.getbymaincode','Expcode defining function not returning the right object');
                        end
                        fprintf('%d\t%s\t%s\n',obj.expcodes{ii}{1},expcode.status,expcode.name);
                    
                    catch ME
                        fprintf('%d\tERROR calling conf function: %s\n', obj.expcodes{ii}{1},char(obj.expcodes{ii}{2}));
                    end
                end                
                fprintf('------------------------------------------------------------------\n');               
            end
        end
        
        function out=getbymaincode(obj,code)
           if(obj.numexpcodes==0)
               error('SCDclass_expcodecontainer.getbymaincode: %s','Expcode container empty!');
           end
           
           presentcodes=[];
           for(ii=1:obj.numexpcodes)
               presentcodes=[presentcodes; obj.expcodes{ii}{1}];
           end
           
           if(isempty(find(code==presentcodes, 1)))
               error('Expcode %d not present in the container class',code);
           else
               deffunc = obj.expcodes{code==presentcodes}{2};
               %expcode = eval(char(deffunc));
               expcode = deffunc();
               assert(isa(expcode,'SCDclass_expcode'),'SCDclass_expcodecontainer.getbymaincode the configured defining function doesn''t return a SCDclass_expcode object');
               expcode.maincode=code;
               out=expcode;
           end
        
        end    
    end
end