function [mprob] = minterface(problem_name) 
%MINTERFACE  Generate MEX-Function interface to IVP_testset problems  
%  
%   MPROB = MINTERFACE(PROBLEM_NAME) returns a function handle to a  
%   MEX-Function interface to problem PROBLEM_NAME. If needed, the  
%   Fortran MEX-Function interface is automatically generated and  
%   compiled.  
%   
%   MINTERFACE ALL produces MEX-Functions for all IVP_testset problems.
%
%   MINTERFACE CLEAN removes all generated MEX-Functions
% 
%   The interface MPROB supports the following calling sequences:
%     PROB = MPROB('Prob')
%     [Y0,YP0,CONSIST] = MPROB('Init',NEQ,T0) 
%     [F,IERR,RPAR,IPAR] = MPROB('Feval',NEQ,T,Y,YP,RPAR,IPAR)     
%     [J,IERR,RPAR,IPAR] = MPROB('Jeval',LDIM,NEQ,T,Y,YP,RPAR,IPAR) 
%     [M,IERR,RPAR,IPAR] = MPROB('Meval',LDIM,NEQ,T,Y,YP,RPAR,IPAR) 
%     Y = MPROB('Solut',NEQ,TFINAL)
%   Additional syntax
%     [MESCD,SCD] = MPROB('Report',NEQ,YREF,Y,PROBNM,TOLVEC,ATOL,RTOL)
%     MPROB('Help') 
% 
%---------------------------------------------------------------------
%     This file is part of the Test Set for IVP solvers
%     http://www.dm.uniba.it/~testset/
%
%
%     DISCLAIMER: see
%     http://www.dm.uniba.it/~testset/disclaimer.php
%
%     The most recent version of this source file can be found at
%     http://www.dm.uniba.it/~testset/matlab/minterface.m
%
%     This is revision
%  $Id: minterface.m,v 1.6 2008/02/08 11:09:29 testset Exp $ 
%-----------------------------------------------------------------------

  % Quick check for existing MATLAB function, e.g., vdpol_mfunction.m
  % not used in the present version
  mfunction_tag  = '_mfunction';
  mat_name = [problem_name,mfunction_tag];
  if exist(mat_name) == 2
    mprob = str2func(mat_name);
    return
  end

  % Prepare for generating MEX-File:
 
  % Determine the directory structure from the location of this file
  if local_MLversion < 6.5 
    interface_path = pwd;  
  else   
    interface_path = fileparts(mfilename('fullpath'));  % <IVP_test>/matlab
  end 
  interface_file = fullfile(interface_path,'private','matlab_interface.F');  % '.F' to use preprocessor

  IVP_testset_root = fileparts(interface_path); % <IVP_test>
  problem_path = fullfile(IVP_testset_root,'src','problems'); % <IVP_test>/src/problems
  report_file  = fullfile(IVP_testset_root,'src','auxil','report.f'); % <IVP_test>/src/auxil/report.f
 
  mex_subdir = 'private'; 
  mex_dir = fullfile(interface_path,mex_subdir); % <IVP_test>/matlab/private
 
  minterface_tag = '_minterface';
 
  switch problem_name
  
   case 'clean'
    s = dir(fullfile(problem_path,'*.f'));
    for i = 1:length(s)
      [pathstr,fname] = fileparts(s(i).name);
      mex_name = [mex_dir,filesep,fname,minterface_tag]; 
      if exist(mex_name) == 3 
        clear(mex_name);
        delete(which(mex_name));
      end
    end
     
   case 'all' 
    s = dir(fullfile(problem_path,'*.f'));
    for i = 1:length(s)
      [pathstr,fname] = fileparts(s(i).name);
      minterface(fname);
    end
 
   otherwise 
   
    % generate mex-function   
    mex_name = [mex_dir,filesep,problem_name,minterface_tag];
     
    if exist(mex_name) ~= 3

      fprintf('Generating MEX-Function:  %s  ... \n', mex_name);

      problem_file = fullfile(problem_path, [problem_name, '.f']);
     
      if exist(problem_file,'file') ~= 2
        local_error('File %s not found.',problem_file)
      end
                 
      % call mex
      failed = mex('-output', mex_name, ...
                   interface_file, problem_file, report_file);     
      if failed
        local_error('Unable to compile the mex file for %s.',problem_name);
      end 

      % report success
      [pathstr,fname,fext] = fileparts(which(mex_name));
      fprintf('    ... %s%s generated successfully. \n',fname,fext);     
    end

    % return 
    mex_name = [problem_name,minterface_tag];
    mprob = str2func(mex_name)
   
  end % switch
 
% ==========================================================================
% Sub-functions
% 
 
function mlver = local_MLversion 
  v = version; % e.g., '7.4.0.34231 (R2007a)' 
  idx = strfind(v,'.'); 
  mlver = str2num(v(1:idx(2)-1)); % e.g., 7.4
% end local_MLversion 
 
% --------------------------------------------------------------------------    
 
function local_error(varargin) 
  if local_MLversion < 6.5 
    s = sprintf(varargin{:}); 
    error(s); 
  else 
    error(varargin{:}); 
  end 
% end local_error 
 
% --------------------------------------------------------------------------    
      
%[EOF] minterface.m
