function [paths,files]=LocateModelFiles(input)
%% [paths,files]=LocateModelFiles(input)
% Purpose: locate mechanism files associated with DynaSim specifications.
% Input: DynaSim specification or model structure or string or cell array of
%        strings listing mechanism names or files.
% Outputs: 
%   paths - unique paths to mechanism files
%   files - full names of files containing mechanism sub-models
% 
% See also (used by): ParseModelEquations, CheckHostPaths, CreateBatch

% extract list of mechanisms from input
if ischar(input)
  % convert to cell array of strings
  mechanism_list={input};
elseif iscellstr(input)
  mechanism_list=input;
elseif isstruct(input)
  if isfield(input,'specification')
    % extract specification from DynaSim model structure
    input=input.specification;
  elseif isfield(input,'model') && isfield(input.model,'specification') 
    % extract specification from DynaSim data structure
    input=input.model.specification;
  elseif isfield(input,'base_model') && isfield(input.base_model,'specification') 
    % extract specification from DynaSim studyinfo structure
    input=input.base_model.specification;
  else
    % this is probably a specification structure
  end
  mechanism_list={};
  if isfield(input,'populations') && isstruct(input.populations)
    % extract mechanism_list from populations in DynaSim specification structure
    m={input.populations.mechanism_list};
    m=unique([m{:}],'stable');
    mechanism_list=cat(2,mechanism_list,m);
    % add equations to mechanism_list in case it contains a .eqns file
    for i=1:length(input.populations)
      if ~isempty(input.populations(i).equations)
        mechanism_list{end+1}=input.populations(i).equations;
      end
    end
  end
  if isfield(input,'connections') && isstruct(input.connections)
    % extract mechanism_list connections in DynaSim specification structure
    m={input.connections.mechanism_list};
    m=unique([m{:}],'stable');
    mechanism_list=cat(2,mechanism_list,m);
  end  
end

% remove @ pointers from mechanism identifiers
if any(~cellfun(@isempty,regexp(mechanism_list,'@','once')))
  mechanism_list=regexp(mechanism_list,'^([^@]+)@?','tokens','once');
  mechanism_list=[mechanism_list{:}];
end
% exclude elements with non-word characters (these are not file names)
keep=cellfun(@isempty,regexp(mechanism_list,'[^\w\.\-/]'));
%keep=cellfun(@isempty,regexp(mechanism_list,'[^\w\.]'));
mechanism_list=mechanism_list(keep);

% search in dynasim toolbox model directory
dynasim_path=fileparts(fileparts(which(mfilename))); % root is one level up from directory containing this function
model_dir=fullfile(dynasim_path,'models'); % models dir is at root level
search_paths=regexp(genpath(model_dir),':','split'); % look in all dynasim directories
% add current directory
search_paths=cat(2,pwd,search_paths); % look in current directory first
% add Matlab path
search_paths=cat(2,search_paths,regexp(path,':','split'));
% exclude .git directories
keep=cellfun(@isempty,regexp(search_paths,'.git'));
search_paths=search_paths(keep);
num_paths=length(search_paths)+1;

% locate mechanism files
files={};
if iscellstr(mechanism_list)
  for f=1:length(mechanism_list) % loop over mechanisms
    for s=1:num_paths
      % determine name of mechanism file (assuming recommended extensions)
      if s==num_paths
        mech=mechanism_list{f};
      else
        mech=fullfile(search_paths{s},mechanism_list{f});
      end
      if exist(mech,'file')
        file=mech;
      elseif exist([mech '.eqns'],'file')
        file=[mech '.eqns'];
      elseif exist([mech '.mech'],'file')
        file=[mech '.mech'];
      elseif exist([mech '.txt'],'file')
        file=[mech '.txt'];
      elseif exist([mech '.m'],'file')
        file=[mech '.m'];
      else
        file='';
      end
      % use 'which' to get full filename of file in Matlab path
      if isempty(fileparts(file)) % file is a name without a path
        file=which(file);
      end
      if ~isempty(file)
        files{end+1}=file;
        break;
      end
    end
  end
end

% extract unique paths to mechanism files
paths=unique(cellfun(@fileparts,files,'uni',0),'stable');