function install_mex_if_needed(mexname, srcspec, sources, check_date)
% INSTALL_MEX_IF_NEEDED           Install MEX files on first call
%
%      Synopsys:
%
%            INSTALL_MEX_IF_NEEDED(MEXNAME)
%            INSTALL_MEX_IF_NEEDED(MEXNAME, SRCDIR, [SOURCES, [CHECK_DATE]])
%            INSTALL_MEX_IF_NEEDED(MEXNAME, M_FILE, [SOURCES, [CHECK_DATE]])
%
%      Parameters:
%
%           MEXNAME = Name of MEX function to be installed
%
%           M_FILE  = Name of an M-file contained in the sources
%                     directory 
%
%           SRCDIR  = Source directory
%
%           SOURCES = Cell array with the name of source files. If
%                     empty, defaults to MEXNAME followed by '.c'
%
%      Description:
%
%           INSTALL_MEX_IF_NEEDED check if MEXNAME is installed and
%           if it is not, installs it.  The directory with the
%           source files is given by its name SRCDIR or by
%           specifying an M-file M_FILE which lies in the same
%           directory.  The source file names are in cell array
%           SOURCES. 
%
%           If CHECK_DATE=1, check the MEX file and sources dates
%           and re-install the MEX files if at least one source
%           file is newer.  (Currently unimplemented)
%
%      Example:
%
%           A common usage of this function is to call it at the
%           beginning of an M-file "gateway" to the MEX. The Matlab
%           function MFILENAME can be used to determine the
%           "gateway" name, for example
%
%              INSTALL_MEX_IF_NEEDED('my_mex', mfilename, ...
%                                    {'my_mex.c', 'other_src.c'})
%
%      Defaults:
%
%           SRCSPEC    = The caller name
%           SOURCES    = {}
%           CHECK_DATE = 0  (for the sake of efficiency)
%
%      See also: 
%
%           NONE
%

%%
%% Default handling
%%

%
% Call parsing
%

if (nargin < 2)
  srcspec = '';
end

if (nargin < 3)
  sources = {};
end

if (nargin < 4)
  check_date = 0;
end

%
% Default values
%



%%
%% True code
%%

%
% Check if the MEX needs to be (re)-installed.  Note the usage of
% shortcut boolean operator '||' and '&&'.  This avoids the call to
% SRC_NEWER() if CHECK_DATE==0.
%
if (exist(mexname)==0 || (check_date && src_newer(mexname, srcspec, sources)))
  %
  % First of all, assign the default values to SRCSPEC and SOURCES,
  % if needed.  This is done here rahter than at the beginning of
  % the function for the sake of efficiency.
  %
  assign_defaults(mexname, srcspec, sources);

  %
  % If the mex file does not exist, try to install it.  We need to 
  % move into the directory which contains this file.  First of
  % all, save the current directory in order to come back to it.
  %
  current_dir = pwd;                 

  %
  % Change to the source directory
  %
  srcspec_to_srcdir(srcspec)
  cd(srcspec_to_srcdir(srcspec))
  
  %
  % Compile the C code
  %
  if (exist('warn_matlab_incompatible'))
    %
    % Octave version
    %
    sources = sprintf('%s ', sources{:});
    [output, status]=system(['mex ' sources]);

    if (status ~= 0)
      error('Error while compiling mex: %s', output);
    end
  else
    mex(sources{:});
  end
  
  %
  % Back to the original dir
  %
  cd(current_dir);
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function flag=src_newer(mexname, srcspec, sources)

flag=0;  %%% Currenty unimplemented

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function srcdir=srcspec_to_srcdir(srcspec)
%
% SRCSPEC may be the name of an M-file in the source directory or
% the name of the source directory itself.  This function maps
% SRCSPEC into the corresponding SRCDIR
%

%
% Find out the source directory.  Check with EXIST if SRCSPEC is a
% directory or an M-file
%
switch (exist(srcspec))
 case 2
  %
  % SRCSPEC is the name of a M-file on Matlab PATH.  Find its
  % directory and remove the name part 
  %
  srcdir = fileparts(which(srcspec));
  
  if (isempty(srcdir))
    %
    % This should never happen since WHICH returns a full
    % pathname, but anyway...
    %
    error(['Directory empty for ''' which(srcspec) '''']);
  end
 case 7
  %
  % SRCSPEC is a directory name: nothing is to be done.
  %
  srcdir = srcspec
 otherwise 
  error(['Bad SRCSPEC: ''' srcspec ''' is not an M-file nor a directory'])
end

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function assign_defaults(mexname, srcspec, sources)


if (isempty(sources))
  assignin('caller', inputname(3), { [mexname '.c'] });
end

if (isempty(srcspec))
  %
  % Find out who called INSTALL_MEX_IF_NEEDED
  %
  stack=dbstack;

  assignin('caller', inputname(2), stack(3).name);
end

