function [h,colors] = mybarcon(ax,x,y,varargin)
% MYBARCON  [Not a public function] Contribution bar graph .
%
% Backend IRIS function.
% No help provided.

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

if isempty(x) || isempty(y)
    h = [];
    colors = [];
    return
end

opt = passvalopt('tseries.barcon',varargin{:});

if isempty(opt.colormap)
    opt.colormap = get(gcf(),'colorMap');
end

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

[nper,ndata] = size(y);
nc = size(opt.colormap,1);

% Make sure we never run short of colors.
while ndata > nc
    opt.colormap = [opt.colormap;opt.colormap];
    nc = size(opt.colormap,1);
end
if opt.evenlyspread
    % Colors are evenly spread across the color map.
    colorindex = 1 + round(0 : (nc-1)/(ndata-1) : nc-1);
else
    % Colors are taken in order of appearance in the color map.
    colorindex = 1 : ndata;
end
colors = opt.colormap(colorindex,:);    

% Remember the `nextPlot` status.
nextplot = get(ax,'nextPlot');

% Width of bars.
if length(x) > 1
    avgxstep = mean(diff(x));
else
    avgxstep = 1;
end
d = avgxstep*opt.barwidth/2;

h = nan(nper,ndata);
yy = nan(4,nper,ndata);
xx = nan(4,nper);

if isnumeric(opt.ordering)
    opt.ordering = opt.ordering(:).';
elseif strcmpi(opt.ordering,'preserve')
    opt.ordering = 1 : ndata;
end

for i = 1 : nper
    if all(isnan(y(i,:)))
        continue
    end
    if isnumeric(opt.ordering)
        % User-spec ordering of same-sign contributions.
        sortindex = opt.ordering;
        ysort = y(i,sortindex);
        isnegative = ysort < 0;
        ysort = [ ...
            sum(ysort(isnegative)); ...
            -fliplr(ysort(isnegative)).'; ...
            ysort(~isnegative).'; ...
        ];
        sortindex = ...
            [fliplr(sortindex(isnegative)),sortindex(~isnegative)];
    elseif ischar(opt.ordering)
        % Use `sort` with 'ascend' or 'descend'.
        [ysort,sortindex] = sort(y(i,:),2,opt.ordering);
        isnegative = ysort < 0;
        ysort = [ ...
            sum(ysort(isnegative)); ...
            -ysort(isnegative).'; ...
            ysort(~isnegative).'; ...
        ];
        sortindex = [sortindex(isnegative),sortindex(~isnegative)];
    end
    cysort = cumsum(ysort,1);
    % Stow y-coordinates for each series and all periods so that we can
    % run `fill` on all periods at once.
    for j = 1 : ndata
        pos = find(sortindex == j);
        yy(:,i,j) = cysort([pos,pos,pos+1,pos+1],1);
    end
    xx(:,i) = x(i)+[-1;1;1;-1]*d;
end

% Plot bars for one series and all periods at once.
for j = 1 : ndata
    if j == 2
        set(ax,'nextPlot','add');
    end
    h(:,j) = fill(xx,yy(:,:,j),colors(j,:));
end

% Make all bar clusters invisible except the first one.
grfun.excludefromlegend(h(2:end,:));

% Reset `nextPlot` to its original status.
set(ax,'nextPlot',nextplot);

end