function [cmap,range] = monoColormap( range, hues, steps )
%[cmap,range] = monoColormap( range, hues )
%   Create a monochromatic colour map.  Hues can be a single colour or a
%   pair of colors.  The colors can be specified either as single-letter
%   names: b, w, r, g, b, c, m, y, o; or as hues (single values in the
%   range 0..1); or as rgb colours (a 1*3 or 2*3 matrix).

    if nargin < 3
        steps = 100;
    end
    range = extendToZero( range );
    if range(1)==range(2)
        cmap = [1 1 1
                1 1 1];
        return;
    end
    if ischar(hues)
        colors = namedColor(hues);
    elseif size(hues,2)==3
        colors = hues;
    else
        colors = hsv2rgb( [hues(:), ones(length(hues),2)] );
    end
    if size(colors,1) > 2
        colors = colors([1 2],:);
    end
    EXTENDEDRANGE = false;
    if (length(hues)==1) || (range(1) >= 0)
        color = colors(1,:);
        if EXTENDEDRANGE
            cmap = makeCmap( [ [1 1 1]; ...
                               (2/3)*[1 1 1] + (1/3)*color; ...
                               (1/3)*[1 1 1] + (2/3)*color; ...
                               color; ...
                               (2/3)*color ], ...
                             steps, 1 );
        else
            cmap = makeCmap( [ [1 1 1]; ...
                               (2/3)*[1 1 1] + (1/3)*color; ...
                               (1/3)*[1 1 1] + (2/3)*color; ...
                               color ], ...
                             steps, 1 );
        end
        range = [0 range(2)];
    elseif range(2) <= 0
        color = colors(2,:);
        if EXTENDEDRANGE
            cmap = makeCmap( [ (2/3)*color; ...
                               color; ...
                               (1/3)*[1 1 1] + (2/3)*color; ...
                               (2/3)*[1 1 1] + (1/3)*color; ...
                               [1 1 1] ], ...
                             steps, 1 );
        else
            cmap = makeCmap( [ color; ...
                               (1/3)*[1 1 1] + (2/3)*color; ...
                               (2/3)*[1 1 1] + (1/3)*color; ...
                               [1 1 1] ], ...
                             steps, 1 );
        end
        range = [range(1) 0];
    else
        % Zero is strictly included in the range.
        x = max(abs(range));
        negamount = -range(1)/x;
        posamount = range(2)/x;
        if false && (posamount==negamount)
            cmap = [ colors(2,:); [1 1 1]; colors(1,:) ];
        else
            if posamount >= negamount
                possteps = ceil(steps*posamount/(negamount + posamount));
                delta = posamount/possteps;
                negsteps = ceil(negamount/delta);
                negamount = negsteps*delta;
            else
                negsteps = ceil(steps*negamount/(negamount + posamount));
                delta = negamount/negsteps;
                possteps = ceil(posamount/delta);
                posamount = possteps*delta;
            end
            negratios = (negsteps:-1:1)'*(negamount/negsteps);
            negrgb = negratios*colors(2,:) + (1-negratios)*[1 1 1];
            posratios = (1:possteps)'*(posamount/possteps);
            posrgb = posratios*colors(1,:) + (1-posratios)*[1 1 1];
            cmap = [ negrgb; [1 1 1]; posrgb ];
        end
    end
end
