function varargout = mdbfileonpath(inFilename)
   %   MDBFILEONPATH Helper function for the Editor/Debugger
   %   MDBFILEONPATH is passed a string containing an absolute filename of an
   %   m-file.
   %   It returns:
   %      a filename:
   %         the filename that will be run (may be a shadower)
   %         if file not found on the path and isn't shadowed, returns the
   %         filename passed in
   %      an integer defined in com.mathworks.mlwidgets.dialog.PathUpdateDialog
   %      describing the status:
   %         FILE_NOT_ON_PATH - file not on the path or error occurred
   %         FILE_WILL_RUN - m-file is the one MATLAB will run (or is shadowed by a newer
   %         p-file)
   %         FILE_SHADOWED_BY_PWD - m-file is shadowed by another file in the current directory
   %         FILE_SHADOWED_BY_TBX - m-file is shadowed by another file somewhere in the MATLAB path
   %         FILE_SHADOWED_BY_PFILE - m-file is shadowed by a p-file in the same directory
   %         FILE_SHADOWED_BY_MEXFILE - m-file is shadowed by a mex or mdl file in the same directory
   %
   %   inFilename should be an absolute filename with extension ".m" (No
   %   checking is done.)
   %   This file is for internal use only and is subject to change without
   %   notice
   %   Copyright 1984-2004 The MathWorks, Inc.
   %   $Revision: 1.1.6.5 $

   if nargin > 0
      try
         % Keep these in the try clause in case java throws an error
         statusNotOnPath = com.mathworks.mlwidgets.dialog.PathUpdateDialog.FILE_NOT_ON_PATH;
         statusOK = com.mathworks.mlwidgets.dialog.PathUpdateDialog.FILE_WILL_RUN;
         statusShadowedByCWD = com.mathworks.mlwidgets.dialog.PathUpdateDialog.FILE_SHADOWED_BY_PWD;
         statusShadowedByTbx = com.mathworks.mlwidgets.dialog.PathUpdateDialog.FILE_SHADOWED_BY_TBX;
         statusShadowedByPfile = com.mathworks.mlwidgets.dialog.PathUpdateDialog.FILE_SHADOWED_BY_PFILE;
         statusShadowedByMex = com.mathworks.mlwidgets.dialog.PathUpdateDialog.FILE_SHADOWED_BY_MEXFILE;

         [path fn] = fileparts(inFilename);

         mexfilename = fullfile(path, [fn '.' mexext]);
         mdlfilename = fullfile(path, [fn '.mdl']);
         pfilename = fullfile(path, [fn '.p']);
         if doesFileExist(mexfilename)
            % Check for mex file shadowing this file in the same directory.
            fullpath = mexfilename;
            shadowStatus = statusShadowedByMex;
         elseif doesFileExist(mdlfilename)
            % Check for mdl file shadowing this file in the same directory.
            fullpath = mdlfilename;
            shadowStatus = statusShadowedByMex;
         elseif doesFileExist(pfilename)
            % Check if there is a p-file shadowing this file in the same
            % directory.  If there is (and if the m-file is newer), then
            % report that the p-file is shadowing it.
            mdirInfo = dir(inFilename);
            pdirInfo = dir(pfilename);
            % If the p-file is newer than the m-file, assume that it's OK
            if (datenum(pdirInfo.date) >= datenum(mdirInfo.date))
               [shadowStatus, fullpath] = checkIfShadowed(pfilename);
            else
               fullpath=pfilename;
               shadowStatus = statusShadowedByPfile;
            end
         else
            [shadowStatus, fullpath] = checkIfShadowed(inFilename);
         end

         if nargout == 0
            disp(fullpath);
            disp(shadowStatus);
         else
            varargout{1} = fullpath;
            varargout{2} = shadowStatus;
         end

      catch
         if nargout == 0
            disp(inFilename);
            disp(0);
         else
            varargout{1} = inFilename;
            varargout{2} = 0;
         end
      end
   else
      if nargout == 0
         disp('')
         disp 0;
      else
         varargout{1} = '';
         varargout{2} = 0;
      end

   end

   %---------------------------------------------------------------------
   % Make this nested to share the status codes
   function [shadowStatus, fullpath] = checkIfShadowed(inFilename)

      [path fn ext] = fileparts(inFilename);
      xfiletorun = getFileToRun(inFilename);
      if ~isempty(xfiletorun)
         [xpath xfn xext] = fileparts(xfiletorun);
         % The executable fileparts are identical to the file passed in
         if arePathsEqual(xpath, path) && areFilenamesEqual(xfn, fn) && areFilenamesEqual(xext, ext)
            fullpath = xfiletorun;
            shadowStatus = statusOK; % MATLAB will run the file
         end

         % Can only happen on unix: eg foo.m and FOO.m
         if arePathsEqual(xpath, path) && ~areFilenamesEqual(xfn, fn) && areFilenamesEqual(xext, ext)
            fullpath = xfiletorun;
			if arePathsEqual(xpath, pwd)
				shadowStatus = statusShadowedByCWD;
			else
				shadowStatus = statusShadowedByTbx; % shadower on path
			end
         end

         % Paths are different, so the file is shadowed
         if ~arePathsEqual(xpath, path)
            if arePathsEqual(xpath, pwd)
               shadowStatus = statusShadowedByCWD; % shadower in cwd
            else
               shadowStatus = statusShadowedByTbx; % shadower on path
            end
            fullpath = xfiletorun;
         end

      else
         fullpath = inFilename;
         shadowStatus = statusNotOnPath;
      end
   end
end

%---------------------------------------------------------------------
% Test if two strings containing pathnames are equal.  This takes
% platform considerations into account.
function pathsAreEqual = arePathsEqual(path1, path2)
   %TODO need more robust test
   try
      if ispc
         pathsAreEqual = isequal(lower(path1), lower(path2));
      else
         pathsAreEqual = isequal(path1, path2);
      end
   catch
      pathsAreEqual = false;
   end
end

%---------------------------------------------------------------------
% Test if two strings containing filenames are equal.  This only
% needs to handle case on the PC
function namesAreEqual = areFilenamesEqual(name1, name2)
   try
      if ispc
         namesAreEqual = isequal(lower(name1), lower(name2));
      else
         namesAreEqual = isequal(name1, name2);
      end
   catch
      namesAreEqual = false;
   end
end
   
%---------------------------------------------------------------------
% Return a string containing the absolute path of the file that
% MATLAB will run based on the input filename (e.g., foo)
function fn = getFileToRun(inPath)
   if isPrivateOrObject(inPath)
      % For files in a private or object directory, use absolute path
      whichargs = [ '''' strrep(inPath, '''', '''''') ''''];
      fn = evalin('caller', ['which(' whichargs ')']);
      if isempty(fn)
         fn = evalin('base', ['which(' whichargs ')']);
      end
   else
      [path filename] = fileparts(inPath);
      fn = evalin('caller', ['which(''' filename ''')']);
      if isempty(fn)
         fn = evalin('base', ['which(''' filename ''')']);
      end
   end
end

%---------------------------------------------------------------------
% Returns true if the absolute path that is passed in is syntactically
% equal to a 'private' directory or an object directory
function rcode = isPrivateOrObject(inPath)
   path = fileparts(inPath);
   i1 = strfind(path, [filesep 'private']);
   if isempty(i1)
      i1 = strfind(inPath, [filesep '@']);
   end
   if isempty(i1)
      rcode = false;
   else
      rcode = true;
   end
end

%---------------------------------------------------------------------
% This returns true only if inFilename's case matches what is on disk.
% This function is used instead of the 'exist' function because we want to
% differentiate files 'FOO.m' and 'foo.m' when on UNIX.  The 'exist'
% function will return 2 regardless of the case of the string that is
% passed in.
function existsOnDisk = doesFileExist(inFilename)
   fileObject = java.io.File(inFilename);
   existsOnDisk = false;
   if isempty(fileObject)
      return;
   else
      try
         if fileObject.exists && fileObject.isFile
            [path fn1] = fileparts(inFilename);
            filename2 = char(fileObject.getCanonicalPath);
            [path fn2] = fileparts(filename2);
            if isequal(fn1, fn2)
               existsOnDisk = true;
            end
         end
      catch
         existsOnDisk = false;
      end
   end
end