function out1 = fnbrk(fn,part)
%FNBRK Name and part(s) of a form.
%
%   OUT1 = FNBRK(FN,PART)
%
%   returns the 'form' of the form contained in FN or any other
%   specified PART (thus obviating direct use of SPBRK, PPBRK, ... ).
%
%   If FN is in B-form (or BBform, or rBform), then the part returned is 
%   specified by the string PART which may be (the beginning character(s) of) 
%   one of the following strings: 
%
%      'knots' or 't', 'coefs', 'number', 'order', 'dim'ension, 'interval'
%
%   corresponding to the knot sequence, the B-spline coefficient array, the 
%   number of coefficients, the (polynomial) order, the dimension of the 
%   function's target, and the basic interval.
%
%   If FN is in ppform (or rpform), then the part returned is specified by the 
%   string PART which may be (the beginning character(s) of) one of the 
%   following strings: 
%
%      'breaks, 'coefs', 'pieces' or 'l', 'order', 'dim'ension, 'interval'
%
%   corresponding to the break sequence, the array of local polynomial
%   coefficients, the number of polynomial pieces, the (polynomial) order, the 
%   dimension of the function's target, and the basic interval.
%   In addition, if PART is the integer 
%
%      j
%
%   then the ppform of the j-th polynomial piece is returned. 
%   Also, for a while, there is for PART the choice
%
%      'guide'
%
%   that returns the coefficient array in the form required in the ppform used
%   in `A Practical Guide to Splines', especially for PPVALU there. This is not
%   available for vector-valued and/or tensor product splines.
%
%   Finally, for any form in FN, the command
%
%   FC = FNBRK(FN,[A B])
%
%   (with A and B scalars) returns, in the same form, the restriction/extension 
%   to the interval with endpoints A and B of the function described by FN. 
%
%   If FN contains an m-variate spline with m>1 and PART is not a string, then 
%   it must be a cell-array, of length m .
%
%   FNBRK(FN)
%
%   prints the 'form' along with all the parts if available.
% 
%   For example,
%
%      coefs = fnbrk( fn, 'coef' );
%
%   returns the coefficients (from its B-form or its ppform) of the spline
%   in fn.
%   As another example, if p1 and p2 contain the B-form of two splines of the 
%   same order, with the same knot sequence, and the same target dimension, then
%
%      p1plusp2 = spmak( fnbrk(p1,'k'), fnbrk(p1,'c')+fnbrk(p2,'c') );
%
%   provides the (pointwise) sum of those two functions.
%
%   If pp contains the ppform of a bivariate spline with at least 4 polynomial
%   pieces in the first variable, then 
%
%      ppp = fnbrk(pp,{4,[-1 1]});
%
%   gives the spline that agrees with the spline in pp on the rectangle 
%   [b4 .. b5] x [-1 .. 1] , where b4, b5 are the 4th and 5th point in the 
%   break sequence for the first variable.
%
%   See also SPMAK, PPMAK, RSMAK, RPMAK, SPBRK, PPBRK, RSBRK, RPBRK.

%   cb 26aug96 29aug96 22dec96 26jul97 8oct97, 17oct97, 15nov97, 23nov97,
%      22apr98, 31jul98, 09jan00, 22jan00, 29jan00, 23may00
%   Copyright 1987-2000 by C. de Boor and The MathWorks, Inc.
%   $Revision: 1.11 $

if ~isstruct(fn)    % this branch should eventually be abandoned
   switch fn(1)
   %
   % curves:
   %
      case 10, out1 = 'ppform, univariate, array format';
      case 11, out1 = 'B-form, univariate, array format';
      case 12, out1 = 'BBform, univariate, array format';
      case 15, out1 = 'polynomial in Newton form';
   %
   % surfaces:
   %
      case 20, out1 = 'ppform, bivariate tensor product, array format';
      case 21, out1 = 'B-form, bivariate tensor product, array format';
      case 22, out1 = 'BBform, bivariate, array format';
      case 24, out1 = 'polynomial in shifted power form, bivariate';
   %
   % matrices:
   %
      case 40, out1 = 'almost block diagonal form';
      case 41, out1 = 'spline version of almost block diagonal form';
   % 42 = 'factorization of spline version of almost block diagonal form'
   %      (not yet implemented)
   
   %
   % multivariate:
   %
      case 94, out1 = 'polynomial in shifted normalized power form, multivariate';
      otherwise
         error('Input is of unknown (function) form.')
   end
   
   if nargin>1
      if isstr(part)&part(1)=='f'
      else
         switch fn(1)
         case 10, out1 = ppbrk(fn,part);
         case {11,12}, out1 = spbrk(fn,part);
         otherwise
         error(['Parts for ',out1,' are not (yet) available.'])
         end
      end
      return
   else
      if nargout>0
         error('You need to specify a part to be returned.')
      else
         fprintf(['The input describes a ',out1,'\n\n'])
         clear out1
         switch fn(1)
         case 10, ppbrk(fn);
         case {11,12}, spbrk(fn);
         otherwise
         fprintf(['Its parts are not (yet) available.\n'])
         end
      end
      return
   end
else
   switch fn.form
      case 'pp', out1 = 'ppform';
      case 'B-', out1 = 'B-form';
      case 'BB', out1 = 'BBform';
      case 'rB', out1 = 'rBform';
      case 'rp', out1 = 'rpform';
   %   case 15, out1 = 'polynomial in Newton form';
      otherwise
         error('Input is of unknown (function) form.')
   end
   
   if nargin>1
      if isstr(part)&part(1)=='f'
      else
         switch fn.form
         case 'pp', out1 = ppbrk(fn,part);
         case {'B-','BB'}, out1 = spbrk(fn,part);
         case 'rB', out1 = rsbrk(fn,part);
         case 'rp', out1 = rpbrk(fn,part);
         otherwise
         error(['Parts for ',out1,' are not (yet) available.'])
         end
      end
      return
   else
      if nargout>0
         error('You need to specify a part to be returned.')
      else
         fprintf(['The input describes a ',out1,'\n\n'])
         clear out1
         switch fn.form
         case 'pp', ppbrk(fn);
         case {'B-','BB'}, spbrk(fn);
         case 'rB', rsbrk(fn);
         case 'rp', rpbrk(fn);
         otherwise
         fprintf(['Its parts are not (yet) available.\n'])
         end
      end
      return
   end
end
