function [m,ok] = leaf_snapshot( m, varargin )
%[m,ok] = leaf_snapshot( m, filename, ... )
% Take a snapshot of the current view of the leaf into an image file.
% A name for the image file will be automatically generated if none is
% given.  If the snapshot cannot be taken or the arguments are invalid then
% ok will be returned as false.
%
%   Arguments:
%       1: The name of the file to write.  The extension of
%          the filename specifies the image format.  This may be
%          any format acceptable to the Matlab function IMWRITE.
%          These include 'png', 'jpg', 'tif', and others.
%
%   Options:
%       'newfile': if true (the default), the file name given will be
%           modified so as to guarantee that it will not overwrite any
%           existing file. If false, the filename will be used as given and
%           any existing file will be overwritten without warning.
%       'thumbnail': if true (the default is false), the other arguments
%           and options will be ignored (the filename must be given as the
%           empty string), and a snapshot will be saved to the file
%           thumbnail.png in the project directory.
%       'resolution': Dots-per-inch value.  Passing this option will cause
%           the procedure to use the Matlab function print() instead of
%           imwrite(), so as to take a picture at whatever resolution you
%           require.  This also has the advantage that as the snapshot is
%           not performed by grabbing the screen buffer, it does not matter
%           whether the window is entirely visible on the screen.  However,
%           the image obtained will be of the entire figure window, instead
%           of just the picture part.  If this option is specified with
%           the empty array as its value, the value currently stored
%           in m.plotdefaults.hiresdpi will be used. Specifying a value for
%           resolution does not update m.plotdefaults.hiresdpi: for that,
%           use leaf_plotoptions( m, 'hiresdpi', ... ).
%
%   All remaining arguments will be passed as options to IMWRITE.  Any
%   arguments taken by IMWRITE may be given.  If any such arguments are
%   provided, the filename must be present (otherwise the first argument
%   for IMWRITE would be taken to be the filename).  If you do not want to
%   provide a filename, specify it as the empty string.  The image will be
%   saved in the 'snapshots' folder of the current project folder, if any,
%   otherwise the current folder.  You can override this by specifying an
%   absolute path.
%
%   Example:
%       m = leaf_snapshot( m, 'foo.png' );
%
%   Equivalent GUI operation: clicking the "Take snapshot" button.  This
%   saves an image in PNG format into a file with an automatically
%   generated name.  A report is written to the Matlab command window.
%   The 'thumbnail' option is equivalent to the "Make Thumbnail" menu
%   command.
%
%   If stereo mode is turned on, snapshots will be stereo, with the two
%   images arranged according to the stereo parameters.
%
%   See also:
%       IMWRITE, PRINT
%
%   Topics: Movies/Images.

    ok = true;
    if isempty(m), return; end
    [ok, framefilename, args] = getTypedArg( mfilename(), 'char', varargin, '' );
    if ~ok, return; end
    [s,ok] = safemakestruct( mfilename(), args );
    if ~ok, return; end
    
    if isempty( m.pictures )
        % complain( '%s: There is no picture to take a snapshot of.', mfilename() );
        ok = false;
        return;
    end
    
    thumbnail = isfield(s,'thumbnail') && s.thumbnail;
    newfile = (~thumbnail) && ((~isfield(s,'newfile')) || s.newfile);
    s = safermfield( s, 'newfile', 'thumbnail' );
    usePrint = isfield( s, 'resolution' );
    if usePrint
        resolution = s.resolution;
        if isempty( resolution ) || (resolution <= 0)
            resolution = m.plotdefaults.hiresdpi;
        end
    else
        imwriteargs = struct2args(s);
    end
    
    framecount = m.globalDynamicProps.currentIter;
    if isempty(framefilename)
        if isempty(m.globalProps.modelname)
            snapshotname = 'snapshot';
        else
            snapshotname = m.globalProps.modelname;
        end
        if thumbnail
            framefilename = 'GPT_thumbnail.png';
        else
            framefilename = sprintf( '%s-%s-00.png', ...
                snapshotname, stageTimeToText( m.globalDynamicProps.currenttime ) );
        end
    end
    h = guidata( m.pictures(1) );

    if thumbnail
        scalebarVis = strcmp( get( h.scalebar, 'Visible' ), 'on' );
        colorbarVis = true; % strcmp( get( h.colorbar, 'Visible' ), 'on' );
        legendVis = strcmp( get( h.legend, 'Visible' ), 'on' );
        pictureVis = strcmp( get( h.picture, 'Visible' ), 'on' );
        if scalebarVis
            set( h.scalebar, 'Visible', 'off' );
        end
        if colorbarVis
            colorBarParams = blankColorBar( h.colorbar, get( h.colorbar, 'Color' ) );
        end
        if legendVis
            set( h.legend, 'Visible', 'off' );
        end
        if pictureVis
            set( h.picture, 'Visible', 'off' );
        end
        drawnow;
    end
        
    frame = mygetframe(h.pictureBackground);

    if thumbnail
        if scalebarVis
            set( h.scalebar, 'Visible', 'on' );
        end
        if colorbarVis
            if ~isempty( colorBarParams )  % Error if empty.
                drawColorbar( h.colorbar, colorBarParams );
            end
        end
        if legendVis
            set( h.legend, 'Visible', 'on' );
        end
        if pictureVis
            set( h.picture, 'Visible', 'on' );
        end
        
        frame.cdata = trimimageborders( frame.cdata );
    end

    if isempty( frame )
        % A warning has been written to the console by mygetframe().
        ok = false;
        return;
    end
    framesize = size(frame.cdata);
    if ~thumbnail
        for i=2:length(m.pictures)
            h = guidata( m.pictures(i) );
            nextframe = mygetframe(h.pictureBackground);
            frame.cdata( :, (framesize(2)*i+1):(framesize(2)*(i+1)), : ) = ...
                trimframe( nextframe.cdata, framesize([1 2]), m.plotdefaults.bgcolor );
        end
    end
    if thumbnail
        olddir = goToProjectDir( m, '' );
        imtype = 'thumbnail';
    else
        olddir = goToProjectDir( m, 'snapshots' );
        imtype = 'snapshot';
    end
    if newfile
        framefilename = newfilename( framefilename );
    end
    fprintf( 1, 'Saving %s of frame %d to %s in %s.\n', ...
        imtype, framecount, framefilename, pwd );
    if usePrint
        print( m.pictures(1), '-dpng', sprintf( '-r%d', resolution ), framefilename );
        resetVisibility( m.pictures(1) );
    else
        imwrite( frame.cdata, framefilename, imwriteargs{:} );
    end
    if isfield(m,'monitor_figs') %if ishandle(1)
        current_figure=gcf;
        revised_list=[];
        for k=1:length(m.monitor_figs)
            if ishandle(m.monitor_figs(k))
                revised_list(end+1)=m.monitor_figs(k);
            end            
        end
        m.monitor_figs=revised_list;
        for k=1:length(m.monitor_figs)
            figurestr=['-f',num2str(m.monitor_figs(k))];
            print(figurestr,'-dpng',[framefilename(1:end-4),'_mon',num2str(m.monitor_figs(k)),'.png']);
            fprintf(1,'Saving monitor Figure %d\n',m.monitor_figs(k));
        end
        figure(current_figure);
    end

    if olddir, cd( olddir ); end

    % Copy the interaction file to a text file with associated name
    if ~thumbnail && ~isempty( m.globalProps.projectdir )
        olddir = goToProjectDir( m, '' );
        interaction_filename = [m.globalProps.modelname,'.m'];
        % Might have to change underscores into hyphens
        if exist(interaction_filename,'file') ~= 2
            % try hyphens
            ind=findstr(interaction_filename,'_');
            interaction_filename(ind)='-';
        end
        targetname = fullfile('snapshots',[framefilename(1:end-4),'.txt']);
        if exist(interaction_filename,'file')==2
            [success,msg,msgid] = copyfile(interaction_filename,targetname,'f');
            if success
                fprintf(1,'Copied %s to %s\n',interaction_filename,targetname);
            else
                fprintf(1,'Failed to copy %s to %s\n    %s\n',interaction_filename,targetname,msg);
            end
        end
        if olddir, cd( olddir ); end
    end
end
