classdef align < report.tabularobj
    % align  Vertically align the following K objects.
    %
    % Syntax
    % =======
    %
    %     P.align('',K,NCOL)
    %
    % Input arguments
    % ================
    %
    % * `P` [ struct ] - Report object created by the
    % [`report.new`](report/new) function.
    %
    % * `K` [ numeric ] - Number of objects following this `align`
    % that will be vertically aligned.
    %
    % * `NCOL` [ numeric ] - Number of columns in which the objects will
    % vertically aligned.
    %
    % Options
    % ========
    %
    % * `'hspace='` [ numeric | *`2`* ] - Horizontal space (in em units) inserted
    % between two neighbouring objects.
    %
    % * `'separator='` [ char | *`'\medskip\par`* ] - (Inheritable from parent
    % objects) \LaTeX\ commands that will be inserted after the aligned objects.
    %
    % * `'typeface='` [ char | *empty* ] - (Not inheritable from parent objects)
    % \LaTeX\ code specifying the typeface for the align element as a whole; it
    % must use the declarative forms (such as `\itshape`) and not the command
    % forms (such as `\textit{...}`).
    %
    % Description
    % ============
    %
    % Vertically aligned can be the following types of objects:
    %
    % * [`figure`](report/figure)
    % * [`table`](report/table)
    % * [`matrix`](report/matrix)
    % * [`array`](report/array)
    %
    % Note that the `align` object itself has no caption (even if you specify
    % one it will not be used). Only the objects within `align` will be given
    % captions. If the objects aligned on one row have identical captions (i.e.
    % both titles and subtitles), only one caption will be displayed centred
    % above the objects.
    %
    % Because [`empty`](report/empty) objects count in the total number of
    % objects inluded in `align`, you can use [`empty`](report/empty) in to
    % create blank space in a particular position.
    %
    % Example
    % ========
    %
    
    % -IRIS Toolbox.
    % -Copyright (c) 2007-2012 Jaromir Benes.
    
    properties
        K = 1;
    end
    
    methods
        
        function this = align(varargin)
            this = this@report.tabularobj(varargin{:});
            this.childof = {'report'};
            this.default = [this.default, {...
                'hspace',2,@isnumericscalar,true, ...
                'separator','\medskip\par',@ischar,true, ...
                'typeface','',@ischar,false, ...
                }];
        end
        
        function [this,varargin] = specargin(this,varargin)
            this.caption = {'',''};
            if isnumericscalar(varargin{1}) ...
                    && varargin{1} == round(varargin{1}) ...
                    && varargin{1} >= 0
                this.K = varargin{1};
                varargin(1) = [];
            else
                utils.error('report', ...
                    'Invalid input argument K in ALIGN.');
            end
            if isnumericscalar(varargin{1}) ...
                    && varargin{1} == round(varargin{1}) ...
                    && varargin{1} > 0
                this.ncol = varargin{1};
                varargin(1) = [];
            else
                utils.error('report', ...
                    'Invalid input argument NCOL in ALIGN.');
            end
        end
        
        function this = setoptions(this,varargin)
            this = setoptions@report.tabularobj(this,varargin{:});
            this.options.long = false;
            this.options.sideways = false;
        end
        
        function [c,helperfiles] = speclatexcode(this)
            c = '';
            helperfiles = {};
            nchild = length(this.children);
            if nchild == 0
                return
            end
            br = sprintf('\n');
            ncol = min([this.ncol,nchild]);
            onecol = ...
                ['l@{\hspace*{',sprintf('%gem',this.options.hspace),'}}'];
            colspec = ...
                ['{@{\hspace*{-3pt}}',repmat(onecol,1,ncol-1),'l}'];
            c = [c,'\begin{tabular}[t]',colspec];
            children = this.children;
            while ~isempty(children)
                n = min([ncol,length(children)]);
                obj = children(1:n);
                children(1:n) = [];
                [this,obj] = samecaption(this,obj);
                if ~isempty(this.title)
                    c = [c,br,printcaption(this,ncol,'c',7)]; %#ok<AGROW>
                end
                for i = 1 : n
                    [c1,tmp] = latexcode(obj{i});
                    helperfiles = [helperfiles,tmp]; %#ok<AGROW>
                    c = [c,br,c1]; %#ok<AGROW>
                    if i < n
                        c = [c,br,'&']; %#ok<AGROW>
                    end
                end
                if ~isempty(children)
                    c = [c,br,'\\ \\ \\']; %#ok<AGROW>
                end
            end
            c = [c,br,'\end{tabular}'];
        end
        
    end
    
    methods (Access = protected, Hidden)
        
        function flag = accepts(this)
            flag = length(this.children) < this.K;
        end
        
        function [this,obj] = samecaption(this,obj)
            tit = obj{1}.title;
            subtit = obj{1}.subtitle;
            form = obj{1}.options.captiontypeface;
            flag = true;
            for i = 2 : length(obj)
                if ~strcmp(tit,obj{i}.title) ...
                        || ~strcmp(subtit,obj{i}.subtitle)
                    flag = false;
                    break
                end
            end
            if flag
                for i = 1 : length(obj)
                    obj{i}.caption = {'',''};
                end
                this.caption = {tit,subtit};
                this.options.captiontypeface = form;
            else
                this.caption = {'',''};
            end
        end
        
    end
    
end