classdef report < report.genericobj
    % report  [Not a public class] Top level report object.
    %
    % Backed IRIS class.
    % No help provided.
    
    % -IRIS Toolbox.
    % -Copyright (c) 2007-2012 Jaromir Benes.
    
    properties
        footnotecounter = 0;
    end
    
    methods
        
        function THIS = report(varargin)
            THIS = THIS@report.genericobj(varargin{:});
            THIS.default = [THIS.default,{ ...
                'centering',true,@islogicalscalar,false, ...
                'orientation','landscape', ...
                @(x) any(strcmpi(x,{'landscape','portrait'})),false, ...
                'typeface','',@ischar,false, ...
                }];
            THIS.parent = [];
        end
        
        function THIS = merge(THIS,varargin)
            for i = 1 : length(varargin)
                if isa(varargin{i},'report.report')
                    n = length(varargin{i}.children);
                    for j = 1 : n
                        % Add children to THIS report.
                        THIS.children{end+1} = ...
                            copy(varargin{i}.children{j});
                        % Set the children's parent property to point to
                        % THIS report.
                        varargin{i}.children{j}.parent = THIS;
                    end
                else
                    utils.error('report', ...
                        'Can only merge two or more top-level report objects.');
                end
            end
        end
        
        function [C,TEMPFILES] = speclatexcode(THIS)
            br = sprintf('\n');
            C = '';
            if THIS.options.centering
                C = [C,'\centering',br,br];
            end
            C = [C,begintypeface(THIS)];
            TEMPFILES = {};
            nchild = length(THIS.children);
            for i = 1 : nchild
                ch = THIS.children{i};
                % Add a comment before each of the first-level objects.
                C = [C,br, ...
                    '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%', ...
                    sprintf('%% Start of %s %s', ...
                    shortclass(ch),ch.title), ...
                    br]; %#ok<AGROW>
                % Add user-defined latex commands before each of the first-level objects.
                C = [C,begintypeface(ch)]; %#ok<AGROW>
                [c1,tmphelperfiles] = latexcode(ch);
                C = [C,c1,'%',br]; %#ok<AGROW>
                TEMPFILES = [TEMPFILES,tmphelperfiles]; %#ok<AGROW>
                C = [C,endtypeface(ch)]; %#ok<AGROW>
                C = [C,br]; %#ok<AGROW>
                if i < nchild
                    C = [C,ch.options.separator,br]; %#ok<AGROW>
                end
            end
            C = [C,endtypeface(THIS)];
        end
        
        function publish(THIS,OUTPUTFILE,varargin)
            % The following options passed down to latex.compilepdf:
            % * `'display='`
            % * `'rerun='`
            % and we need to capture them in output varargin.
            [opt,varargin] = passvalopt('report.publish',varargin{:});
            THIS.options.progress = opt.progress;
            if any(strcmpi(opt.papersize,{'a4','letter'}))
                opt.papersize = [opt.papersize,'paper'];
            end
            if ~isequal(opt.title,Inf)
                THIS.caption = opt.title;
                %opt.title = {THIS.title,THIS.subtitle};
            end
            % Obsolete options.
            if ~isempty(opt.deletelatex)
                opt.deletetempfiles = opt.deletelatex;
            end
            if ~isempty(opt.deletetempfiles)
                opt.cleanup = opt.deletetempfiles;
            end
            THIS.options = dbmerge(THIS.options,opt);
            
            % List of extra packages.
            pkg = THIS.options.package;
            if ~iscell(pkg)
                pkg = {pkg};
            end
            if islongtable(THIS)
                pkg{end+1} = 'longtable';
            end
            
            thisdir = fileparts(mfilename('fullpath'));
            templatefile = fullfile(thisdir,'report.tex');
            % Pass the publish options on to the report object and align
            % objects either of which can be a parent of figure.
            [reportcode,tempfiles] = latexcode(THIS);
            c = file2char(templatefile);
            c = strrep(c,'$document$',reportcode);
            c = mydocument(THIS,c,pkg);
            latexfile = [tempname(cd()),'.tex'];
            char2file(c,latexfile);
            [outputpath,outputtitle,outputext] = fileparts(OUTPUTFILE);
            if isempty(outputext)
                OUTPUTFILE = fullfile(outputpath,[outputtitle,'.pdf']);
            end
            % Use try-catch to make sure the helper files are deleted at
            % the end of `publish`.
            try
                pdffile = latex.compilepdf(latexfile,varargin{:});
                movefile(pdffile,OUTPUTFILE);
            catch Error
                msg = regexprep(Error.message,'\s+',' ');
                if ~isempty(strfind(msg,'The process cannot access'))
                    dodeletetempfiles();
                    utils.error('report', ...
                        ['Cannot create ''%s'' file because ', ...
                        'the file used by another process ', ...
                        '-- most likely open and locked.'], ...
                        OUTPUTFILE);
                else
                    utils.warning('report', ...
                        ['Error when compiling LaTeX and/or PDF files.', ...
                        '\n\tMatlab says ''%s'''],msg);
                end
            end
            cleanup(THIS,latexfile,tempfiles);
            
        end
        
        function cleanup(THIS,LATEXFILE,TEMPFILES)
            if THIS.options.cleanup
                % Delete all helper files produced when TeX files was
                % compiled.
                [latexpath,latextitle] = fileparts(LATEXFILE);
                latexfiles = fullfile(latexpath,[latextitle,'.*']);
                if ~isempty(dir(latexfiles))
                    delete(latexfiles);
                end
                % Delete all helper files produced when latex codes for
                % children were built.
                for i = 1 : length(TEMPFILES)
                    if exist(TEMPFILES{i},'file')
                        delete(TEMPFILES{i});
                    end
                end
            end
        end
        
        % Level 1 objects.
        
        function THIS = section(THIS,varargin)
            newobj = report.section(varargin{:});
            THIS = add(THIS,newobj,varargin{2:end});
        end
        
        function THIS = table(THIS,varargin)
            newobj = report.table(varargin{:});
            THIS = add(THIS,newobj,varargin{2:end});
        end
        
        function THIS = figure(THIS,varargin)
            newobj = report.figure(varargin{:});
            THIS = add(THIS,newobj,varargin{2:end});
        end
        
        function THIS = matrix(THIS,varargin)
            newobj = report.matrix(varargin{:});
            THIS = add(THIS,newobj,varargin{2:end});
        end
        
        function THIS = array(THIS,varargin)
            newobj = report.array(varargin{:});
            THIS = add(THIS,newobj,varargin{2:end});
        end
        
        function THIS = tex(THIS,varargin)
            newobj = report.tex(varargin{:});
            THIS = add(THIS,newobj,varargin{2:end});
        end
        
        function THIS = text(THIS,varargin)
            THIS = tex(THIS,varargin{:});
        end
        
        function THIS = texcommand(THIS,varargin)
            newobj = report.texcommand(varargin{:});
            THIS = add(THIS,newobj,varargin{2:end});
        end
        
        function THIS = include(THIS,varargin)
            newobj = report.include(varargin{:});
            THIS = add(THIS,newobj,varargin{2:end});
        end
        
        function THIS = modelfile(THIS,varargin)
            newobj = report.modelfile(varargin{:});
            THIS = add(THIS,newobj,varargin{2:end});
        end
        
        function THIS = pagebreak(THIS,varargin)
            newobj = report.pagebreak(varargin{:});
            THIS = add(THIS,newobj,varargin{2:end});
        end
        
        function THIS = clearpage(THIS,varargin)
            THIS = pagebreak(THIS,varargin{:});
        end
        
        function THIS = align(THIS,varargin)
            newobj = report.align(varargin{:});
            THIS = add(THIS,newobj,varargin{2:end});
        end
        
        function THIS = empty(THIS,varargin)
            newobj = report.empty(varargin{:});
            THIS = add(THIS,newobj,varargin{2:end});
        end
        
        % Level 2 and 3 objects.
        
        function THIS = graph(THIS,varargin)
            newobj = report.graph(varargin{:});
            THIS = add(THIS,newobj,varargin{2:end});
        end
        
        function THIS = series(THIS,varargin)
            newobj = report.series(varargin{:});
            THIS = add(THIS,newobj,varargin{2:end});
        end
        
        function THIS = band(THIS,varargin)
            newobj = report.band(varargin{:});
            THIS = add(THIS,newobj,varargin{2:end});
        end
        
        function THIS = fanchart(THIS,varargin)
            newobj = report.fanchart(varargin{:});
            THIS = add(THIS,newobj,varargin{2:end});
        end
        
        function THIS = vline(THIS,varargin)
            newobj = report.vline(varargin{:});
            THIS = add(THIS,newobj,varargin{2:end});
        end
        
        function THIS = highlight(THIS,varargin)
            newobj = report.highlight(varargin{:});
            THIS = add(THIS,newobj,varargin{2:end});
        end
        
        function THIS = subheading(THIS,varargin)
            newobj = report.subheading(varargin{:});
            THIS = add(THIS,newobj,varargin{2:end});
        end
        
    end
    
    methods (Access=protected)
        
        function FLAG = islongtable(THIS)
            FLAG = false;
            collect = findall(THIS,'report.tabularobj');
            for i = 1 : length(collect)
                if collect{i}.options.long
                    FLAG = true;
                    break
                end
            end
        end
        
        function DOC = mydocument(THIS,DOC,PKG)
            
            opt = THIS.options;
            
            if nargin < 3
                PKG = {};
            end
            
            nl = sprintf('\n');
            
            try
                temptitle = latex.stringsubs(THIS.title);
                tempsubtitle = latex.stringsubs(THIS.subtitle);
                temphead = temptitle;
                if ~isempty(tempsubtitle)
                    if ~isempty(temptitle)
                        temptitle = [temptitle,' \\ '];
                        temphead = [temphead,' / '];
                    end
                    temptitle = [temptitle,'\mdseries ',tempsubtitle];
                    temphead = [temphead,tempsubtitle];
                end
                DOC = strrep(DOC,'$title$',temptitle);
            catch
                DOC = strrep(DOC,'$title$','');
            end
            
            try
                temphead = strrep(temphead,'\\',' / ');
                temphead = latex.stringsubs(temphead);
                DOC = strrep(DOC,'$headertitle$',temphead);
            catch
                DOC = strrep(DOC,'$headertitle$','');
            end
            
            try
                DOC = strrep(DOC,'$author$',opt.author);
            catch
                DOC = strrep(DOC,'$author$','');
            end
            
            try
                DOC = strrep(DOC,'$date$',opt.date);
            catch
                DOC = strrep(DOC,'$date$','');
            end
            
            try
                DOC = strrep(DOC,'$papersize$',opt.papersize);
            catch %#ok<*CTCH>
                DOC = strrep(DOC,'$papersize$','');
            end
            
            try
                DOC = strrep(DOC,'$orientation$',opt.orientation);
            catch
                DOC = strrep(DOC,'$orientation$','');
            end
            
            try
                if isa(opt.timestamp,'function_handle')
                    opt.timestamp = opt.timestamp();
                end
                DOC = strrep(DOC,'$headertimestamp$',opt.timestamp);
            catch
                DOC = strrep(DOC,'$headertimestamp$','');
            end
            
            try
                DOC = strrep(DOC,'$textscale$',sprintf('%g',opt.textscale));
            catch
                DOC = strrep(DOC,'$textscale$','0.75');
            end
            
            try
                DOC = strrep(DOC,'$graphwidth$',opt.graphwidth);
            catch
                DOC = strrep(DOC,'$graphwidth$','4in');
            end
            
            try
                DOC = strrep(DOC,'$fontencoding$',opt.fontenc);
            catch
                DOC = strrep(DOC,'$fontencoding$','T1');
            end
            
            try
                DOC = strrep(DOC,'$preamble$',opt.preamble);
            catch
                DOC = strrep(DOC,'$preamble$','');
            end
            
            try
                if ~isempty(PKG)
                    npkg = length(PKG);
                    pkgstr = '';
                    for i = 1 : npkg
                        pkgstr = [pkgstr,'\usepackage{',PKG{i},'}']; %#ok<AGROW>
                        if i < npkg
                            pkgstr = [pkgstr,nl]; %#ok<AGROW>
                        end
                    end
                    DOC = strrep(DOC,'$packages$',pkgstr);
                else
                    DOC = strrep(DOC,'$packages$','');
                end
            catch
                DOC = strrep(DOC,'$packages$','');
            end
            
            try
                c = sprintf('%g,%g,%g',opt.highlightcolor);
                DOC = strrep(DOC,'$highlightcolor$',c);
            catch
                DOC = strrep(DOC,'$highlightcolor$','0.9,0.9,0.9');
            end
            
            try
                if opt.maketitle
                    repl = '\maketitle\thispagestyle{empty}';
                else
                    repl = '';
                end
            catch
                repl = '';
            end
            DOC = strrep(DOC,'$maketitle$',repl);
            
            try
                if ~isempty(opt.abstract) && opt.maketitle
                    repl = ['\begin{abstract}',nl,...
                        '\input{',opt.abstract,'}',nl,...
                        '\end{abstract}'];
                else
                    repl = '';
                end
            catch
                repl = '';
            end
            DOC = strrep(DOC,'$abstract$',repl);
            
            try
                if opt.maketitle
                    repl = '\clearpage';
                else
                    repl = '';
                end
            catch
                repl = '';
            end
            DOC = strrep(DOC,'$clearfirstpage$',repl);
            
        end
        
    end
    
end