function iT = c_index(T, trange, irange, clip)
%  function iT = c_index(T, trange, irange, clip)
%
%  Linearly maps floating point values onto indices;
%  this was developed to facilitate the use of indices
%  into segments of a colormap.  It uses the same
%  mapping algorithm as the direct mapping in pcolor,
%  for example, except that the clipping guarantees
%  that only colors in the irange section of the colormap
%  will be used.  Hence it gives much more control in the
%  use of multiple concatenated colormaps than Mathworks'
%  suggestion of using direct mapping and manipulating caxis
%  to select the desired chunk of a concatenated colormap.
%
%  T:          an array of values such as temperatures;
%              or a cell array, such as is returned by
%              get(h, 'CData'), where h is a vector of patch
%              handles.  If T is a cell array, then a cell
%              array is returned.
%  trange:     2-element vector, [tmin tmax],
%              min and max values to be mapped.
%              Or, it can be the vector of contour levels
%              used with contourf.  In this case, the mapping
%              is done to all contour levels, and any value
%              in T that is within those levels, but not on
%              a level, is rounded down to the nearest level.
%              This fixes a peculiarity in contourf, in which
%              the CData for the lowest contour takes the value
%              of the actual minimum data value, not the lower
%              contour level.
%  irange:     optional 2-element vector, [imin imax]
%              min and max indices to which T will be mapped.
%              default is [1 64].
%  clip:       optional 1 or 2-element vector giving index to which
%              values outside trange will be mapped; default is
%              clip = irange.  A typical alternative would be to
%              specify clip as NaN, so that any values outside
%              the range are not colored (and show up as black).
%
%  All values of T greater than or equal to tmin and less than tmax
%  get mapped onto indices between imin and imax; values of T
%  greater than or equal to tmax, or less than tmin, are dealt
%  with by clipping.
%
%  See also ind_cbar.m, which makes a corresponding colorbar;
%  and cf_index.m, which applies c_index to the output of contourf.
%

%  Eric Firing

%  2001/05/24 EF modified to work with CData for EdgeColor flat
%
if nargin < 2,
   error('Need at least 2 arguments');
end
if nargin < 3,
   irange = [1 64],
end
if nargin < 4,
   imax = irange(2);
   imin = irange(1);
else
   imin = clip(1);
   imax = clip(end);
end

Tt = [];

if iscell(T),
   cellflag = 1;
   for ii = 1:length(T(:)),
      Tt = [Tt; T{ii}(:)];
   end
else
   cellflag = 0;
   Tt = T(:);
end

if length(trange) > 2,
   for ii = 1:length(Tt)
      jj = find( trange <= Tt(ii) );
      if ~isempty(jj) & Tt(ii) < trange(end)
         Tt(ii) = trange(max(jj));
      end
   end
end

d_trange = trange(end)-trange(1);
iTt = irange(1) + floor( (1 + diff(irange))*(Tt - trange(1))/d_trange );


ii = find(iTt > irange(2));
iTt(ii) = imax;
ii = find(iTt < irange(1));
iTt(ii) = imin;

if cellflag == 1,
   iT = T;
   iii = 1;
   for ii = 1:length(T)
      n = length(T{ii});
      iT{ii} = iTt(iii:(iii+n-1));
      iii = iii + n;
   end
else
   iT = iTt;
end
