function [LN,CP] = vline(varargin)
% vline  Add vertical line with text caption at the specified position.
%
% Syntax
% =======
%
%     [LN,CP] = grfun.vline(AX,POSITION,...)
%     [LN,CP] = grfun.vline(POSITION,...)
%
% Input arguments
% ================
%
% * `AX` [ numeric ] - Handle to an axes object in which the vline will be
% placed.
%
% * `POSITION` [ numeric ] - Horizontal position on the x-axis at which the
% vline will be placed; in tseries graphs this is supposed to be a date.
%
% Output arguments
% =================
%
% * `LN` [ numeric ] - Handle to the vline(s) plotted (line objects).
%
% * `CP` [ numeric ] - Handle to the caption(s) created (text objects).
%
% Options
% ========
%
% * `'caption='` [ char ] - Annotate the vline with this text string.
%
% * `'excludeFromLegend='` [ *`true`* | `false` ] - Exclude the vline from
% legend.
%
% * `'hPosition='` [ `'center'` | `'left'` | *`'right'`* ] - Horizontal position
% of the caption.
%
% * `'vPosition='` [ `'bottom'` | `'middle'` | *`'top'`* | numeric ] - Vertical
% position of the caption.
%
% * `'timePosition='` [ `'after'` | `'before'` | `'middle'` ] - Placement of the
% vertical line on the time axis: in the middle of the specified period,
% immediately before it (between the specified period and the previous
% one), or immediately after it (between the specified period and the next
% one).
%
% Description
% ============
%
% Example
% ========
%

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

if ~isempty(varargin) ...
        && all(ishghandle(varargin{1})) ...
        && all(strcmp(get(varargin{1}(:),'type'),'axes'))
    AX = varargin{1};
    varargin(1) = [];
    nax = numel(AX);
    if nax > 1
        for i = 1 : nax
            grfun.vline(AX(i),varargin{:});
        end
        return
    end
else
    AX = gca();
end

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

% Parse options.
[options,varargin] = passvalopt('grfun.vline',varargin{:});

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

% If this is a time series graph, convert the vline position to a date grid
% point.
x = location;
if isequal(getappdata(AX,'tseries'),true)
    x = dat2grid(x);
    freq = getappdata(AX,'freq');
    if ~isempty(freq) && isnumericscalar(freq) ...
            && any(freq == [0,1,2,4,6,12])
        if freq > 0
            dx = 1/(2*freq);
        else
            dx = 0.5;
        end
        switch options.timeposition
            case 'before'
                x = x - dx;
            case 'after'
                x = x + dx;
        end
    end
end

yLim = get(AX,'yLim');
nextPlot = get(AX,'nextPlot');
set(AX,'nextPlot','add');

CP = [];
LN = [];
nlocation = numel(location);
for i = 1 : nlocation
    ln = plot(AX,x([i,i]),yLim,'color',[0,0,0]);
    ln = ln(:).';
    if ~isempty(varargin)
        set(ln,varargin{:});
    end
    
    ch = get(AX,'children');
    for j = ln
        % Update the vline y-data whenever the parent y-lims change.
        grfun.listener(AX,j,'vline');
        % Move the highlight patch object to the background.
        ch(ch == j) = [];
        ch(end+1) = j;
    end
    set(AX,'children',ch);

    LN = [LN,ln]; %#ok<*AGROW>

    % Add annotation.
    if ~isempty(options.caption)
        cp = caption_(AX,x(i), ...
            options.caption,options.vposition,options.hposition);
        CP = [CP,cp(:).'];
    end
end

% Tag the vlines and captions for `qstyle`.
set(LN,'tag','vline');
set(CP,'tag','vline-caption');

% Reset `'nextPlot='` to its original value.
set(AX,'nextPlot',nextPlot);

% Exclude the line object from legend.
if ~isempty(LN) && options.excludefromlegend
    grfun.excludefromlegend(LN);
end

end
