function set_browser_mode(h,mode,data)

% set_browser_mode - set browser selection mode
% ---------------------------------------------
%
% flag = set_browser_mode(h,'hand')
%      = set_browser_mode(h,'group')
%      = set_browser_mode(h,'select')
% 
% Input:
% ------
%  h - handle to parent browser figure

%--------------------------------
% Author: Harold Figueroa
%--------------------------------
% $Revision: 132 $
% $Date: 2004-12-02 15:58:47 -0500 (Thu, 02 Dec 2004) $
%--------------------------------

% NOTE: at the moment the state saved in the browser selection mode

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

%--
% get parent data if needed
%--

if ((nargin < 3) || isempty(data))
	data = get(h,'userdata');
end

%----------------------------------
% SET MODE
%----------------------------------

switch (mode)
	
	%----------------------------------
	% HAND MODE
	%----------------------------------
	
	% NOTE: this mode permits fine tuned navigation in time
	
	case ('hand')
		
		%--
		% turn off selection callbacks
		%--
		
		set(data.browser.images,'buttondownfcn',[]);
		
		%--
		% set pointer and mode callbacks
		%--
		
		setptr(h,'hand');
		
		slider = findobj(h,'tag','BROWSER_TIME_SLIDER');
		
		set(h, ...
			'windowbuttondownfcn',{@drag_start,slider}, ...
			'windowbuttonupfcn',{@drag_end,slider} ...
		);
	
		%--
		% update userdata
		%--
		
		data.browser.selection.mode = mode;
		set(h,'userdata',data);
		
	%----------------------------------
	% GROUP MODE
	%----------------------------------
	
	% NOTE: this mode permits the creation of hierarchical events
	
	
	case ('group')
		
	%----------------------------------
	% SELECTION MODE
	%----------------------------------
	
	% NOTE: the familiar selection mode available in earlier versions
	
	case ('select')
		
		%--
		% turn off hand navigation callbacks
		%--
		
		set(h, ...
			'windowbuttondownfcn',[], ...
			'windowbuttonupfcn',[] ...
		);
	
		%--
		% set pointer and mode callbacks
		%--
		
		setptr(h,'arrow');
		
		set(data.browser.images,'buttondownfcn','browser_bdfun;');
		
		%--
		% update userdata
		%--
		
		data.browser.selection.mode = mode;
		set(h,'userdata',data);
		
	%----------------------------------
	% UNRECOGNIZED MODE
	%----------------------------------
	
	otherwise
		
		disp(' ');
		warning('Unrecognized browser mode.');
		
end

%---------------------------------------------
% DRAG_START
%---------------------------------------------

function drag_start(obj,eventdata,slider)

%--------------------------------
% Author: Harold Figueroa
%--------------------------------
% $Revision: 132 $
% $Date: 2004-12-02 15:58:47 -0500 (Thu, 02 Dec 2004) $
%--------------------------------

%--
% set pointer
%--

setptr(obj,'closedhand');
	
%--
% create drag state structure
%--

ax = gca;

point = get(ax,'currentpoint');
point = point(1,1:2);

drag.axes = ax;
drag.start = point;
drag.end = [];

set_env('DRAG_STRUCT',drag);

%--
% set button motion function
%--

m = get(slider,'min'); 
M = get(slider,'max');

set(gcf,'windowbuttonmotionfcn',{@drag_update,slider,m,M});
	
	
%---------------------------------------------
% DRAG_UPDATE
%---------------------------------------------

function drag_update(obj,eventdata,slider,m,M)

%--------------------------------
% Author: Harold Figueroa
%--------------------------------
% $Revision: 132 $
% $Date: 2004-12-02 15:58:47 -0500 (Thu, 02 Dec 2004) $
%--------------------------------

%--
% set update direction sum variable
%--

persistent DIR_SUM;

if (isempty(DIR_SUM))
	DIR_SUM = 0;
end 

%--
% check that we are within starting axes
%--

ax = gca; drag = get_env('DRAG_STRUCT');

% NOTE: this handles a rare callback sync error

if (isempty(drag))
	return;
end

if (drag.axes ~= ax)
	return;
end
	
%--
% compute current end point
%--

point = get(ax,'currentpoint');
point = point(1,1:2);

drag.end = point;

%--
% get drag length (note the reversal) and slider properties
%--

% NOTE: this exception handles drag ending in other figures

try
	dt = drag.start(1) - drag.end(1);
catch
	return;
end

t = get(slider,'value');

%--
% check that change is significant
%--

% NOTE: increments are required to be larger than 0.01 of a page

if (abs(dt / diff(get(ax,'xlim'))) < 0.01)
	return;
end

%--
% update time slider
%--

t = t + dt;

if (t < m)
	t = m;
end

if (t > M)
	t = M;
end

%--
% update the slider when the motion direction is stable
%--

DIR_SUM = DIR_SUM + sign(dt);

if (abs(DIR_SUM) > 1)
	
	set(slider,'value',t); 
	DIR_SUM = 0;
	
end


%---------------------------------------------
% DRAG_END
%---------------------------------------------

function drag_end(obj,eventdata,slider)

%--------------------------------
% Author: Harold Figueroa
%--------------------------------
% $Revision: 132 $
% $Date: 2004-12-02 15:58:47 -0500 (Thu, 02 Dec 2004) $
%--------------------------------

%--
% update pointer and button motion function
%--

setptr(obj,'hand');

set(gcf,'windowbuttonmotionfcn',[]);

%--
% discard drag environment variable
%--

rm_env('DRAG_STRUCT',0);