function handle=colorbar(arg1, arg2, arg3)
%COLORBAR Display color bar (color scale).
%   This file is from MATLAB R12
%   COLORBAR('vert') appends a vertical color scale to the current
%   axes. COLORBAR('horiz') appends a horizontal color scale.
%
%   COLORBAR(H) places the colorbar in the axes H. The colorbar will
%   be horizontal if the axes H width > height (in pixels).
%
%   COLORBAR without arguments either adds a new vertical color scale
%   or updates an existing colorbar.
%
%   H = COLORBAR(...) returns a handle to the colorbar axes.
%
%   COLORBAR(...,'peer',AX) creates a colorbar associated with axes AX
%   instead of the current axes.
%
%   See also IMAGESC.

%   Clay M. Thompson 10-9-92
%   Copyright 1984-2000 The MathWorks, Inc. 
%   $Revision: 1.1 $  $Date: 2002/11/07 21:05:32 $

narg = nargin;
if narg<2
	haxes = gca;
	hfig = gcf;
	if narg<1
    	loc = 'vert'; % Default mode when called without arguments.
	else
		% Peer must be followed by a valid axes handle.
		if strcmp(arg1,'peer')
			error('Parameter ''peer'' must be followed by an axes handle.');
		end
		loc = arg1;
	end
elseif narg == 2
	% This is the case ONLY when peer and a handle is passed.
	if strcmp(arg1,'peer')
		if ishandle(arg2) & strcmp(get(arg2, 'type'), 'axes')
			haxes = arg2;
			hfig = get(haxes,'parent');
			loc = 'vert';
			narg = 0;
		else
			% If second arg is not a valid axes handle
			error('Second argument must be a scalar axes handle.');
		end
	else
		error('Unknown command option.');
	end
else
	% For three arguments the first must be the mode or a axes handle, 
	% second must be the string 'peer' and third must be the peer axes handle.
	loc = arg1;
	if strcmp(arg2,'peer')
		if ishandle(arg3) & strcmp(get(arg3, 'type'), 'axes')
			haxes = arg3;
			hfig = get(haxes,'parent');
			narg = 1;
		else
			error('Third argument must be a scalar axes handle.');
		end
	else
		error('Unknown command option.');
	end
end

% Catch colorbar('delete') special case -- must be called by the deleteFcn.
if narg==1 & strcmp(loc,'delete')
    ax = gcbo;
    
    % 
    % If called from DeleteProxy, delete the colorbar axes
    %
    if strcmp(get(ax,'tag'),'ColorbarDeleteProxy')
        cbo = ax;
        ax = get(cbo,'userdata');
        if ishandle(ax)
            ud = get(ax,'userdata');
            
            % Do a sanity check before deleting colorbar
            if isfield(ud,'DeleteProxy') & ...
                    isequal(ud.DeleteProxy,cbo) & ...
                    ishandle(ax)
                try
            	    delete(ax)
            	end
            end
        end
    else
        %
        % If called from the colorbar image resize the original axes
        %
        if strcmp(get(ax,'tag'),'TMW_COLORBAR')
            ax=get(ax,'parent');
        end
        
        ud = get(ax,'userdata');
        if isfield(ud,'PlotHandle') & ...
                ishandle(ud.PlotHandle) & ...
                isfield(ud,'origPos') & ...
                ~isempty(ud.origPos)
            
            units = get(ud.PlotHandle,'units');
            set(ud.PlotHandle,'units','normalized');
            set(ud.PlotHandle,'position',ud.origPos);
            set(ud.PlotHandle,'units',units);
            
            
            legH=legend(ud.PlotHandle);
            if ~isempty(legH) & ishandle(legH)
                legend('RecordSize',ud.PlotHandle);
                legend(legH) % Update legend
            end
        end
        
        if isfield(ud,'DeleteProxy') & ishandle(ud.DeleteProxy)
            try
                delete(ud.DeleteProxy)
            end
        end
    end
    return
end

%   If called with COLORBAR(H) or for an existing colorbar, don't change
%   the NextPlot property.
ax = [];
changeNextPlot = 1;
if narg==1
    if ishandle(loc)
        ax = loc;
        if ~strcmp(get(ax,'type'),'axes'),
            error('Requires axes handle.');
        end
        
        units = get(ax,'units');
        set(ax,'units','pixels');
        rect = get(ax,'position');
        set(ax,'units',units);
        if rect(3) > rect(4)
            loc = 'horiz';
        else
            loc = 'vert';
        end
        changeNextPlot = 0;
    end
end

% Determine color limits by context.  If any axes child is an image
% use scale based on size of colormap, otherwise use current CAXIS.

ch = get(gcda(hfig,haxes),'children');
hasimage = 0; t = [];
cdatamapping = 'direct';

for i=1:length(ch),
    typ = get(ch(i),'type');
    if strcmp(typ,'image'),
        hasimage = 1;
        cdatamapping = get(ch(i), 'CDataMapping');
    elseif strcmp(typ,'surface') & ...
            strcmp(get(ch(i),'FaceColor'),'texturemap') % Texturemapped surf
        hasimage = 2;
        cdatamapping = get(ch(i), 'CDataMapping');
    elseif strcmp(typ,'patch') | strcmp(typ,'surface')
        cdatamapping = get(ch(i), 'CDataMapping');
    end
end

if ( strcmp(cdatamapping, 'scaled') )
  % Treat images and surfaces alike if cdatamapping == 'scaled'
  t = caxis(haxes);
  d = (t(2) - t(1))/size(colormap(haxes),1);
  t = [t(1)+d/2  t(2)-d/2];
else
    if hasimage,
        t = [1, size(colormap(haxes),1)]; 
    else
        t = [1.5  size(colormap(haxes),1)+.5];
    end
end

h = gcda(hfig,haxes);

if narg==0,
    % Search for existing colorbar
    ch = get(findall(hfig,'type','image','tag','TMW_COLORBAR'),{'parent'});
    ax = [];
    for i=1:length(ch),
        ud = get(ch{i},'userdata');
        d = ud.PlotHandle;
        if prod(size(d))==1 & isequal(d,h), 
            ax = ch{i}; 
            pos = get(ch{i},'Position');
            if pos(3)<pos(4)
                loc = 'vert';
            else
                loc = 'horiz';
            end
            changeNextPlot = 0;
            % Make sure image deletefcn doesn't trigger a colorbar('delete')
            % for colorbar update
            set(findall(ax,'type','image'),'deletefcn','')
            break; 
        end
    end
end

origNextPlot = get(hfig,'NextPlot');
if strcmp(origNextPlot,'replacechildren') | strcmp(origNextPlot,'replace'),
    set(hfig,'NextPlot','add')
end

if loc(1)=='v', % Append vertical scale to right of current plot
    
    if isempty(ax),
        legend('RestoreSize',h); %restore axes to pre-legend size
        units = get(h,'units');
        set(h,'units','normalized');
        pos = get(h,'Position'); 
        [az,el] = view(haxes);
        stripe = 0.075; edge = 0.02; 
        if all([az,el]==[0 90])
            space = 0.05;
        else
            space = .1;
        end
        set(h,'Position',[pos(1) pos(2) pos(3)*(1-stripe-edge-space) pos(4)]);
        legend('RecordSize',h); %set this as the new legend fullsize

        rect = [pos(1)+(1-stripe-edge)*pos(3) pos(2) stripe*pos(3) pos(4)];
        ud.origPos = pos;
        
        % Create axes for stripe and
        % create DeleteProxy object (an invisible text object in
        % the target axes) so that the colorbar will be deleted
        % properly.
        ud.DeleteProxy = text('parent',h,...
            'visible','off',...
            'tag','ColorbarDeleteProxy',...
            'HandleVisibility','off',...
            'deletefcn','colorbar(''delete'',''peer'',get(gcbf,''currentaxes''))');
 
        axH = graph3d.colorbar('parent',hfig);
        set(axH,'position',rect,'Orientation','vert');
        ax = double(axH);

        setappdata(ax,'NonDataObject',[]); % For DATACHILDREN.M
        set(ud.DeleteProxy,'userdata',ax)
        set(h,'units',units)
    else
        axes(ax);
        axH=[];
        ud = get(ax,'userdata');
    end
    
    % Create color stripe
    n = size(colormap(haxes),1);
    img = image([0 1],t,(1:n)',...
        'Parent',ax,...
        'Tag','TMW_COLORBAR',...
        'deletefcn','colorbar(''delete'',''peer'',get(gcbf,''currentaxes''))',...
        'SelectionHighlight','off',...
        'HitTest','off');

    %set up axes delete function
    set(ax,...
        'Ydir','normal',...
        'YAxisLocation','right',...
        'xtick',[],...
        'deletefcn','colorbar(''delete'',''peer'',get(gcbf,''currentaxes''))');
    
elseif loc(1)=='h', % Append horizontal scale to top of current plot
    
    if isempty(ax),
        legend('RestoreSize',h); %restore axes to pre-legend size
        units = get(h,'units'); set(h,'units','normalized')
        pos = get(h,'Position');
        stripe = 0.075; space = 0.1;
        set(h,'Position',...
            [pos(1) pos(2)+(stripe+space)*pos(4) pos(3) (1-stripe-space)*pos(4)])
        legend('RecordSize',h); %set this as the new legend fullsize
        rect = [pos(1) pos(2) pos(3) stripe*pos(4)];
        ud.origPos = pos;

        % Create axes for stripe and
        % create DeleteProxy object (an invisible text object in
        % the target axes) so that the colorbar will be deleted
        % properly.
        ud.DeleteProxy = text('parent',h,...
            'visible','off',...
            'tag','ColorbarDeleteProxy',...
            'handlevisibility','off',...
            'deletefcn','colorbar(''delete'',''peer'',get(gcbf,''currentaxes''))');

        axH = graph3d.colorbar('parent',hfig);
        set(axH,'Orientation','horiz');
        set(axH,'position',rect);
        ax = double(axH);
        
        setappdata(ax,'NonDataObject',[]); % For DATACHILDREN.M
        set(ud.DeleteProxy,'userdata',ax)
        set(h,'units',units)
    else
        axes(ax);
        axH=[];
        ud = get(ax,'userdata');
    end
    
    % Create color stripe
    n = size(colormap(haxes),1);
    img=image(t,[0 1],(1:n),...
        'Parent',ax,...
        'Tag','TMW_COLORBAR',...
        'deletefcn','colorbar(''delete'',''peer'',get(gcbf,''currentaxes''))',...
        'SelectionHighlight','off',...
        'HitTest','off');

    % set up axes deletefcn
    set(ax,...
        'Ydir','normal',...
        'Ytick',[],...
        'deletefcn','colorbar(''delete'',''peer'',get(gcbf,''currentaxes''))')
    
else
  error('COLORBAR expects a handle, ''vert'', or ''horiz'' as input.')
end

if ~isfield(ud,'DeleteProxy')
    ud.DeleteProxy = [];
end

if ~isfield(ud,'origPos')
    ud.origPos = [];
end

ud.PlotHandle = h;
set(ax,'userdata',ud)
set(hfig,'NextPlot',origNextPlot)

axes(h)

legH=legend(h);
if ~isempty(legH) & ishandle(legH)
    legend(legH) % Update legend
end

%make sure annotation layer ends up on top.
plotedit(get(ax,'parent'),'promoteoverlay');

if nargout>0
    handle = ax;
end

%--------------------------------
function h = gcda(hfig, haxes)
%GCDA Get current data axes

h = datachildren(hfig);
if isempty(h) | any(h == haxes)
  h = haxes;
else
  h = h(1);
end

