function [varargout] = uifile(mode, varargin)
%UIFILE Standard get/put dir/file dialog box which remembers last used folder
% UIFILE is a wrapper for Matlab's UI{GET/PUT}{DIR/FILE} functions with the 
% ability to remember the last folder opened.  Only successful file
% selections update the folder remembered.
%
% This version saves the last path infomation in system wide temporary folder.
%
% Usage:
%   [...] = uifile('get', ...);
%   [...] = uifile('put', ...);
%   [...] = uifile('getdir', ...);
%   The rest of input and output arguments are the same as MATLAB built-ins.
%
% This work is a combination of Chris Cannell's uigetfile2 functions.
%
% See also UIGETFILE2, UIGETDIR, UIGETFILE, UIPUTFILE.
%
% Written by: Xiaohu Mo
% xiaohumo@gmail.com

% Argument checking
if nargin < 1
    warning('Usage: uifile(''getfile'', ...)');
    return;
end

% Name of mat file to save last used directory information
lastDirMat = fullfile(tempdir, '_matlabLastUsedDir.mat');

% Try load the saved path and set the dir to use
% default useDir is current path
useDir = pwd;
if exist(lastDirMat, 'file')
    % lastDirMat mat file exists, load it
    load('-mat', lastDirMat)
    % check if lastDir variable exists and contains a valid path
    if exist('lastDir', 'var') && exist(lastDir, 'dir')
        % set default dialog open directory
        useDir = lastDir;
    end
end

% Save the pwd, cd to useDir, open dialog and change back
savedPwd = pwd;
cd(useDir);

% Call uiget/putfile with arguments passed in
switch lower(mode)
    case 'get'
        [varargout{1} varargout{2} varargout{3}] = uigetfile(varargin{1:end});
    case 'put'
        [varargout{1} varargout{2} varargout{3}] = uiputfile(varargin{1:end});
    case 'getdir'
        [varargout{1}] = uigetdir('', varargin{1:end});
end

cd(savedPwd);

% If the user did not cancel the file dialog then update lastDirMat
if ~isequal(varargout{1}, 0)
    try
        % save last folder used to lastDirMat mat file
        switch lower(mode)
            case 'get'
                lastDir = varargout{2};
            case 'put'
                lastDir = varargout{2};
            case 'getdir'
                lastDir = varargout{1};
        end
        save(lastDirMat, 'lastDir');
    catch
        % error saving lastDirMat mat file
        % display warning, the folder will not be remembered
        disp(['Warning: Could not save file ''', lastDirMat, '''']);
    end
end
