function fig_export( fig, file, varargin )
%FIG_EXPORT  Export figure to various graphical formats.

% (c) 2008-05-28 Martin Matousek
% Last change: $Date$
%              $Revision$

  fu = get( fig, 'units' );

  set( fig, 'units', 'points' )
  fpos = get( fig, 'position' );

  popt = {};
  hidestrings = 1;

  while ~isempty( varargin )
    cmd = varargin{1};
    varargin = varargin(2:end);
    switch cmd
      case 'nohidestrings'
        hidestrings = 0;
      case 'legend'
        set( legend, 'location', varargin{1} );
        varargin = varargin(2:end);
      case 'legendpos'
        set( legend, 'position', varargin{1} );
        varargin = varargin(2:end);
      case 'axnormal'
        axis( gca, 'normal' )
      case 'axequal'
        axis( gca, 'equal' )
      case 'aximage'
        axis( gca, 'image' )
      case 'axborder'
        p = varargin{1};
        varargin = varargin(2:end);
        set( gca, 'units', 'normalized', 'position', [0 0 1 1] );
        set( gca, 'units', 'points' );
        set( gca, 'position', get( gca, 'position' ) + ...
                  [p(1:2) -p(1:2)-p(3:4)] );
      case 'size'
        fpos(3:4) = varargin{1};
        varargin = varargin(2:end);
        set( fig, 'position', fpos );
      case 'sizecm'
        set( fig, 'units', 'centimeters' )
        fposcm = get( fig, 'position' );
        fposcm(3:4) = varargin{1};
        varargin = varargin(2:end);
        set( fig, 'position', fposcm );
        set( fig, 'units', 'points' )
        fpos = get( fig, 'position' );

      case 'fontsize'
        fsiz = varargin{1};
        varargin = varargin(2:end);

        set( findall( fig, 'type', 'text' ), 'fontsize', fsiz );
        set( findall( fig, 'type', 'axes' ), 'fontsize', fsiz );
      case 'tight'
        apos = get( gca, 'position' );
        fpos = get( fig, 'position' );

        fpos(3) = fpos(3) * apos(3);
        fpos(4) = fpos(4) * apos(4);

        set( fig, 'position', fpos );
        set( gca, 'position', [ 0 0 1 1] );
      case 'tightax'
        set( gca, 'position', [ 0 0 1 1] );
      case 'tightinset'
        u = get( gca, 'units' );
        set( gca, 'units', 'normalized' );
        for i = 1:10
          ti = get( gca, 'tightinset' );
          set( gca, 'position', [ti(1:2) 1-ti(1:2)-ti(3:4)] );
        end
        %     set( gca, 'units', 'points' );
        %     p = get( gca, 'position' );
        %     set( gca, 'position', get( gca, 'position' ) + [2 2 -4 -4] );
        set( gca, 'units', u );
      case 'loose'
        popt = [ popt { '-loose' } ]; %#ok
      case 'cmd'
        eval( varargin{1} )
        varargin = varargin(2:end);
      otherwise
        error( 'Wrong option ''%s''.', cmd );

    end % switch
  end % while

  allax = findobj( gcf, 'type', 'axes' );
  set( fig, 'paperunits', 'points', 'papersize', fpos(3:4), ...
            'paperposition', [0 0 fpos(3:4)] );

  if ~isempty( file )

    hidden = [];
    if hidestrings
      for i = 1:length(allax)
        hidden = [ hidden; hide_strings_off_limits( allax(i) ) ];%#ok
      end
    end

    [ ~, ~, ext ] = fileparts( file );

    switch ext
      case '.pdf'
        print( fig, '-dpdf', popt{:}, file );
      case '.eps'
        print( fig, '-depsc2', popt{:}, file );
      case '.png'
        print( fig, '-dpng', '-r150', popt{:}, file );
      otherwise
        error( '???' );
    end
    fprintf( 'Saved: %s\n', file );

    if ~isempty( hidden )
      set( hidden, 'visible', 'on' );
    end
  end

  set( fig, 'units', fu )

  %   PaperOrientation: [ {portrait} | landscape | rotated ]
  %         PaperPosition
  %         PaperPositionMode: [ auto | {manual} ]
  %         PaperSize
end % fcn.


function hidden = hide_strings_off_limits( ax )

  h = findobj( ax, 'type', 'text' );
  xl = xlim;
  yl = ylim;
  zl = zlim;

  p = get( h, 'position' );
  s = get( h, 'string' );
  v = get( h, 'visible' );
  u = get( h, 'units' );

  if ~iscell( p )
    p = {p};
    s = {s};
    v = {v};
    u = {u};
  end

  hidden = [];
  for i = 1:length(h)

    if ( ~inside( p{i}(1), xl ) || ...
          ~inside( p{i}(2), yl ) || ...
          ~inside( p{i}(3), zl ) ) && strcmp( v{i}, 'on' ) && ...
        strcmp( u{i}, 'data' )
      set( h(i), 'visible', 'off' )
      hidden = [ hidden; h(i) ]; %#ok
      fprintf( 'Off-limits string temporarily hidden ''%s''\n', s{i} );
    end
  end

end % fcn.


function i = inside( val, lim )
  i = val >= lim(1) && val <= lim(2);
end % fcn.
