function figsave(fnum,savename,shape,enhance)
% function figsave(fnum,savename,shape,enhance)
%
%    Function FIGSAVE - export figure in desired graphics format
%
%    figsave(fnum,savename)
%    figsave(fnum,savename,shape)
%    figsave(fnum,savename,shape,enhance)
%
%    FIGSAVE wraps up a number of the Matlab PRINT commands to provide
%    optimum graphics export for JPEG, PDF and EPS files.  The figure
%    settings have been optimised to ensure graphics files are (relatively)
%    square and the images are centred.
%
%    figsave(fnum,savename) - export figure number FNUM to graphics file
%        SAVENAME.
%
%        The file extension of SAVENAME is used to specify the graphics
%        format of the saved file.  It can be one of the following:
%
%       'jpg' - export as JPEG, with 300dpi resolution and quality level of
%               80.
%
%       'pdf' - export to colour PDF file.
%
%       'eps' - export to colour Level 2 encapsulated postscript with TIFF
%               preview.
%
%    figsave(fnum,savename,shape) - specify shape of figure to be saved.
%
%        By default, the figure is autoscaled to fit an A4 landscape page.
%        Specifying SHAPE allows a number of different options to be
%        specified.  The SHAPE variable can either be a string or
%        numerical, and can have the following values:
%
%        'A4' or 'a4' - landscape A4 (default).
%
%        'A4square', 'a4square', 'A4s' or 'a4s' - scales paper size to be
%            as close to square as possible, with the height equal to 'a4'
%            but a narrower width.  Best for images.
%
%        'square' - same as 'a4square'.
%
%        'A3' or 'a3' - landscape A3.
%
%        'A3square', 'a3square', 'A3s' or 'a3s' - scales paper size to be
%            as close to square as possible, with the height equal to 'a3'
%            but a narrower width.
%
%        'screen' - takes the dimensions from the figure size as it is
%            currently displayed on screen.
%
%        'halfheight' - takes the dimensions from the figure size as it is
%            currently displayed on screen, but shrinks the height by 2.
%
%        [HxW] - a single value, HxW, that gives the height-to-width ratio
%            of the figure; it is then scaled to fit a4 landscape.
%
%        [WIDTH HEIGHT] - a pair of values that give the WIDTH and HEIGHT
%            of the figure in centimetres.
%
%    figsave(fnum,savename,shape,enhance) - enhance figure with JPGPLOT.
%
%        In order to run JPGPLOT(FNUM), to enhance the figure text and
%        lines and make them clearer, set ENHANCE = 'enhance'.  The default
%        value is ENHANCE = 0 (figure not enhanced).
%

%    Make sure input arguments are correct

    if nargin > 4
        error('Can only specify 4 input arguments: figsave(fnum,savename,shape,enhance)') ;
    end

    if nargin < 2
        error('Must specify at least 2 input arguments: figsave(fnum,savename)') ;
    end

    inds = find( savename == '.' ) ;
    gtype = savename(inds(end)+1:end) ;

    if ~ischar(savename)
        error('SAVENAME must be a string') ;
    end

    if nargin < 4 || ~strcmp(enhance,'enhance')
        enhance = 0 ;
    else
        jpgplot(fnum) ;
    end

    if nargin < 3 || isempty(shape)
        shape = 'a4' ;
    end

%    Get current paper settings

    curunits = get(fnum, 'PaperUnits') ;
    cursize = get(fnum, 'PaperSize') ;
    curppm = get(fnum, 'PaperPositionMode') ;
    curpp = get(fnum, 'PaperPosition') ;

%    Set figure size for saving

    set(fnum,'PaperUnits','centimeters') ;
    set(fnum,'PaperSize', [29.6774 20.984]) ;

    if ischar(shape)

        switch shape
            case {'A4','a4'}
                set(fnum,'PaperSize', [29.6774 20.984]) ;
            case {'A4s','a4s','A4square','a4square','square'}
                set(fnum,'PaperSize', [22.2184 20.984]) ;
            case{'A3','a3'}
                set(fnum,'PaperSize', [41.9487 29.6812]) ;
            case {'A3s','a3s','A3square','a3square'}
                set(fnum,'PaperSize', [31.4272 29.6812]) ;
            case {'screen'}
                set(fnum, 'PaperPositionMode', 'auto') ;
                scpp = get(fnum,'PaperPosition') ;
                set(fnum,'PaperSize', scpp(3:4)) ;
            case {'halfheight'}
                set(fnum, 'PaperPositionMode', 'auto') ;
                scpp = get(fnum,'PaperPosition') ;
                scpp(4) = round(scpp(4)./2) ;
                set(fnum,'PaperSize', scpp(3:4)) ;
            otherwise
                error('SHAPE variable is unknown') ;
        end

    elseif isnumeric(shape)

        if length(shape) == 1
            if shape < sqrt(2)
                set(fnum,'PaperSize', [shape.*20.984 20.984]) ;
            else
                set(fnum,'PaperSize', [29.6774 29.6774./shape]) ;
            end
        elseif length(shape) == 2
            set(fnum,'PaperSize', [shape(1) shape(2)]) ;
        else
            error('SHAPE variable is unknown') ;
        end

    else
        error('SHAPE variable is unknown') ;
    end

    set(fnum, 'PaperPositionMode', 'manual') ;
    set(fnum,'PaperUnits','normalized') ;
    set(fnum, 'PaperPosition', [0 0 1 1]) ;
    set(fnum,'PaperUnits','centimeters') ;

%    Export as JPEG

    if ( strcmp(gtype,'jpg') ) || ( strcmp(gtype,'jpeg') )

        eval(['print -f' num2str(fnum) ' -r300 -djpeg80 ' savename ' ;']) ;

%    Export as PDF or EPS

    elseif strcmp(gtype,'pdf') || strcmp(gtype,'eps')

        if strcmp(gtype,'pdf')
            eval(['print -f' num2str(fnum) ' -r300 -dpdf ' savename ' ;']) ;
        elseif strcmp(gtype,'eps')
%            eval(['print -f' num2str(fnum) ' -r300 -tiff -depsc2 ' savename ' ;']) ;
%            set(fnum,'PaperOrientation','landscape') ;
            eval(['print -f' num2str(fnum) ' -r300 -depsc2 ' savename ' ;']) ;
%            set(fnum,'PaperOrientation','portrait') ;
        end

    else

        error('Graphics format not recognised: must be jpg, pdf or eps') ;

    end

%    Reset to previous paper settings

    set(fnum, 'PaperUnits', curunits) ;
    set(fnum, 'PaperSize', cursize) ;
    set(fnum, 'PaperPositionMode', curppm) ;
    set(fnum, 'PaperPosition', curpp) ;

    return
