## Copyright (C) 2013 Adam H Aitkenhead
##
## This file is part of Octave.
##
## Octave is free software; you can redistribute it and/or modify it
## under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or (at
## your option) any later version.
##
## Octave is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Octave; see the file COPYING.  If not, see
## <http://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn  {Function File} {[@var{mapnew}] =} rgbmap (@var{n}, @var{rlim}, @var{glim}, @var{blim})
## Generate an rgb colormap.
##
## @var{n} is the maximum number of rows in the output colormap. @var{rlim}, @var{glim} and @var{blim}
## define the minimum and maximum of the range of values in each of the RGB color channels.
##
## @seealso{rgb2ind}
## @end deftypefn

## Author: Adam H Aitkenhead <adamhaitkenhead@gmail.com>
## Created: May 2013

function [mapnew] = rgbmap (n, rlim, glim, blim)

  if (n<8)
    error ("rgbmap: n must be >= 8");
  endif

  ## Compute the number of points in each color channel
  diffrgb = diff([rlim; glim; blim]');
  nrgb = floor (n^(1/3)+eps) * ones (1,3);

  ## Check if the number of points in any color channel can be increased
  ## without exceeding the maximum number of colors in the colormap
  if nrgb(1)*(nrgb(2)+1)*(nrgb(3)+1)<=n
    Imin = find (diffrgb == min (diffrgb), 1, 'first');
    nrgb = nrgb + 1;
    nrgb(Imin) = nrgb(Imin) - 1;
  elseif nrgb(1)*nrgb(2)*(nrgb(3)+1)<=n
    Imax = find (diffrgb == max (diffrgb), 1, 'first');
    nrgb(Imax) = nrgb(Imax) + 1;
  endif

  ## Generate the values in each colour channel
  steprgb = diffrgb./nrgb;
  r = rlim(1)+steprgb(1)/2 : steprgb(1) : rlim(2)-steprgb(1)/2;
  g = glim(1)+steprgb(2)/2 : steprgb(2) : glim(2)-steprgb(2)/2;
  b = blim(1)+steprgb(3)/2 : steprgb(3) : blim(2)-steprgb(3)/2;

  ## Generate the full colormap, taking all combinations of the rgb channels
  mapnew = zeros (prod (nrgb),3);
  loopi = 0;
  for loopr = 1:numel (r)
    for loopg = 1:numel (g)
      for loopb = 1:numel (b)
        loopi = loopi + 1;
        mapnew(loopi,:) = [r(loopr),g(loopg),b(loopb)];
      endfor
    endfor
  endfor

endfunction

