classdef graph < report.genericobj
    % graph  Add graph to figure.
    %
    % Syntax
    % =======
    %
    %     P.graph(CAPTION,...)
    %
    % Input arguments
    % ================
    %
    % * `P` [ struct ] - Report object created by the [`report.new`](report/new)
    % function.
    %
    % * `CAPTION` [ char | cellstr ] - Title, or cell array with title and
    % subtitle, displayed at the top of the graph.
    %
    % Options
    % ========
    %
    % * `'axesOptions='` [ cell | *empty* ] - Options executed by calling `set`
    % on the axes handle before running `'postProcess='`.
    %
    % * `'dateFormat='` [ char | *`'YYYY:P'`* ] - (Inheritable from parent
    % objects) Date format string, see help on [`dat2str`](dates/dat2str).
    %
    % * `'dateTick='` [ numeric | *`Inf`* ] - (Inheritable from parent objects)
    % Date tick spacing.
    %
    % * `'legend='` [ *`false`* | `true` ] - (Inheritable from parent objects) Add
    % legend to the graph.
    %
    % * `'legendLocation='` [ char | *`'best'`* ] - (Inheritable from parent
    % objects) Location of the legend box; see help on `legend` for values
    % available.
    %
    % * `'postProcess='` [ char | *empty* ] - String with Matlab commands
    % executed after the graph has been drawn and styled; the commands have
    % access to variable `H`, a handle to the current axes object.
    %
    % * `'preProcess='` [ char | *empty* ] - String with Matlab commands
    % executed before the graph has been drawn and styled; the commands have
    % access to variable `H`, a handle to the current axes object.
    %
    % * `'range='` [ numeric | *`Inf`* ] - (Inheritable from parent objects) Graph
    % range.
    %
    % * `'style='` [ struct | *empty* ] - (Inheritable from parent objects)
    % Apply this style structure to the graph and its children; see help on
    % [`qstyle`](qreport/qstyle).
    %
    % * `'tight='` [ *`true`* | `false` ] - (Inheritable from parent objects) Set
    % the y-axis limits to the minimum and maximum of displayed data.
    %
    % * `'zeroLine='` [ `true` | *`false`* ] - (Inheritable from parent objects) Add
    % a horizontal zero line if zero is included on the y-axis.
    %
    % Generic options
    % ================
    %
    % See help on [generic options](report/Contents) in report objects.
    %
    % Description
    % ============
    %
    % Example
    % ========
    %
    
    % -IRIS Toolbox.
    % -Copyright (c) 2007-2012 Jaromir Benes.
    
    methods
        
        function this = graph(varargin)
            this = this@report.genericobj(varargin{:});
            this.childof = {'figure'};
            this.default = [this.default, { ...
                'axesoptions',{},@(x) iscell(x) && iscellstr(x(1:2:end)),true, ...
                'dateformat',irisget('plotdateformat'),@ischar,true, ...
                'datetick',Inf,@isnumeric,true, ...
                'grid',true,@islogicalscalar,true, ... Obsolete, use style.
                'highlight',[],@(x) isnumeric(x) ...
                || (iscell(x) && all(cellfun(@isnumeric,x))),true, ... Obsolete, use highlight object.
                'legend',false,@(x) islogical(x) || isnumeric(x),true, ...
                'legendlocation','Best',@ischar,true, ...
                'preprocess','',@(x) isempty(x) || ischar(x),true, ...
                'postprocess','',@(x) isempty(x) || ischar(x),true, ...
                'range',Inf,@isnumeric,true, ...
                'style',[],@(x) isempty(x) || isstruct(x),true, ...
                'tight',true,@islogical,true, ...
                'xlabel','',@ischar,true, ...
                'ylabel','',@ischar,true, ...
                'zlabel','',@ischar,true, ...
                'zeroline',false,@islogical,true, ...
                }];
        end
        
        function [this,varargin] = specargin(this,varargin)
        end
        
        % Plot this graph.
        function plot(THIS,AX)
            if isempty(THIS.children)
                return
            end
            % Clear the axes object.
            cla(AX);
            % Run user-supplied pre-processor.
            if ~isempty(THIS.options.preprocess)
                qreport.styleprocessor(AX,THIS.options.preprocess);
            end
            % Array of legend entries.
            lgdentries = {};
            % Plot children other than annotate objects. The annotate objects
            % will be plotted last.
            nchild = length(THIS.children);
            annotateindex = false(1,nchild);
            held = false;
            for i = 1 : nchild
                if isa(THIS.children{i},'report.annotateobj')
                    annotateindex(i) = true;
                    continue
                end
                lgdentries{end+1} = plot(THIS.children{i},AX); %#ok<AGROW>
                if ~held
                    % The following two lines emulate `hold('all')` and are
                    % faster than `hold('all')`.
                    set(AX,'nextPlot','add');
                    setappdata(AX,'PlotHoldStyle',true);
                    held = true;
                end
            end
            if THIS.options.grid
                grid(AX,'on');
            end
            if THIS.options.zeroline
                zeroline(AX);
            end
            % Make y-axis tight if requested by the user. Only after that the
            % vline children can be plotted.
            if THIS.options.tight
                grfun.yaxistight(AX);
            end
            % Plot highlight and vline. These are excluded from legend.
            for i = find(annotateindex)
                plot(THIS.children{i},AX);
            end
            % Find children tagged 'background' and move them to
            % background.
            ch = get(AX,'children');
            bg = findobj(ch,'flat','tag','background');
            for ibg = bg(:).'
                ch(ch == ibg) = [];
            end
            ch = [ch;bg];
            set(AX,'children',ch);
            set(AX,'layer','top');
            % Add legend.
            lg = [];
            if (islogical(THIS.options.legend) && THIS.options.legend) ...
                    || (isnumeric(THIS.options.legend) && ~isempty(THIS.options.legend))
                if isnumeric(THIS.options.legend) && ~isempty(THIS.options.legend)
                    % Select only the legend entries specified by the user.
                    lgdentries = lgdentries(THIS.options.legend);
                end
                lgdentries = [lgdentries{:}];
                lg = legend(AX,lgdentries{:}, ...
                    'location',THIS.options.legendlocation);
            end
            if ~isempty(THIS.caption)
                if ~isempty(lg) && strcmpi(get(lg,'Location'),'northOutside')
                    tt = get(lg,'title');
                    set(tt,'string',THIS.caption,'interpreter','none', ...
                        'visible','on');
                else
                    title(THIS.caption,'interpreter','none');
                end
            end
            % Annotate axes.
            if ~isempty(THIS.options.xlabel)
                xlabel(AX,THIS.options.xlabel);
            end
            if ~isempty(THIS.options.ylabel)
                xlabel(AX,THIS.options.ylabel);
            end
            if ~isempty(THIS.options.zlabel)
                xlabel(AX,THIS.options.zlabel);
            end
            if ~isempty(THIS.options.style)
                % Apply styles to the axes object and its children.
                qstyle(THIS.options.style,AX,'warning',false);
                if ~isempty(lg)
                    % Apply styles to the legend axes.
                    qstyle(THIS.options.style,lg,'warning',false);
                end
            end
            % Run user supplied axes options.
            if ~isempty(THIS.options.axesoptions)
                set(AX,THIS.options.axesoptions{:});
            end
            % Run user-supplied post-processor.
            if ~isempty(THIS.options.postprocess)
                qreport.styleprocessor(AX,THIS.options.postprocess);
            end
        end
        
        function ax = subplot(this,r,c,i)
            ax = subplot(r,c,i);
        end
        
    end
    
end