function [m,ok] = leaf_movie( m, varargin )
%m = leaf_movie( m, ... )
%   Start or stop recording a movie.
%   Any movie currently being recorded will be closed.
%   If the first optional argument is 0, no new movie is started.
%   Otherwise, the arguments may contain the following option-value pairs:
%   FILENAME    The name of the movie file to be opened.  If this is not
%               given, and m.globalProps.autonamemovie is true, then a name
%               will be generated automatically, guaranteed to be different
%               from the name of any existing movie file. Otherwise, a file
%               selection dialog is opened.
%   MODE        (NOT IMPLEMENTED)  This is one of 'screen', 'file', or 'fig'.
%                   'screen' will capture the movie frames from the figure
%               as drawn on the screen, using avifile().
%                   'file' will use print() to save the
%               figure to a file, then load the file and add it to the
%               movie.  This allows arbitrarily high resolution movies to
%               be made, not limited to the size drawn on the screen.
%                   'fig' will save each frame as a MATLAB .fig file
%               and will not generate a movie file.  The figures can later
%               be assembled into a movie file by running the command
%               fig2movie.  The reason for this option is that when
%               running in an environment with no graphics, I have been
%               unable to find a way of creating images from figures.
%   FPS, COMPRESSION, QUALITY, KEYFRAME, COLORMAP, VIDEONAME: These options
%   are passed directly to the Matlab function AVIFILE.  LEAF_MOVIE provides
%   defaults for some of these:
%       FPS          15
%       COMPRESSION  'None'
%       QUALITY      100
%       KEYFRAME     5
%
%   Equivalent GUI operation: clicking the "Record movie..." button.
%
%   See also AVIFILE.
%
%   Topics: Movies/Images.

    ok = true;
    if isempty(m), return; end
    if m.globalProps.makemovie
        fprintf( 1, 'Closing movie file %s.\n', ...
            m.globalProps.moviefile );
        % On the Mac, I find that closing a movie writes the movie file
        % into the current directory, even although the file was created
        % and opened in a different directory.  Therefore we must cd to the
        % directory containing the movie before closing it, and cd back to
        % where we were afterwards.
        [moviefilepath,moviefilename] = ...
            fileparts( m.globalProps.moviefile );
        if m.globalProps.flashmovie
            fprintf( 1, 'If ''Convert to Flash'' were implemented, the movie file would now be converted to Flash format.\n' );
        end
        olddir = trycd( moviefilepath );
        try
            m.globalProps.mov = closemovie(m.globalProps.mov);
        catch
            e = lasterror;
            ok = false;
            GFtboxAlert( 1, 'Could not close movie:\n%s', e.message );
        end
%         % convert uncompressed movie file for web if required
%         flashh=findobj(m.pictures,'tag','convertToFlashItem');
%         if strcmpi(get(flashh,'checked'),'on')
%         %if m.plotdefaults.flashmovie % this did not seem to exist
%             MakeVideosAndFLV( 400, 0, moviefilepath  ,[moviefilename,'.avi'] );
%         end
        if olddir, cd( olddir ); end
        m.globalProps.mov = [];
        m.globalProps.makemovie = 0;
        m.globalProps = safermfield( m.globalProps, 'movieframe' );
        m.globalProps.moviefile = '';
        if hasPicture( m )
            olddir = trycd( moviefilepath );  % goToProjectDir( m, 'movies' );
            figureFilename = fullfile( moviefilepath, moviefilename );
            if ~(isfield(m.globalProps,'RecordMeshes') ...
                    && isfield( m.globalProps.RecordMeshes, 'flag' ) ...
                    && m.globalProps.RecordMeshes.flag ...
                    && isfield( m.globalProps.RecordMeshes, 'saveframe' ) ...
                    && m.globalProps.RecordMeshes.saveframe)
                m.globalProps.RecordMeshes.saveframe=false;
                fprintf( 1, 'Saving final frame at time %f as figure file %s.fig.\n', ...
                    m.globalDynamicProps.currenttime, figureFilename );
                try
                    saveas( m.pictures(1), figureFilename, 'fig' );
                catch
                    GFtboxAlert( 1, 'Could not save figure to %s.', figureFilename );
                end
                finalPicFileName = [figureFilename,'.png'];
                fprintf( 1, 'Saving snapshot of final frame to %s.\n', ...
                    finalPicFileName );
                h = guidata( m.pictures(1) );
                frame = mygetframe(h.pictureBackground);
                try
                    imwrite( frame.cdata, finalPicFileName );
                catch
                    GFtboxAlert( 1, 'Could not save snapshot to %s.', finalPicFileName );
                end
            end
            if ~isempty(m.globalProps.modelname)
                interaction_filename = fullfile('..',[makeIFname(m.globalProps.modelname),'.m']);
                targetname= [moviefilename,'.txt'];
                if exist(interaction_filename,'file')==2
                    try
                        copyfile(interaction_filename,targetname);
                        fprintf(1,'Copied %s to %s\n',interaction_filename,targetname);
                    catch
                        GFtboxAlert( 1, 'Could not copy interaction function to %s.', targetname );
                    end
                end
            end
            if olddir, cd( olddir ); end
        end
        % convert uncompressed movie file for web if required
        flashh=findobj(m.pictures,'tag','convertToFlashItem');
        if strcmpi(get(flashh,'checked'),'on')
        %if m.plotdefaults.flashmovie % this did not seem to exist
            MakeVideosAndFLV( 400, 0, moviefilepath  ,[moviefilename,'.avi'],finalPicFileName );
        end
    end
    m.globalProps.framesize = [];
    
    if ~isempty(varargin) && isnumeric(varargin{1}) && (varargin{1}==0)
        return;
    end
    
    [s,ok] = safemakestruct( mfilename(), varargin );
    if ~ok, return; end
    ok = checkcommandargs( mfilename(), s, 'only', ...
        'mode', 'filename', 'moviedir', 'fps', 'compression', ...
        'quality', 'keyframe', 'colormap', 'videoname' );
    if ~ok, return; end
    
    s = defaultfields( s, ...
        'fps', 15, ...
        'compression', 'None', ...
        'quality', 75, ...
        'keyframe', 5 );
    s.fps = double(s.fps);  % Because it generates a bad movie file if
                            % it's an integer type.
    useNewMethod = strcmp( s.compression, 'Motion JPEG AVI' );
    if useNewMethod && ~(exist( 'VideoWriter.m', 'file' )==2)
        if isinteractive(m)
            queryDialog( 1, 'Unable to perform operation', ...
                '%s compression is not available.  Movie not created.', ...
                s.compression );
        else
            complain( '%s compression is not available.  Movie not created.', ...
                s.compression );
        end
        ok = false;
        return;
    end
    if isfield( s, 'mode' )
        % NOT IMPLEMENTED
         s = rmfield( s, 'mode' );
    end
    
    % The file name may be supplied explicitly, or default to the project
    % name, or be asked for.
    % The directory may be supplied by the filename, explicitly as the
    % 'moviedir' argument, or default to the project movies directory.
    
    filename = '';
    fileext = '';
    filepath = '';
    asked = 0;
    if isfield( s, 'filename' )
        % Use s.filename
        [filepath,filename,fileext] = fileparts( s.filename );
    elseif m.globalProps.autonamemovie && ~isempty(m.globalProps.modelname)
        % Invent a name.
        if ~isempty(m.globalProps.moviefile)
            [filepath,filename,fileext] = fileparts( m.globalProps.moviefile );
        else
            [filepath,filename,fileext] = fileparts( m.globalProps.modelname );
            filename = [ filename, '-0000' ];
        end
    else
        % Ask.
        filterspec = {'*.avi', 'AVI movie files'};
        % Go to movies directory.
        if isempty(m.globalProps.modelname)
            moviefilepath = pwd;
            olddir = '';
        else
            moviefilepath = fullfile( fullfile( m.globalProps.projectdir, m.globalProps.modelname ), 'movies' );
            olddir = trymkdircd( moviefilepath );
        end
        [filename, filepath, filterindex] = uiputfile( ...
        	filterspec, 'Create a movie file');
        % Return to previous directory.
        if olddir, trycd( olddir ); end
        if (filterindex==0) || ~ischar(filename)
            % User cancelled.
            ok = false;
            return;
        end
        fileext = filterspec{filterindex,1};
        fileext = fileext(2:end);  % Get rid of the '*'.
        asked = 1;
        [xfilepath,filename,xfileext] = fileparts( filename );
        if ~isempty( xfileext )
            fileext = xfileext;
        end
    end
    
    if isempty(fileext)
        fileext = '.avi';
    end
    
    if ~asked
        if isrootpath( filepath )
            % This is the directory to use.
        elseif isfield( s, 'moviedir' )
            % Directory is s.moviedir.
            filepath = s.moviedir;
        else
            % Directory is project movies directory.
            modeldir = getModelDir( m );
            filepath = fullfile( modeldir, 'movies' );
        end
    end
    
    filename = fullfile(filepath,[filename,fileext]);
    if (~asked) && (~m.globalProps.overwritemovie)
        filename = newfilename( filename );
    end
    [filepath,filename,fileext] = fileparts( filename );
    
    s = safermfield( s, 'filename', 'moviedir' );
    
    olddir = trymkdircd( filepath );
    
    basemoviename = [ filename, fileext ];
    m.globalProps.moviefile = fullfile( filepath, basemoviename );
    m.globalProps.makemovie = 1;
    aviargs = struct2args(s);
    try
        if useNewMethod
            m.globalProps.mov = VideoWriter( basemoviename, s.compression );
            m.globalProps.mov.FrameRate = s.fps;
            m.globalProps.mov.Quality = s.quality;
            % Set other properties here: compression quality.
            open( m.globalProps.mov );
        else
            m.globalProps.mov = avifile( basemoviename, aviargs{:} );
            m.globalProps.mov = setFromStruct( m.globalProps.mov, s );
        end
        fprintf( 1, 'Starting movie file %s.\n', ...
            m.globalProps.moviefile );
        fprintf( 1, 'Using %s compressor, %d quality.  Frame rate %d fps.\n', ...
            s.compression, s.quality, s.fps );
        m = recordframe( m );
    catch
        e = lasterror();
        if strcmp( e.identifier, 'MATLAB:aviset:invalidCompressionType' )
            GFtboxAlert( 1, 'Movie not started:\nCompression method %s not supported', ...
                s.compression );
        else
            GFtboxAlert( 1, 'Movie not started:\n%s', ...
                regexprep( e.message, '<[^>]*>', '' ) );
        end
        m.globalProps.mov = [];
        m.globalProps.makemovie = 0;
    end

    if olddir, cd( olddir ); end
end

        
