function [PT,CP] = highlight(varargin)
% highlight  Highlight specified range or date range in a graph.
%
% Syntax
% =======
%
%     [PT,CP] = highlight(RANGE,...)
%     [PT,CP] = highlight(AX,RANGE,...)
%
% Input arguments
% ================
%
% * `RANGE` [ numeric ] - X-axis range or date range that will be
% highlighted.
%
% * `AX` [ numeric ] - Handle(s) to axes object(s) in which the highlight
% will be made.
%
% Output arguments
% =================
%
% * `PT` [ numeric ] - Handle to the highlighted area (patch object).
%
% * `CP` [ numeric ] - Handle to the caption (text object).
%
% Options
% ========
%
% * `'caption='` [ char ] - Annotate the highlighted area with this text
% string.
%
% * `'color='` [ numeric | *[0.9,0.9,0.9]* ] - An RGB color code or a Matlab
% color name.
%
% * `'excludeFromLegend='` [ *`true`* | `false` ] - Exclude the highlighted area
% from legend.
%
% * `'hPosition='` [ 'center' | 'left' | *'right'* ] - Horizontal position
% of the caption.
%
% * `'vPosition='` [ 'bottom' | 'middle' | *'top'* | numeric ] - Vertical
% position of the caption.
%
% Description
% ============
%
% Example
% ========
%

% -IRIS Toolbox.
% -Copyright (c) 2007-2012 Jaromir Benes.

if all(ishghandle(varargin{1}))
    AX = varargin{1};
    varargin(1) = [];
else
    AX = gca();
end

range = varargin{1};
varargin(1) = [];

if iscell(range)
    PT = [];
    CP = [];
    for i = 1 : numel(range)
        [pt,cp] = highlight(AX,range{i},varargin{:});
        PT = [PT,pt(:).'];
        CP = [CP,cp(:).'];
    end
    return
end

options = passvalopt('grfun.highlight',varargin{:});

if ~isempty(options.color)
    options.colour = options.color;
end

if ~isempty(options.grade)
    options.colour = options.grade*[1,1,1];
end

%**************************************************************************

PT = [];
CP = [];

for ax = AX(:).'
    % Preserve the order of figure children.
    fg = get(ax,'parent');
    fgch = get(fg,'children');
    
    % Check if this axes handles has its plotyy peer. If so, find out which
    % one is the bottom layer, and plot the highlight area in that one.
    peer = getappdata(ax,'graphicsPlotyyPeer');
    if ~isempty(peer)
        siblings = get(get(ax,'parent'),'children');
        thispos = find(ax == siblings);
        peerpos = find(peer == siblings);
        if peerpos > thispos
            ax = peer; %#ok<FXSET>
        end
    end
    
    % Make axes sit on top of lines and patches so that grid is visible.
    set(ax,'layer','top');
    
    range = range([1,end]);
    if isequal(getappdata(ax,'tseries'),true)
        freq = datfreq(range(1));
        timescale = dat2grid(range);
        if isempty(timescale)
            continue
        end
        if freq > 0
            around = 1/(2*freq);
        else
            around = 0.5;
        end
        timescale = [timescale(1)-around,timescale(end)+around];
    else
        timescale = [range(1)-options.around,range(end)+options.around];
    end

    ylim = get(ax,'ylim');
    ydata = ylim([1,1,2,2]);
    xdata = timescale([1,2,2,1]);
    pt = patch(xdata,ydata,options.colour, ...
        'parent',ax,'edgeColor','none');

    % Add caption to the highlight.
    if ~isempty(options.caption)
        cp = caption_(ax,timescale([1,end]), ...
            options.caption,options.vposition,options.hposition);
        CP = [CP,cp];
    end

    % Move the highlight patch object to the background.
    ch = get(ax,'children');
    ch(ch == pt) = [];
    ch(end+1) = pt;
    set(ax,'children',ch);

    % Update y-data whenever the parent y-lims change.
    grfun.listener(ax,pt,'highlight');

    % Reset the order of figure children.
    set(fg,'children',fgch);
    PT = [PT,pt]; %#ok<*AGROW>

end

% Tag the highlights and captions for `qstyle`.
set(PT,'tag','highlight');
set(CP,'tag','highlight-caption');

if ~isempty(PT) && options.excludefromlegend
    % Exclude highlighted area from legend.
    grfun.excludefromlegend(PT);
end

end
