function g = event_view(mode, par, m, ix, ax, data, light_flag)

% event_view - display event in sound and log browser 
% ---------------------------------------------------
%
% g = event_view('sound', par, m, ix, ax, data)
%
%   = event_view('log', par, m, ix, ax, data)
%
% Input:
% ------
%  par - handle to parent figure
%  m - log index
%  ix - event indices
%  ax - handles to axes available for display
%  data - figure userdata
%
% Output:
% -------
%  g - handles to event display objects

%--------------------------------
% Author: Harold Figueroa
%--------------------------------
% $Revision: 6150 $
% $Date: 2006-08-15 02:07:22 -0400 (Tue, 15 Aug 2006) $
%--------------------------------

% TODO: make possible the display of deleted 

%---------------------------------------------------
% HANDLE INPUT
%---------------------------------------------------
		
%--
% set default light_flag
%--

if (nargin < 7) || isempty(light_flag)
	light_flag = 0;
end

%--
% get userdata if needed
%--

if (nargin < 6) || isempty(data)
	data = get(par, 'userdata');
end 

%--
% get display axes if needed
%--

if (nargin < 5)
	ax = data.browser.axes;
end

%--
% get parent userdata in case of log browser display
%--

if strcmp(mode, 'log')
	data = get(data.browser.parent, 'userdata');
end 

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

%--
% copy browser state elements for convenience
%--

gopt = data.browser.grid;

sound = data.browser.sound;

ANNOT_VIEW = data.browser.annotation.view;

MEAS_VIEW = data.browser.measurement.view;

%--
% compute kHz flag
%--

khz_flag = strcmp(gopt.freq.labels, 'kHz');

%--
% other convenience variables
%--

% log index string

mstr = int2str(m);

% extracted channels array

ch = get_channels(data.browser.channels);

%--
% get events parent log
%--

if ischar(m)

	if ~strcmp('__ACTIVE_DETECTION__', m)
		g = []; return;
	end
	
	log = data.browser.active_detection_log;
	
	active_flag = 1;

else
	
	log = data.browser.log(m);
	
	active_flag = 0;
	
end 

% THESE QUICK RETURN TESTS NEED IMPROVEMENT

if (log.length < 1)
	g = []; return;
end

if (min(ix) < 0) || (max(ix) > log.length)	
	g = []; return;
end
	
%---------------------------------------------------
% DISPLAY EVENTS
%---------------------------------------------------

for k = 1:length(ix)

	%--
	% get event
	%--

	event = log.event(ix(k));

	%--
	% compute event coordinates in axes
	%--

	[x, y] = axes_coordinates(event, sound, khz_flag);

	%--
	% get display axes
	%--

	if strcmp(mode, 'sound')
		dax = data.browser.axes(find(ch == event.channel));
	else
		dax = findobj(ax, 'flat', 'tag', [mstr '.' int2str(ix(k))]);
	end

	%---------------------------------------------------
	% DISPLAY EVENT BOX
	%---------------------------------------------------

	%--
	% create event display objects
	%--

	style = log.linestyle; width = log.linewidth;

	%----------------------------
	% ACTIVE DETECTION DISPLAY
	%----------------------------
	
	if active_flag

		%----------------------------
		% SOUND BROWSER DISPLAY
		%----------------------------

		active_colors = 'ants';

		switch (active_colors)

			case ('candy') 	
				C1 = [1 0 0]; 
				C2 = [1 1 1];

			case ('fire')
				C1 = [1 0 0];
				C2 = [1 1 0];

			case ('ants')
				C1 = [0 0 0]; 
				C2 = [1 1 1];

			case ('blue-yellow')
				C1 = [1 1 0]; 
				C2 = [0 0 1];

			case ('red-green')
				C1 = [1 0 0]; 
				C2 = [0 1 0];

		end

		width = data.browser.selection.linewidth;

		g(k,1) = line( ...
			'parent',dax, ...
			'xdata',x, ...
			'ydata',y, ...
			'linestyle','-', ...
			'linewidth',width, ...
			'color',C1 ...
		);

		g(k,2) = line( ...
			'parent',dax, ...
			'xdata',x, ...
			'ydata',y, ...
			'linestyle',':', ...
			'linewidth',width, ...
			'color',C2 ...
		);

		% display patch to enable selection

		g(k,3) = patch( ...
			'parent',dax, ...
			'xdata',x, ...
			'ydata',y, ...
			'EdgeColor','none', ...
			'FaceColor','none', ...
			'Erasemode','none' ...
		);

		tag = ['ACTIVE_DETECTION.' int2str(ix(k))];

		set(g(k,:),'tag',tag);

	%----------------------------
	% LOG DISPLAY
	%----------------------------

	else

		color = log.color;
		
		if (light_flag)
			color = (0.5 + 0.25 * color);
		end

		alpha = log.patch;

		%----------------------------
		% SOUND BROWSER DISPLAY
		%----------------------------

		if strcmp(mode, 'sound')

			if (alpha > 0) && ~light_flag
				g(k,1) = patch( ...
					'parent',dax, ...
					'xdata',x, ...
					'ydata',y, ...
					'linestyle',style, ...
					'linewidth',width, ...
					'EdgeColor',color, ...
					'FaceColor',color, ...
					'FaceAlpha',alpha ...
				);	
			else
				g(k,1) = patch( ...
					'parent',dax, ...
					'xdata',x, ...
					'ydata',y, ...
					'linestyle',style, ...
					'linewidth',width, ...
					'EdgeColor',color, ...
					'FaceColor','none', ...
					'Erasemode','none' ...
				);
			end

			%--
			% display event id text
			%--

			if log.event_id

				g(k,2) = text( ...
					'parent',dax, ...
					'position',[x(1),y(3),0], ...
					'string',['#' int2str(event.id)], ...
					'clipping','on', ...
					'color',color, ...
					'edgecolor',color, ...
					'linestyle','-', ...
					'margin',2, ...
					'HorizontalAlignment','right', ...
					'VerticalAlignment','bottom', ...
					'fontweight','bold', ...
					'rotation',0 ...
				);

				% NOTE: this is the same color used in 'text_highlight'
				
				if ~light_flag
					text_highlight(g(k,2));
				end

			end

			tag = [mstr, '.', int2str(ix(k))];

			set(g(k,:), 'tag', tag);

		%----------------------------
		% LOG BROWSER DISPLAY
		%----------------------------

		else

			g(k,1) = line( ...
				'parent',dax, ...
				'xdata',x, ...
				'ydata',y, ...
				'linestyle',style, ...
				'linewidth',width, ...
				'color',color ...
			);

			if (alpha > 0)
				g(k,2) = patch( ...
					'parent',dax, ...
					'xdata',x, ...
					'ydata',y, ...
					'EdgeColor','none', ...
					'FaceColor',color, ...
					'FaceAlpha',alpha ...
				);	
			else
				g(k,2) = patch( ...
					'parent',dax, ...
					'xdata',x, ...
					'ydata',y, ...
					'EdgeColor','none', ...
					'FaceColor','none', ...
					'Erasemode','none' ...
				);
			end

			tag = [mstr '.' int2str(ix(k))];

			set(g(k,:), 'tag', tag);
			set(g(k,2), 'hittest', 'off');

			hi = findobj(gca, 'type', 'image');

			set(hi, 'tag', tag);
			set(gca, 'tag', tag);

		end

	end
	
	%---------------------------------------------------
	% EARLY EXIT FOR LIGHTWEIGHT MODE
	%---------------------------------------------------
	
	if light_flag
		continue;
	end	
	
	%---------------------------------------------------
	% DISPLAY LABEL (FROM TAGS)
	%---------------------------------------------------
	
	
	% TODO: get label from tags, then get display code from 'simple_annotation' code

	
	
	%---------------------------------------------------
	% DISPLAY EVENT ANNOTATIONS
	%---------------------------------------------------

	% TODO: this needs to be generalized to handle pre-selection display

	if ~isempty(ANNOT_VIEW)

		%--
		% loop over event annotations
		%--

		% FIXME: problems here, if the active detection events contained non-empty annotation

		for j  = 1:length(event.annotation)				

			if ~isempty(find(strcmp(ANNOT_VIEW, event.annotation(j).name), 1))

				% NOTE: the empty log index informs the system of active detection

				if active_flag
					event.annotation(j).fun('display', par, [], ix(k), data);
				else
					event.annotation(j).fun('display', par, m, ix(k), data);
				end

			end

		end

	end

	%---------------------------------------------------
	% DISPLAY EVENT MEASUREMENTS
	%---------------------------------------------------

	% TODO: exceptions must be handled here and extension warning produced
	
	if ~isempty(MEAS_VIEW)

		%--
		% loop over event measurements
		%--

		for j  = 1:length(event.measurement)
			
			if ~isempty(find(strcmp(MEAS_VIEW, event.measurement(j).name), 1))
				event.measurement(j).fun('display', par, m, ix(k), data);
			end

		end

	end

	%---------------------------------------------------
	% ATTACH CONTEXT MENU ACTION
	%---------------------------------------------------	

	%--
	% attach event menu to patch context menu
	%--

	if ~active_flag

		if strcmp(mode, 'sound')

			% NOTE: the 'ishandle' call seems costly for this level

			if ishandle(g(k,1))
				set(g(k,1), ...
					'buttondownfcn', {@event_menu_bdfun, 'sound', par, m, ix(k)} ...
				); 
			end 

		else

			set(hi, ...
				'buttondownfcn', {@event_menu_bdfun, 'log', par, m, ix(k)} ...
			);

		end

	else

		set(g(k,3), ...
			'buttondownfcn', {@active_bdfun, par, khz_flag} ...
		);

	end

end

%---------------------------
% HANDLE MARCHING ANTS
%---------------------------

if active_flag
	
	%--
	% get or create daemon
	%--
	
	daemon = marching_ants_daemon(g);
	
	%--
	% start marching ants on the lines given by handles
	%--
	
	if strcmp(get(daemon, 'running'), 'off')
		start(daemon);
	end
			
end


%--------------------------------------------------------
% ACTIVE_BDFUN
%--------------------------------------------------------

function active_bdfun(obj, eventdata, par, khz)

%--
% get event information from display
%--

ch = eval(get(get(obj,'parent'),'tag'));

time = fast_min_max(get(obj,'xdata'));

freq = fast_min_max(get(obj,'ydata'));

if (khz)
	freq = 1000 * freq;
end

%--
% create and set event as selection
%--

event = event_create( ...
	'channel', ch, ...
	'time', time, ...
	'freq', freq ...
);

figure(par);

% TODO: the pre-selection buttondown function should be different and provide for display of detection values

browser_bdfun(event);


%--------------------------------------------------------
% GET_ANT_TYPES
%--------------------------------------------------------

function types = get_ant_types

types = {'black', 'candy', 'fire'};


%--------------------------------------------------------
% GET_ANT_COLORS
%--------------------------------------------------------

function color = get_ant_colors(type)

%--
% check ant type
%--

types = get_ant_types;

if ~ismember(type, get_ant_types)
	type = types{1};
end

%--
% get ant colors using type
%--

switch type

	case 'black'
		color.one = [0 0 0]; color.two = [1 1 1];

	case 'candy'
		color.one = [1 0 0]; color.two = [1 1 1];

	case 'fire'
		color.one = [1 0 0]; color.two = [1 1 0];

end


%--------------------------------------------------------
% MARCHING_ANTS_DAEMON
%--------------------------------------------------------

function daemon = marching_ants_daemon(handles)

%--
% try to get daemon
%--

daemon = timerfind('name', 'XBAT Marching Ants');

%--
% create and configure daemon if needed
%--

if isempty(daemon)

	daemon = timer;

	% NOTE: timer speed is set for comfort and performance
	
	set(daemon, ...
		'name', 'XBAT Marching Ants', ...
		'timerfcn', @march_ants, ...
		'executionmode', 'fixedRate', ...
		'period', 0.5 ...
	);

end

%--
% set handles to march
%--

if nargin
	set(daemon, 'userdata', handles);
end


%--------------------------------------------------------
% MARCH_ANTS
%--------------------------------------------------------

function march_ants(obj, eventdata)

%--
% get handles to march
%--

handles = get(obj, 'userdata');

% NOTE: this is a temporary solution

if isempty(handles) || ~ishandle(handles(1,1))
	return;
end 

%--
% this code is very specific to this context
%--

par = get(get(handles(1), 'parent'), 'parent');

%--
% get and exchange line colors
%--

% NOTE: the first two columns contain the event boundary lines

c1 = get(handles(1,1), 'color');

c2 = get(handles(1,2), 'color');

set(handles(:,1), 'color', c2);

set(handles(:,2), 'color', c1);

% NOTE: move selection grid to back if needed

grid = findobj(par, 'tag', 'selection', 'type', 'line', 'linestyle', ':');

if ~isempty(grid)
	uistack(grid, 'bottom');
end

%--
% refresh figure
%--

% NOTE: this is a required costly step, consider 'drawnow'

refresh(par);


