function varargout = coco_get_adjt_data(prob, fid, varargin)

% Copyright (C) Frank Schilder, Harry Dankowicz
% $Id: coco_get_adjt_data.m 2972 2017-01-10 19:44:34Z hdankowicz $

adjoint     = prob.adjoint;
varargout = {};
idx       = find(strcmpi(fid, ['adjoint' adjoint.identifyers]), 1)-1;
if isempty(idx)
  error('%s: could not find adjoint with identifyer ''%s''', mfilename, fid);
else
  if idx
    func = adjoint.funcs(idx);
    for oarg = 1:nargin-2
      switch lower(varargin{oarg})
        case 'data'  % adjoint data
          if isa(func.data, 'coco_func_data')
            varargout = [ varargout { func.data.protect() } ]; %#ok<VARARG,AGROW>
          else
            varargout = [ varargout { func.data } ]; %#ok<VARARG,AGROW>
          end
        case 'afidx' % position of l0 and tl0 in full adjoint solution vector
          varargout = [ varargout { func.af_idx(:) } ]; %#ok<VARARG,AGROW>
        case 'axidx' %
          varargout = [ varargout { func.ax_idx(:) } ]; %#ok<VARARG,AGROW>
        case 'fidx'  % position of F(x) in zero function
          varargout = [ varargout { func.f_idx(:) } ]; %#ok<VARARG,AGROW>
        case 'midx'  % position of F(x) in monitor function
          varargout = [ varargout { func.m_idx(:) } ]; %#ok<VARARG,AGROW>
        case {'x0' 'u0'}  % initial solution point of toolbox
          varargout = [ varargout { adjoint.l0(func.af_idx) } ]; %#ok<VARARG,AGROW>
        case 't0'    % initial tangent of toolbox
          varargout = [ varargout { adjoint.tl0(func.af_idx) } ]; %#ok<VARARG,AGROW>
        otherwise
          error('%s: unknown function data field ''%s''', ...
            mfilename, varargin{oarg});
      end
    end
  else
    for oarg = 1:nargin-2
      switch lower(varargin{oarg})
        case 'l0' % full adjoint solution vector constructed so far
          varargout = [ varargout { adjoint.l0 } ]; %#ok<VARARG,AGROW>
        case 'afidx' % indices of full solution vector constructed so far
          varargout = [ varargout { 1:numel(adjoint.l0) } ]; %#ok<VARARG,AGROW>
        case 'tl0' % full initial tangent vector constructed so far
          varargout = [ varargout { adjoint.tl0 } ]; %#ok<VARARG,AGROW>
        case 'fidx' % list of positions of functions added so far
          list = {};
          for i=1:numel(adjoint.funcs)
            func = adjoint.funcs(i);
            if ~isempty(func.af_idx)
              list = [ list ; { func.identifyer func.af_idx(:) } ]; %#ok<AGROW>
            end
          end
          varargout = [ varargout { list } ]; %#ok<VARARG,AGROW>
        case 'axidx' % indices of added columns of adjoint
          list = {};
          xidx = [];
          for i=1:numel(adjoint.funcs)
            func  = adjoint.funcs(i);
            axidx = setdiff(func.ax_idx, xidx);
            if ~isempty(axidx)
              list = [ list ; { func.identifyer axidx(:) } ]; %#ok<AGROW>
            end
            xidx  = union(xidx, axidx);
          end
          varargout = [ varargout { list } ]; %#ok<VARARG,AGROW>
        otherwise
          error('%s: unknown function data field ''%s''', ...
            mfilename, varargin{oarg});
      end
    end
  end
end
