function cmap = vivid(varargin)

% VIVID: Creates a Personalized Vivid Colormap
%
% VIVID(M,...)       Creates a colormap with M colors
% VIVID(MINMAX,...)  Creates a colormap with a custom intensity range
% VIVID(CLRS,...)    Creates a colormap with custom colors
% CMAP = VIVID(...)  Exports the vivid colormap to a Mx3 matrix
%
% On Input:
%
%    M        An integer between 1 and 256 specifying the number
%             of colors in the colormap (OPTIONAL).
%             Default is 128.
%
%    MINMAX   A 1x2 vector with values between 0 and 1 representing the 
%             intensity range for the colors, which correspond to black
%             and white, respectively (OPTIONAL).
%             Default is [0.15 0.85].
%
%   CLRS      Either a Nx3 matrix of values between 0 and 1
%             representing the desired colors in the colormap
%         or
%             a string of characters that includes any combination of
%             thefollowing letters:
%
%               'r' = red           'g' = green         'b' = blue
%               'y' = yellow        'c' = cyan          'm' = magenta
%               'o' = orange        'l' = lime green    'a' = aquamarine
%               's' = sky blue      'v' = violet        'p' = pink
%               'n' = navy blue     'f' = forest green
%               'k' or 'w' = black/white/grayscale
%
% On Output:
%
%    CMAP     An Mx3 colormap matrix
%
% Examples:
%
%   * Default Colormap:
%  
%       imagesc(sort(rand(200),'descend'));
%       colormap(vivid); colorbar
%
%   * Mapping With 256 Colors
%
%       imagesc(peaks(500))
%       colormap(vivid(256)); colorbar
%
%   * Mapping With Full Intensity Range
%
%       mesh(peaks(500))
%       colormap(vivid([0 1])); colorbar
%
%   * Mapping With Light Colors
%
%       mesh(peaks(500))
%       colormap(vivid([.5 1])); colorbar
%
%   * Mapping With Dark Colors
%
%       mesh(peaks(500))
%       colormap(vivid([0 .5])); colorbar
%
%   * Mapping With Custom Color Matrix
%
%       imagesc(peaks(500))
%       clrs = [.5 0 1; 0 .5 1; 0 1 .5; .5 1 0; 1 .5 0; 1 0 .5;];
%       colormap(vivid(clrs)); colorbar
%
%   * Mapping With Color String
%
%       imagesc(peaks(500))
%       colormap(vivid('pmvbscaglyor')); colorbar
%
%   * Colormap With Multiple Custom Settings
%
%       imagesc(sort(rand(300,100),'descend'));
%       colormap(vivid(64,[.1 .9],'bwr')); colorbar
%
%   * Topo Colormap
%
%       load topo;
%       imagesc(topo); axis xy; caxis([-6000 6000])
%       colormap(vivid('bg')); colorbar
%
% See also: jet, hsv, gray, hot, cold, copper, bone, fireice
%
% Author: Joseph Kirk
% Email: jdkirk630@gmail.com
% Release: 1.1
% Date: 12/09/11


% Default Color Spectrum

clrs = [1 0 1;.5 0 1;0 0 1;0 1 1      % Magenta, Violet, Blue, Cyan
        0 1 0;1 1 0;1 .5 0;1 0 0];    % Green, Yellow, Orange, Red

% Default Min/Max Intensity Range

minmax = [0.15 0.85];

% Default Colormap Size

m = 256;

% Process Inputs

for var = varargin
    input = var{1};
    if ischar(input)
        nColors = length(input(:));
        colorMat = zeros(nColors,3);
        c = 0;
        for k = 1:nColors
            c = c + 1;
            switch lower(input(k))
                case 'r', colorMat(c,:) = [1 0 0];  % red
                case 'g', colorMat(c,:) = [0 1 0];  % green
                case 'b', colorMat(c,:) = [0 0 1];  % blue
                case 'y', colorMat(c,:) = [1 1 0];  % yellow
                case 'c', colorMat(c,:) = [0 1 1];  % cyan
                case 'm', colorMat(c,:) = [1 0 1];  % magenta
                case 'p', colorMat(c,:) = [1 0 .5]; % pink
                case 'o', colorMat(c,:) = [1 .5 0]; % orange
                case 'l', colorMat(c,:) = [.5 1 0]; % lime green
                case 'a', colorMat(c,:) = [0 1 .5]; % aquamarine
                case 's', colorMat(c,:) = [0 .5 1]; % sky blue
                case 'v', colorMat(c,:) = [.5 0 1]; % violet
                case 'f', colorMat(c,:) = [0 .5 0]; % forest green
                case 'n', colorMat(c,:) = [0 0 .5]; % navy
                case {'k','w'}, colorMat(c,:) = [.5 .5 .5]; % grayscale
                otherwise, c = c - 1;
                    fprintf('Warning: Input character [%s] is not a recognized color ...\n',input(k));
            end
        end
        colorMat = colorMat(1:c,:);
        if ~isempty(colorMat)
            clrs = colorMat;
        end
    elseif isnumeric(input)
        if isscalar(input)
            m = max(1,min(256,round(real(input))));
        elseif size(input,2) == 3
            clrs = max(0,min(1,real(input)));
        elseif length(input) == 2
            minmax = max(0,min(1,real(input)));
        end
    end
end

% Calculate Parameters

nc = size(clrs,1);  % number of spectrum colors
ns = ceil(m/nc);    % number of shades per color
n = nc*ns;
d = n - m;

% Scale Intensity

sup = 2*minmax;
sub = 2*minmax - 1;
if ns == 1
    high = repmat(min(1,mean(sup)),[1 nc 3]);
    low = repmat(max(0,mean(sub)),[1 nc 3]);
else
    high = repmat(min(1,linspace(sup(1),sup(2),ns))',[1 nc 3]);
    low = repmat(max(0,linspace(sub(1),sub(2),ns))',[1 nc 3]);
end

% Determine Color Spectrum

rgb = repmat(reshape(clrs,1,nc,3),ns,1);
map = rgb.*high + (1-rgb).*low;

% Obtain Color Map

cmap = reshape(map,n,3,1);
cmap(1:ns:d*ns,:) = [];

return
