function h=editlist(hfig, type, p1,v1,p2,v2,p3,v3,p4,v4,p5,v5,p6,v6,p7,v7,p8,v8,p9,v9,p10,v10)
%EDITLIST  Edit uicontrol for list with increment buttons/slide tool.
%
%   H=EDITNUM(HFIG, TYPE, 'P1',V1,'P2',V2,P3,V3...)
%
%   Where:
%    HFIG : The figure handle (default gcf)
%    TYPE : Specify the different control type (default BT_RR)
%    Pn   : Uicontrol property name (up to 10 parameters are allowed)
%    Vn   : Uicontrol property value
%    H    : The handle of the 'edit' uicontrol object created
%
%
%  This function allow you to create in a single call a useful
%  uicontrol system for list. 
%  Different tools can be specified to modify the list with the mouse.
%  Setting the 'style' to 'text' (instead of the default 'edit'
%  allow the user to modify the number only with the mouse.
%  The Item can also be entered by typing it. If it is a item of the list
%  it is kept and the value is set to correspond to the list index, 
%  else the previous item is manteined.
%  The list is passed in the 'string' property and is always stored
%  in the 'ButtonDownFcn' property.
%
%  Setting 'min' to 0 the list is Case Insensitive (default)
%  Setting 'min' to 1 the list is Case Sensitive
%
%  To read the current value in the list use: 
%
%    value=get(H, 'value');
%
%  To read the current string of the list use: 
%
%    value=get(H, 'string');
%  
%  To set the list item internally to a function use:
%
%    set(H, 'string', item);
%    set(get(H, 'parent'), 'CurrentObject', H);
%    eval(get(H, 'CallBack'));
%
%
%  If the parameter position is specified it refers to the
%  total size of the uicontrols (edit plus buttons/slide) created.
%
%  Valid types are:
%      BT_RR  with buttons on the right
%      BT_LL  with buttons on the left
%      BT_TT  with buttons on the top
%      BT_BB  with buttons on the bottom
%      BT_LR  with buttons on the left and right
%      BT_TB  with buttons on the top and bottom
%      SL_T   with slide on the top
%      SL_B   with slide on the bottom
%      SL_L   with slide on the left
%      SL_R   with slide on the right
%      NN     without increment tools
%
%   
%    Note: if one of the properties is a callback, it will be evaluated
%    also when the increment tools are pushed with the mouse.
%    The setlist function is always added before the edit callback.
%    To start with a particular item set the 'value' property
%    to the item index in the list.
%    The pushbuttons handles or the slide handle are stored
%    in the 'edit' uicontrol userdata.
%    The size and the string of the buttons or slide can be changed
%    in the first lines of this function.
%
%    If a tag is specified it is set to the edit uicontrol only.
%    Therefore, findobj('tag', 'MYTAG') will find only
%    one uicontrol.
%
%    Bugs: When the slide is on the left or right and the 'edit'
%    uicontrol usually it is not high enough and the slide arrows
%    will not be shown. This is a Matlab problem that I was not 
%    able to overcome.
%
%    Example:
%    figure('position',  [200 400 280  80]);
%    p=[.2 .2 0.2 0.05];
%    S='Item 1|Item 2|Item 3|Item 4|Item 5';
%    h=editlist(gcf, 'BT_RR', 'units','norm','pos', p, 'string', S)
%
%    See also: UICONTROL, UICPUSH.

% This function can be modified with the only restriction that the
% next two lines have to be reteined.
%             Copyright (c) 1996 by Claudio Rivetti 
%                  claudio@alice.uoregon.edu
%
% Last version: October 6, 1996.
% ENJOY IT!
%


% definition of the increment tools size in pixels.
BT_SIZE=16;
SL_SIZE=14;

% definition of the buttons 'string'.
BT2_STR='+';
BT1_STR='-';


if nargin > 22
	error('Too many input arguments.');
end

%Set the default values if needed
if nargin<2
	if nargin == 0, hfig=gcf; type='BT_RR'; end
	if nargin == 1, type='BT_RR'; end
end


type=upper(strrep(type, ' ', ''));

valid_types=[	'BT_RR';...
				'BT_LL';...
				'BT_TT';...
				'BT_BB';...
				'BT_LR';...
				'BT_TB';...
				'SL_T ';...
				'SL_B ';...
				'SL_L ';...
				'SL_R ';...
				'NN   '];	

% Check if type is a valid string 	
ok=0;			
for i=1:size(valid_types,1)
	if strcmp(strrep(valid_types(i,:), ' ',''), type)
		ok=1;
	end
end

if ~ok
	error([type ' is not a valid type.']);
end

% Split the type string
[uic_type, type]=strtok(type, '_');
[pos_type, type]=strtok(type, '_');


% Create the edit uicontrol
h=uicontrol(hfig, 'style', 'edit');

% Set the passed parameters in the h properties
if nargin > 2,
        if (nargin-2)/2-fix((nargin-2)/2),
                error('Incorrect number of input arguments')
        end
        cmdstr='';
        for i=1:(nargin-2)/2-1,
                cmdstr = [cmdstr,'p',num2str(i),',v',num2str(i),','];
        end
        cmdstr = [cmdstr,'p',num2str((nargin-2)/2),',v',num2str((nargin-2)/2)];
        eval(['set(h,',cmdstr,');']);
end


% Set the starting value and string
str=get(h, 'string');
v=get(h, 'value');
if v<size(str,1) | v>size(str,1)
	v=1;
end
bdf='%';
for i=1:size(str,1)
	bdf=[bdf '|' deblank(str(i,:))];
end

set(h, 'string', str(v,:), 'value', v, 'ButtonDownFcn', bdf);


% Build the edit callback
cbk=get(h, 'CallBack');
if strcmp(uic_type, 'SL')
	ed_cbk=['setlist(gco, get(gco, ''string''));set(get(gco, ''user''), ''value'', get(gco, ''value''));drawnow;' cbk];
else
	ed_cbk=['setlist(gco, get(gco, ''string''));drawnow;' cbk];
end

set(h, 'CallBack', ed_cbk);


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                        BUTTONS CASE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if strcmp(uic_type, 'BT')

	old_units=get(h, 'units');
	set(h, 'units', 'pixels');

	if strcmp(pos_type, 'RR')
		pos=get(h, 'pos');
		bw=BT_SIZE;
		pos(3)=pos(3)-bw;
		set(h, 'pos', pos);
		pb1=[pos(1)+pos(3) pos(2)          bw pos(4)/2];
		pb2=[pos(1)+pos(3) pos(2)+pos(4)/2 bw pos(4)/2];
	end
	if strcmp(pos_type, 'LL')
		pos=get(h, 'pos');
		bw=BT_SIZE;
		pos(1)=pos(1)+bw;
		pos(3)=pos(3)-bw;
		set(h, 'pos', pos);
		pb1=[pos(1)-bw pos(2)          bw pos(4)/2];
		pb2=[pos(1)-bw pos(2)+pos(4)/2 bw pos(4)/2];
	end
	if strcmp(pos_type, 'TT')
		pos=get(h, 'pos');
		bh=BT_SIZE;
		pos(4)=pos(4)-bh;
		set(h, 'pos', pos);
		pb1=[pos(1)          pos(2)+pos(4) pos(3)/2 bh];
		pb2=[pos(1)+pos(3)/2 pos(2)+pos(4) pos(3)/2 bh];
	end
	if strcmp(pos_type, 'BB')
		pos=get(h, 'pos');
		bh=BT_SIZE;
		pos(2)=pos(2)+bh;
		pos(4)=pos(4)-bh;
		set(h, 'pos', pos);
		pb1=[pos(1)          pos(2)-bh pos(3)/2 bh];
		pb2=[pos(1)+pos(3)/2 pos(2)-bh pos(3)/2 bh];
	end
	if strcmp(pos_type, 'LR')
		pos=get(h, 'pos');
		bw=BT_SIZE;
		pos(1)=pos(1)+bw;
		pos(3)=pos(3)-2*bw;
		set(h, 'pos', pos);
		pb1=[pos(1)-bw     pos(2) bw pos(4)];
		pb2=[pos(1)+pos(3) pos(2) bw pos(4)];
	end
	if strcmp(pos_type, 'TB')
		pos=get(h, 'pos');
		bh=BT_SIZE;
		pos(2)=pos(2)+bh;
		pos(4)=pos(4)-2*bh;
		set(h, 'pos', pos);
		pb1=[pos(1) pos(2)-bh     pos(3) bh];
		pb2=[pos(1) pos(2)+pos(4) pos(3) bh];
	end
	
	
	bt_cbk1='setlist(get(gco, ''userdata''), get(get(gco, ''userdata''), ''value'')+get(gco, ''min''));';
	bt_cbk=[bt_cbk1 'drawnow;' cbk];
	
	v1=-1;
	v2=1;
	b1=uicontrol(hfig,  'style', 'push',...
						'pos', pb1,...
						'string', BT1_STR,...
						'BackgroundColor', get(h, 'BackgroundColor'),...
						'ForegroundColor', get(h, 'ForegroundColor'),...
						'HorizontalAlignment', 'center',...
						'Units', get(h, 'Units'),...
						'Visible', get(h, 'Visible'),...
						'Enable', get(h, 'Enable'),...
						'Userdata', h,...
						'min', v1,...
						'CallBack', bt_cbk);
						
	b2=uicontrol(hfig,  'style', 'push',...
						'pos', pb2,...
						'string', BT2_STR,...
						'BackgroundColor', get(h, 'BackgroundColor'),...
						'ForegroundColor', get(h, 'ForegroundColor'),...
						'HorizontalAlignment', 'center',...
						'Units', get(h, 'Units'),...
						'Visible', get(h, 'Visible'),...
						'Enable', get(h, 'Enable'),...
						'Userdata', h,...
						'min', v2,...
						'CallBack', bt_cbk);
						
						
	set(h, 'userdata', [b1 b2], 'units', old_units);
	set(b1, 'units',  old_units);
	set(b2, 'units',  old_units);

end  %BUTTONS CASE





%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                        SLIDE CASE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if strcmp(uic_type, 'SL')
	
	old_units=get(h, 'units');
	set(h, 'units', 'pixels');

	if strcmp(pos_type, 'B')
		pos=get(h, 'pos');
		sh=pos(4)/3;
		sh=SL_SIZE;
		pos(4)=pos(4)-sh;
		pos(2)=pos(2)+sh;
		set(h, 'pos', pos);
		sl_pos=[pos(1) pos(2)-sh pos(3) sh];
	end
	if strcmp(pos_type, 'T')
		pos=get(h, 'pos');
		sh=SL_SIZE;
		pos(4)=pos(4)-sh;
		set(h, 'pos', pos);
		sl_pos=[pos(1) pos(2)+pos(4) pos(3) sh];
	end
	if strcmp(pos_type, 'R')
		pos=get(h, 'pos');
		sw=SL_SIZE;
		pos(3)=pos(3)-sw;
		set(h, 'pos', pos);
		sl_pos=[pos(1)+pos(3) pos(2) sw pos(4)];
	end
	if strcmp(pos_type, 'L')
		pos=get(h, 'pos');
		sw=SL_SIZE;
		pos(3)=pos(3)-sw;
		pos(1)=pos(1)+sw;
		set(h, 'pos', pos);
		sl_pos=[pos(1)-sw pos(2) sw pos(4)];
	end

	
	sl_cbk1=['set(gco,  ''value'',  get(get(gco, ''userdata''), ''value'') + max(abs(get(get(gco, ''userdata''), ''value'')-get(gco,  ''value'')), str2num(get(gco,  ''string'')))*sign(get(gco,  ''value'')-get(get(gco, ''userdata''), ''value'')));', ...
			'set(gco,  ''value'',  round(get(gco,  ''value'')/str2num(get(gco,  ''string'')))*str2num(get(gco,  ''string'')));'];
	sl_cbk2='setlist(get(gco, ''userdata''), get(gco, ''value''));';
	sl_cbk=[sl_cbk1 sl_cbk2 'drawnow;' cbk];
	
	
	sl=uicontrol(hfig,  'style', 'slide',...
						'pos', sl_pos,...
						'string', '1',...
						'BackgroundColor', get(h, 'BackgroundColor'),...
						'ForegroundColor', get(h, 'ForegroundColor'),...
						'Units', get(h, 'Units'),...
						'Visible', get(h, 'Visible'),...
						'Userdata', h,...
						'min', 1,...
						'max', size(str,1),...
						'value', get(h, 'value'),...
						'CallBack', sl_cbk);
						
	set(h, 'userdata', sl, 'units', old_units);
	set(sl, 'units',  old_units);

end %  SLIDE CASE


return



