function generate_function(ext, fun)

% generate_function - generate template function for extension
% ------------------------------------------------------------
%
% generate_function(ext, fun)
%
% Input:
% ------
%  ext - extension to generate function for
%  fun - name of function to generate
%
% Output
% ------
%  flag - success flag

%--------------------------------
% Author: Harold Figueroa
%--------------------------------
% $Revision: 1600 $
% $Date: 2005-08-18 17:41:06 -0400 (Thu, 18 Aug 2005) $
%--------------------------------

% TODO: generate null or identity compute as default to make extensions 'able'

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

%--
% get interface information for extension type
%--

type = ext.subtype;

[name, args, sig] = extension_signatures(type);

%--
% set default functions to generate
%--

% NOTE: the default is to generate all

if nargin < 2
	fun = name;
end

% NOTE: return if there is nothing to generate

if isempty(fun)
	return;
end

% NOTE: wrap fun string in cell

if ischar(fun)
	fun = {fun};
end

%-----------------------------------
% GENERATE FUNCTIONS
%-----------------------------------

root = extension_root(ext);

%--
% loop over requested functions
%--

for k = 1:length(fun)
	
	%--
	% find function in interface
	%--
	
	ix = find(strcmp(name, fun{k}));
	
	if isempty(ix)
		continue;
	end
	
	%--
	% check for file, continue if it exists, create if needed
	%--
	
	f = [root, filesep, 'private', filesep, name{ix}, '.m'];
	
	% TODO: ask if we want to regenerate file
	
	if exist(f, 'file')
		continue;
	end
	
	fid = fopen(f, 'w'); rel_path(f);
	
	%-- 
	% add function signature and indicator comment
	%--
	
	fprintf(fid, '%s\n\n%s\n\n', ...
		['function ', sig{ix}], ...
		['% ', upper(ext.name), ' - ', name{ix}] ...
	);

	%--
	% add lazy body to compute to make extension able
	%--
	
	if strcmp(name{ix}, 'compute')
		
		%--
		% generate lazy body based on type
		%--
		
		switch type
			
			case {'signal_filter', 'image_filter'}
				
				% NOTE: copy first input to the first output to get operator identity
				
				body = [args{ix}{1}{1}, ' = ', args{ix}{2}{1}, ';'];
				
			case 'detector'
				
				% NOTE: return no events to get detection additive identity
				
				body = '';
				
				for j = 1:numel(args{ix}{1})
					body = [body, args{ix}{1}{j}, ' = []; '];
				end
				
			otherwise
				
				body = '';
				
		end
		
		%--
		% add lazy body to file
		%--
		
		if ~isempty(body)
			fprintf(fid, '%s\n', body);
		end
		
	end
	
	%--
	% create control skeleton 
	%--
	
	% TODO: control create and callback should be created together
	
	% NOTE: callback is a separate function so we can route callback
	
	if strcmp(name{ix}, 'parameter__control__create')
	
		%--
		% check for context dependency
		%--
		
		% NOTE: try to create the parameters without context, otherwise continue
		
		context = [];
		
		% TODO: somewhere we must check that parameter is struct
		
		try
			parameter = ext.fun.parameter.create(context);
		catch
			fclose(fid); continue;
		end
		
		lines = generate_control_code(parameter);
		
		file_writelines(fid, lines);
					
	end
	
	%--
	% create callback skeleton
	%--
	
	if strcmp(name{ix}, 'parameter__control__callback')
		
		% TODO: eventually use the template system to generate this code
		
		try
			parameter = ext.fun.parameter.create();
		catch
			fclose(fid); continue;
		end
		
		lines = generate_callback_code(parameter);
		
		file_writelines(fid, lines);
	
	end
	
	%--
	% close file
	%--
	
	fclose(fid);
	
end
