classdef RAPTORmodule
  % Generic class of RAPTORmodules
  
  properties
    Name
    Type
    Configuration
  end
  
  methods
    function module = RAPTORmodule(modulename)
      % constructor
      if nargin==0 || strcmp(modulename,'none')
        module.Name = 'none';
        module.Type = 'none';
        module.Configuration = [];
        return
      else
        assert(ischar(modulename),'RAPTOR:ModuleNameNotString','Module name must be a string');
        assert(~~exist(modulename,'file'),'RAPTOR:ModuleNotFound','Module %s not found',modulename);
        module.Name = modulename;
        [module.Type, module.Configuration] = getDefaultTypeAndConfiguration(module);
      end
    end
    
    function [type,config] = getDefaultTypeAndConfiguration(module)
       [type,config] = eval(module.Name);
    end
    
    function [model,params] = setup(module,RAPTORmodel) %#ok<INUSD>
      % setup method
      if strcmp(module.Name,'none')
        [model,params] = empty_module_setup;
      else
        [model,params] = eval([module.Name,'(module.Configuration,RAPTORmodel)']);
      end
    end
    
    function passed = checkConfiguration(module)
     [~,defaultConfiguration] = module.getDefaultTypeAndConfiguration;
     passed = structcmp(defaultConfiguration,module.Configuration,Inf);
    end
    
    function passed = checkModel(module,model,RAPTORmodel)
     defaultModule = RAPTORmodule(module.Name); % re-initialize default module instance
     [defaultModel,~] = defaultModule.setup(RAPTORmodel);
     passed = structcmp(defaultModel,model,Inf);
    end
    
    function passed = checkParams(module,params,RAPTORmodel)
     defaultModule = RAPTORmodule(module.Name); % re-initialize default module instance
     [~,defaultParams] = defaultModule.setup(RAPTORmodel);
     passed = structcmp(defaultParams,params,Inf);
    end

  end
end

function [mm,pp] = empty_module_setup
mm.name = 'none';
mm.type = 'none';
mm.uind = [];
mm.n_units = 0;

pp.active = false;
end