classdef table < report.tabularobj
    % table  Start new table in report.
    %
    % Syntax
    % =======
    %
    %     P.table(CAP,...)
    %
    % Input arguments
    % ================
    %
    % * `P` [ report ] - Report object created by the
    % [`report.new`](report/new) function.
    %
    % * `CAP` [ char | cellstr ] - Title and subtitle displayed at the top
    % of the table.
    %
    % Options
    % ========
    %
    % * `'arrayStretch='` [ numeric | *`1.15`* ] - (Inheritable from parent
    % objects) Stretch between lines in the table (in pts).
    %
    % * `'captionTypeface='` [ cell | *`'\large\bfseries'`* ] - LaTeX format
    % commands for typesetting the table caption and subcaption; you can use
    % Inf for either to indicate the default format.
    %
    % * `'colStruct='` [ struct | *empty* ] - (Not inheritable from parent
    % objects) User-defined structure of the table columns; use of this option
    % disables `'range='`.
    %
    % * `'colWidth='` [ numeric | *`NaN`* ] - (Inheritable from parent objects)
    % Width of table columns in em units; if NaN the width of each column will
    % adjust automatically.
    %
    % * `'headlineJustify='` [ *`'c'`* | `'l'` | `'r'` ] - Horizontal alignment
    % of the headline entries (individual dates or user-defined text): Centre,
    % Left, Right.
    %
    % * `'dateFormat='` [ char | cellstr | *`irisget('dateformat')`* ] -
    % (Inheritable from parent objects) Format string for the date row.
    %
    % * `'footnote='` [ char | *empty* ] - Footnote at the table title; only
    % shows if the title is non-empty.
    %
    % * `'long='` [ true | *`false`* ] - (Inheritable from parent objects) If
    % true, the table may stretch over more than one page.
    %
    % * `'longFoot='` [ char | *empty* ] - (Inheritable from parent objects)
    % Works only with `'long='`=true: Footnote that appears at the bottom of
    % the table (if it is longer than one page) on each page except the last
    % one.
    %
    % * `'longFootPosition='` [ `'centre'` | *`'left'`* | `'right'` ] -
    % (Inheritable from parent objects) Works only with `'long='` `true`:
    % Horizontal alignment of the footnote in long tables.
    %
    % * `'range='` [ numeric | *empty* ] - (Inheritable from parent objects)
    % Date range or vector of dates that will appear as columns of the table.
    %
    % * `'separator='` [ char | *`'\medskip\par'`* ] - (Inheritable from parent
    % objects) \LaTeX\ commands that will be inserted after the table.
    %
    % * `'sideways='` [ `true` | *`false`* ] - (Inheritable from parent objects)
    % Print the table rotated by 90 degrees.
    %
    % * `'tabcolsep='` [ `NaN` | numeric ] - (Inheritable from parent objects)
    % Space between columns in the table, measured in em units; NaN means the
    % \LaTeX\ default.
    %
    % * `'typeface='` [ char | *empty* ] - (Not inheritable from parent objects)
    % \LaTeX\ code specifying the typeface for the table as a whole; it must use
    % the declarative forms (such as `\itshape`) and not the command forms
    % (such as `\textit{...}`).
    %
    % * `'vline='` [ numeric | *empty* ] - (Inheritable from parent objects)
    % Vector of dates after which a vertical line (divider) will be placed.
    %
    % Generic options
    % ================
    %
    % See help on [generic options](report/Contents) in report objects.
    %
    % Description
    % ============
    %
    % Tables are top-level report objects and cannot be nested within other
    % report objects, except [`align`](report/align). Table objects can have
    % the following children:
    %
    % * [`series`](report/series);
    % * [`subheading`](report/subheading).
    %
    % By default, the date row is printed as a leading row with dates formated
    % using the option `'dateFormat='`. Alternatively, you can specify this
    % option as a cell array of two strings. In that case, the dates will be
    % printed in two rows. The first row will have a date string displayed and
    % centred for every year, and the first cell of the `'dateFormat='` option
    % will be used for formatting. The second row will have a date displayed
    % for every period (i.e. every column), and the second cell of the
    % `'dateFormat='` option will be used for formatting.
    %
    % User-defined structure of the table columns
    % --------------------------------------------
    %
    % Use can use the `'columnStruct='` option to define your own table columns.
    % This gives you more flexibility than when using the `'range='` option in
    % defining the content of the table.
    %
    % The option `'columnStruct='` must be a 1-by-N struct, where N is the
    % number of columns you want in the table, with the following fields:
    %
    % * `'name='` - specifies the descriptor of the column that will be
    % displayed in the headline;
    %
    % * `'func='` - specifies a function that will be applied to the input
    % series; if `'func='` is empty, no function will be applied. The function
    % must evaluate to a tseries or a numeric scalar.
    %
    % * `'date='` - specifies the date at which a number will be taken from the
    % series unless the function `'func='` applied before resulted in a numeric
    % scalar.
    %
    % Example
    % ========
    %
    % Compare the headers of these two tables:
    %
    %     x = report.new();
    %
    %     x.table('First table', ...
    %         'range',qq(2010,1):qq(2012,4), ...
    %         'dateformat','YYYYFP');
    %     % You can add series or subheadings here.
    %
    %     x.table('Second table', ...
    %         'range,qq(2010,1):qq(2012,4), ...
    %         'dateformat',{'YYYY','FP'});
    %     % You can add series or subheadings here.
    %
    %     x.publish('myreport.pdf');
    %
    
    % -IRIS Toolbox.
    % -Copyright (c) 2007-2012 Jaromir Benes.
    
    properties (Dependent)
        range
    end
    
    methods
        
        function THIS = table(varargin)
            THIS = THIS@report.tabularobj(varargin{:});
            THIS.childof = {'report','align'};
            THIS.default = [THIS.default,{ ...
                'columnstruct',[],@(x) isempty(x) || report.genericobj.validatecolstruct(x),false, ...
                'colstruct',struct([]),@(x) isempty(x) || report.genericobj.validatecolstruct(x),false, ...
                'datejustify',[],@(x) isempty(x) || (ischar(x) && any(strncmpi(x,{'c','l','r'},1))),true, ...
                'dateformat',irisget('dateformat'),@(x) ischar(x) || iscellstr(x),true, ...
                'headlinejust','c',@(x) ischar(x) && any(strncmpi(x,{'c','l','r'},1)),true, ...
                'range',[],@isnumeric,true, ...
                'separator','\medskip\par',@ischar,true, ...
                'typeface','',@ischar,false, ...
                'vline',[],@isnumeric,true, ...
                }];
            THIS.nlead = 3;
        end
        
        function THIS = setoptions(THIS,varargin)
            % Call superclass setoptions to get all options assigned.
            THIS = setoptions@report.tabularobj(THIS,varargin{:});
            if isstruct(THIS.options.columnstruct)
                THIS.options.colstruct = THIS.options.columnstruct;
            end
            isdates = isempty(THIS.options.colstruct);
            if ~isdates
                ncol = length(THIS.options.colstruct);
                THIS.options.range = 1 : ncol;
                for i = 1 : ncol
                    if ischar(THIS.options.colstruct(i).name)
                        THIS.options.colstruct(i).name = {NaN, ...
                            THIS.options.colstruct(i).name};
                    end
                end
            end
            % Find positions of vertical lines.
            temprange = [THIS.options.range(1)-1,THIS.options.range];
            THIS.vline = [];
            for i = THIS.options.vline(:)'
                pos = datcmp(i,temprange);
                if any(pos)
                    THIS.vline(end+1) = find(pos) - 1;
                end
            end
            % Add vertical lines wherever the date frequency changes.
            [ans,ans,freq] = dat2ypf(THIS.options.range); %#ok<NOANS,ASGLU>
            THIS.vline = ...
                unique([THIS.vline,find([false,diff(freq) ~= 0]) - 1]);
            if ischar(THIS.options.datejustify)
                utils.warning('report', ...
                    ['The option ''datejustify'' in report/band is obsolete ', ...
                    'and will be removed from future IRIS versions. ', ...
                    'Use ''headlinejust'' instead.']);
                THIS.options.headlinejust = THIS.options.datejustify;
            end
            THIS.options.headlinejust = lower(THIS.options.headlinejust(1));
            % Dateformat is converted to cellstr, first cell is format for the first
            % dateline or NaN, second cell is format for the second or main dateline.
            if ischar(THIS.options.dateformat)
                THIS.options.dateformat = {NaN,THIS.options.dateformat};
            elseif iscell(THIS.options.dateformat) ...
                    && length(THIS.options.dateformat) == 1
                THIS.options.dateformat = [{NaN},THIS.options.dateformat];
            end
        end
        
        varargout = speclatexcode(varargin)
        varargout = headline(varargin)
        
    end
    
end
