function [status, result] = svn(str, p, varargin)

% svn - execute subversion client command
% ---------------------------------------
%
% [status, result] = svn(str, p, arg, ... , arg)
% 
% Input:
% ------
%  str - command string
%  p - path to working copy
%  arg - other arguments to command
%
% Output:
% -------
%  status - system call status output
%  results - system call results output
%
% ---------------------------------------
%
% NOTE: 'TortoiseSVN' must be installed for this command work
% 
% NOTE: use 'svn('help')' and to learn more about available commands

%--------------------------------
% Author: Harold Figueroa
%--------------------------------
% $Revision: 1180 $
% $Date: 2005-07-15 17:22:21 -0400 (Fri, 15 Jul 2005) $
%--------------------------------

%------------------------------------------------------------
% SETUP
%------------------------------------------------------------

%--
% check for svn installation
%--

if isempty(svn_root)
	status = []; result = []; return;
end 

%--
% set persistent location of tortoise subversion client
%--

persistent SVN_CLIENT; 

if isempty(SVN_CLIENT)
	
	SVN_CLIENT = [svn_root, filesep, 'bin\TortoiseProc.exe'];
	
	% NOTE: check whether the client application exists
	
	if ~exist(SVN_CLIENT, 'file')
		
		error( ...
			'''TortoiseSVN'' must be installed for this command to be available.' ...
		); 
	
		SVN_CLIENT = '';
		
	end
	
end 

%--
% set persistent list of available commands
%--

persistent SVN_COMMANDS;

if isempty(SVN_COMMANDS)
	
	SVN_COMMANDS = { ...
		'about', ...
		'help', ...
		'settings', ...
		'blame', ...
		'commit', ...
		'copy', ...
		'diff', ... % NOTE: 'diff' used in this way compares input file to base
		'export', ...
		'log', ...
		'repobrowser','browser', ...
		'repostatus','status', ... 
		'checkout', ...
		'update', ...
		'update_to' ...
	}';

end

%--
% get svn options
%--

opt = svn_options;

%--
% build interaction string based on options
%--

if opt.close
	interact = '/closeonend:1';
else
	interact = '/closeonend:0';
end

% NOTE: non-blocking character is added when needed to completed command string

%------------------------------------------------------------
% HANDLE INPUT
%------------------------------------------------------------

%--
% output available command strings or set default command
%--

if (nargin < 1) || isempty(str)
	
	% NOTE: output requested on no command returns available commands
	
	if nargout
		status = SVN_COMMANDS; return;
	else
		str = 'about';
	end

end

%--
% set default output
%--

status = []; result = '';

%--
% check provided command
%--

if isempty(find(strcmp(str, SVN_COMMANDS)))
	error(['Unrecognized command ''', str, '''.']);
end

%------------------------------------------------------------
% BUILD AND EXECUTE COMMAND
%------------------------------------------------------------

% NOTE: the commands are available in the 'TortoiseSVN' documentation

%--
% put prefix to command string together
%--

cli_pre = ['"', SVN_CLIENT, '" ', interact, ' -notempfile /command:'];

switch str
	
	%-----------------------------------------
	% BASIC SVN COMMANDS
	%-----------------------------------------

	% NOTE: version, help, and settings commands
	
	case { ...
		'about', ...
		'help', ...
		'settings' ...
	}

		cli_str = [cli_pre, str];
		
	%-----------------------------------------
	% BASIC WORKING COPY COMMANDS
	%-----------------------------------------
		
	% NOTE: these take a working copy path or a file in a working copy as argument

	case { ...
		'blame', ...
		'commit', ...
		'copy', ...
		'diff', ... % NOTE: 'diff' used in this way compares input file to base
		'export', ...
		'log', ...
		'repobrowser','browser', ...
		'repostatus','status' ... 
	}

		% TODO: distinguish between directory and file path input

		% NOTE: calling 'diff' with a directory argument is the same as 'status'
		
		%--
		% replace shortcut commands with actual commands
		%--
		
		switch str
			
			case 'browser'
				str = 'repobrowser';
				
			case 'status'
				str = 'repostatus';
				
		end
		
		cli_str = [cli_pre, str, ' /path:"', p, '"'];
		
	%-----------------------------------------
	% COMPLEX WORKING COPY COMMANDS
	%-----------------------------------------
	
	% NOTE: these commands may take other arguments besides working copy path
	
	%-------------------
	% CHECKOUT
	%-------------------
	
	case 'checkout'
		
		cli_str = [cli_pre, str, ' /path:"', p, '" /url:"', varargin{1}, '"'];
		
		disp(cli_str); return;
		
	%-------------------
	% UPDATE
	%-------------------
	
	case { ...
		'update', ...
		'update_to' ...
	}
		
		
		%--
		% update to head revision
		%--
		
		cli_str = [cli_pre, 'update /path:"', p, '"'];
			
		%--
		% ask revision to update to
		%---
		
		if strcmp(str, 'update_to')
			cli_str = [cli_str, ' /rev'];
		end
		
end

%--
% make command non-blocking if needed
%--

% NOTE: the method is the same in both pc and unix machines

if ~opt.block
	cli_str = [cli_str, ' &'];
end

%--
% display and execute command
%--

% disp(' '); disp(cli_str);

[status, result] = system(cli_str);
		