function cfg = aplotit2(data, config, varargin);
% cfg = aplotit2(data, config, varargin);
% plots data vs/ dday as a line or pcolor (w/ colorbar) in current axes.
% if just one argument, it assumes abcissa, ordinate, and field are x,y,z.
% optional: 'config' holds plotting nformation, varargin will override
% (see aplotit.m for original and complete specifications)
%% ==========================================================================
% In this context, structures "data" & "config" comes from gpanel.m:
%
% ---------- structure "data" (incomplete- see gpanel):          
% dday         %1xN or Nx1                                                   
% depth        %NBINSxNPRFS                                                  
% [fieldname]  %pg, sw, amp, u_meas, (see below for a detailed list)
%
% ---------- structure "config":
% fn           % plot this field name  (defaults to '')                   
% yearbase     % should have been in config structure used in agetmat
% cur_ax       % handle to figure axes (defaults to new axes in gca)
% reverse_ydir % reverse  direction of ordinate                             
%              %       (defaults to 1 for bins or depth); otherwise 0
% xlim         % limits of abcissa 
% cmap         % colormap to match var_range (sets the number of colors)     
%              %      defaults to jet(20)
% flagged     Boolean (0 == ignore flags)
% lcolor       % color of text label                   

% ANNOYING FACT: latest cmap will override all cmaps
% can get around this using 'direct' colormaps instead of 'scaled'
% surface(x,y,scaled_z,cmap_for_scaled_z,...
%      'CDataMapping, 'direct',...
%      'edgecolor','none');

program_name = 'aplotit2';    %this program; for 'help'

if (nargin < 1)
  help(program_name)
end

if (nargin == 1)                 %the most basic tool. autoscale everything
   config.abc_name = 'x';        %
   config.ord_name = 'y';         
   config.fn       = 'z';        
   
   if (~isstruct(data))          %ok, well, bomb out if it isn't a structure
      help(program_name)
      error('first argument must be a structure')
   end

end

%===== set up the data: make sure config is up-to-date, but don't use 
%      anything yet.

if (~isfield(config, 'cur_ax')),           config.cur_ax = [];       end
if (~isfield(config, 'xlim')),             config.xlim = [];         end
if (~isfield(config, 'ylim')),             config.ylim = [];         end
if (~isfield(config, 'var_range')),        config.var_range = [];    end
if (~isfield(config, 'fn')),               config.fn = 'pg';         end
if (~isfield(config, 'flagged')),          config.flagged = 0;       end
if (~isfield(config, 'lcolor')),           config.lcolor = 'k';      end
if (~isfield(config, 'comment')),          config.comment = '';      end
if (~isfield(config, 'comment2')),         config.comment2 = '';     end
if (~isfield(config, 'abc_name')),         config.abc_name = 'dday'; end  
if (~isfield(config, 'ord_name')),         config.ord_name = 'bins'; end
if (~isfield(config, 'markbinrange')),     config.markbinrange = []; end
if (~isfield(config, 'markcolor')),        config.markcolor = 'k';   end
if (~isfield(config, 'panelcolors')),        config.panelcolors = 1;   end
if (~isfield(config, 'markindex')),        config.markindex = [];    end
if (~isfield(config, 'cmap')),             config.cmap = [];         end
if (~isfield(config, 'astitle')),          config.astitle = 0;       end
if (~isfield(config, 'yearbase')),         config.yearbase = -9999;  end

%  <----- (config comes in)    ....  ----> cfg goes out
%  set defaults and finalize config values
%        i.e. defaults from (1) agetmat, (2) config (3) arg list

if (nargin > 2)%   we'll assume the rest is a set of name,value pairs
   %override input structure with name,value pairs
   cfg = fillstruct(config, varargin);
   cfg.box_ax = cfg.cur_ax;  %better make them match.
else
   cfg = config;
end

%now we have the correctly updated field 
%get the data and then set the clipping
if (~isfield(data, cfg.fn))     
   warning(sprintf('%s: field %s does not exist\n', program_name, cfg.fn))
   return
else
   fieldname  = cfg.fn;               %contour this name
   field      = getfield(data, fieldname);
   cfg.var_range =  getclips(field, fieldname, cfg);
end


if (isempty(field))   %cfg will return unchanged
   warning(sprintf('%s: field %s is empty\n', program_name, cfg.fn))
%   return
end

%get abscissa  ------------------------------
abscissa = getfield(data, getfield(cfg, 'abc_name'));
abscissa_title = '';
if (~isfield(cfg, 'abscissa_title'))  %no title yet
   if (isfield(cfg, 'title'))
      if (isfield(cfg.title, 'abc_name')) %there is a default title
         abscissa_title = getfield(cfg.title, 'abc_name');
      end
   end
end

if (length(abscissa) ~= length(abscissa(:))) %then it is not MxN
  abscissa = abscissa(1,:);                  %assume it is shaped like depth
end

% get abscissa indices
if (isfield(cfg,'index'))
   if (isempty(cfg.index)) 
      abci = 1:length(abscissa);     % use all indices      
   elseif (length(cfg.index) == 1)     % subsample by this number
      abci = [1:cfg.index:length(abscissa)];
   elseif (length(cfg.index) == 2)     %it's a range
      abci = find (...
              (cfg.index(1) <= abscissa) & ...
              (cfg.index(2) >= abscissa) );
   else                                      %it's already set of indices
      abci = cfg.index;
   end
else %there isn't one: same as empty
   abci = 1:length(abscissa); %
end
cfg.index = abci;

% get ordinate ------------------------------
ordinate = getfield(data, getfield(cfg, 'ord_name'));
ordinate_title = '';
if (~isfield(cfg, 'ordinate_title'))  %no title yet
  if (isfield(cfg, 'title'))
    if (isfield(cfg.title, 'ord_name')) %there is a default title
      ordinate_title = getfield(cfg.title, 'ord_name');
    end
  end
end

if (length(ordinate) ~= length(ordinate(:))) %then it is not MxN
  ordinate = ordinate(:,1);                  %assume it is shaped like depth
end

if (~isfield(cfg, 'reverse_ydir') | ...
    (strcmp(cfg.ord_name, 'z')) | ...
    (strcmp(cfg.ord_name, 'bins')) | ...
    (strcmp(cfg.ord_name, 'depth')))
  cfg.reverse_ydir = 1;
else
  cfg.reverse_ydir = 0;
end

% get the bin range for vertical marks
if isempty(cfg.markbinrange)
   cfg.markbinrange = [ floor(.7*length(ordinate)) ceil(.8*length(ordinate))];
end

%set the title ------------------------------
titlestr = '';
if (isfield(cfg, 'title'))
  if (isfield(cfg.title, fieldname))
    titlestr   =  getfield(cfg.title,fieldname);
  end
end

if (isempty(cfg.comment)),  cfg.comment = '';  end
if (isempty(cfg.comment2)), cfg.comment2 = '';  end

numcomments =  2 - sum( [strcmp(cfg.comment, '') strcmp(cfg.comment2, '')]);
if (numcomments == 0)
  comment = '';
elseif (numcomments  == 1  )
   comment = sprintf(' (%s%s)', cfg.comment, cfg.comment2);
else %numcomments = 2
   comment = sprintf(' (%s,%s)', cfg.comment, cfg.comment2);
end
titlestr = [titlestr,comment]; 

% axis  ------------------------------
if (isempty(cfg.xlim)) % doesn't happen
   cfg.xlim = [min(abscissa(cfg.index))  max(abscissa(cfg.index))];
end

if (isempty(cfg.ylim)) % always happens
   cfg.ylim =  [min(ordinate(:)) max(ordinate(:))];
end

%set the axes ------------------------------
if (isempty(cfg.cur_ax))
  figure(gcf);
  clf
  cfg.cur_ax = axes;
end

fprintf('about to plot %s\n',fieldname')

if isempty(abscissa) | isempty(field), 
   set(cfg.cur_ax,'visible', 'off'); 
   cfg.cbar_ax = [];
   return
end;

% set up plotting ==================================================

% it's a line: do a line plot
if (length(field) == length(field(:))) 
   h=plot(abscissa(cfg.index),field(cfg.index),'k');
   set(h,'linewidth',.1)
   %here abscissa = field
   if cfg.astitle
      title(titlestr)
   else
      h=text( cfg.xlim(1) + .05*diff(cfg.xlim),...    
              cfg.ylim(1) + .05*diff(cfg.ylim),titlestr);
      set(h,'fontweight','bold','fontsize',10)
      axis([cfg.xlim cfg.ylim])
   end
   xlabel(abscissa_title)
   %return control to original axes
   return  %get out if it is just a line plot 
end

%----------------------------------------------------------------------
%...  only going past here if it's a color plot
axes(cfg.cur_ax);
%abscissa = abscissa(cfg.index);
abscissa = [abscissa; 2*abscissa(end) - abscissa(end-1)];
ordinate = [ordinate, 2*ordinate(end) - ordinate(end-1)]; 
field = [field, ones(size(field,1),1)];
field = [field; ones(1, size(field,2))];
pcolor(abscissa, ordinate, field);%pcolor(abscissa, ordinate, field(:,cfg.index).*okmask(:,cfg.index))
shading flat
hold on
   
set(cfg.cur_ax,'box','off', 'XLimMode', 'manual', 'XTickLabelMode', 'manual')
set(cfg.cur_ax, 'TickDir', 'out', 'TickLength', [0.01 0.01])
abticknos = cfg.xlim(1):(cfg.xlim(2)-cfg.xlim(1))/10:cfg.xlim(2);
xticklbls = num2cell(abticknos);
set(cfg.cur_ax, 'XTick', abticknos, 'XTickLabel', xticklbls);
caxis(cfg.var_range) 
set(cfg.cur_ax,'xlim', cfg.xlim);
set(cfg.cur_ax,'ylim', cfg.ylim);
if (cfg.reverse_ydir) 
  set(cfg.cur_ax,'ydir', 'reverse')
end

if cfg.astitle
   title(titlestr)
else
   h=text( cfg.xlim(1) + .05*diff(cfg.xlim),...    
           cfg.ylim(end) - .05*diff(cfg.ylim),titlestr,...
           'fontweight','bold','fontsize',10,'color', cfg.lcolor);
end
axis([cfg.xlim cfg.ylim])
xlabel(abscissa_title)
ylabel(ordinate_title)
if ( (strcmp(lower(cfg.abc_name), 'lon')  | ...
      strcmp(lower(cfg.abc_name), 'lat') ))
  lltick(cfg.cur_ax, 'x', lower(cfg.abc_name))
end
if ( (strcmp(lower(cfg.ord_name), 'lon')  | ...
      strcmp(lower(cfg.ord_name), 'lat') ))
  lltick(cfg.cur_ax, 'y', lower(cfg.abc_name))
end

if (strcmp(lower(cfg.abc_name), 'heading')) 
  lltick(cfg.cur_ax, 'x', 'none');
end
if (strcmp(lower(cfg.ord_name), 'heading')) 
  lltick(cfg.cur_ax, 'y', 'none');
end

%set up the colors
% Ticks on colorbar every 10 or 20 units:
l10r = log10(diff(cfg.var_range)); l10int = floor(l10r); l10m = mod(l10r, 1);
if l10m > log10(5), ttt = 10;
elseif l10m > log10(2), ttt = 5;
else ttt = 2;
end
tl = ttt * 10^(l10int-1);
colorticks = (tl*ceil(cfg.var_range(1)/tl)) : tl : ...
    (tl*floor(cfg.var_range(2)/tl));

%set up colorbar.  color is for base of that range
if (isempty(cfg.cmap))
  numcolors = 21;
  if config.panelcolors,
     cfg.cmap = brighten(jet(numcolors), .5);
  else
     cfg.cmap = brighten(gray(numcolors), .5);
  end
else
  numcolors = length(cfg.cmap(:,1));
end
delta = diff(cfg.var_range)/(numcolors - 2); 
clev = min(cfg.var_range) : delta :  max(cfg.var_range) + delta;

irange =  [1 numcolors]; % indices into topo_cmap
colormap(cfg.cmap)

h_dcb = dcolbar(clev, 'vert', ' ');
h_dcbp = findobj(h_dcb,'Type','patch');
cf_index(h_dcbp, clev, irange);
set(h_dcb, 'XTick', [], 'YTick', colorticks);
set(h_dcb, 'YTicklabel', num2cell(colorticks));
set(h_dcb, 'TickDir', 'out', 'TickLength', [0.02 0.02])
set(h_dcb, 'yaxislocation','right')

%now put a box on the outside again
cfg.box_ax = axes('pos',get(cfg.cur_ax,'pos'),'color','none','box','on',...
     'xtick',[],'ytick',[]);
cfg.cbar_ax = h_dcb;

%======================================================================
function [var_range] = getclips(field, fieldname, config);

% get the specified clipping and plot ranges
%first try the data
var_range = [ min(field(:)) max(field(:))];
%now if exists in defaults, override
if (isfield(config, 'minclipval'))
  if (isfield(config.minclipval, fieldname))
    var_range(1) = getfield(config.minclipval, fieldname);
  end
end

if (isfield(config, 'maxclipval'))
  if (isfield(config.maxclipval, fieldname))
    var_range(2) = getfield(config.maxclipval, fieldname);
  end
end

%now test config (maybe it was overridden here?)
if (~isempty(config.var_range))
      var_range = getfield(config, 'var_range');
end
%================== eof