## Copyright (C) 2015 John W. Eaton
##
## This file is part of Octave.
##
## Octave is free software; you can redistribute it and/or modify it
## under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 3 of the License, or (at
## your option) any later version.
##
## Octave is distributed in the hope that it will be useful, but
## WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
## General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with Octave; see the file COPYING.  If not, see
## <http://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn  {Command} {} openfig
## @deftypefnx {Command} {} openfig @var{file}
## @deftypefnx {Function File} openfig(@var{file})
## @deftypefnx {Function File} openfig(@dots{}, @var{"new"})
## @deftypefnx {Function File} openfig(@dots{}, @var{"reuse"})
## @deftypefnx {Function File} openfig(@dots{}, @var{"visible"})
## @deftypefnx {Function File} openfig(@dots{}, @var{"invisible"})
## @deftypefnx {Function File} {@var{h} =} openfig (@dots{})
## Open a saved figure window.
## 
## @seealso{open, saveas, savefig}
## @end deftypefn

## Author: jwe

function F = openfig(varargin)

if (! nargin)
  file =  "Untitled.fig";
else
  file = varargin{1};
  [d,n,ext] = fileparts (file);
  if (isempty (ext))
    file = fullfile(d,[n ".fig"]);
  endif
endif

if (nargin > 3)
  error ("Too many input arguments.");
endif

copies = true;
visibility = {};
for i=2:numel(varargin)
  if (! ischar (varargin{i}))
    error ("Input argument must be a char array.");
  endif
  switch lower(varargin{i})
    case "reuse"
      copies = false;
    case "new"
      copies = true;
    case "visible"
      visibility = {"Visible","on"};
    case "invisible"
      visibility = {"Visible","off"};
    otherwise
      error ("Unknown option ''.",varargin{i});
  endswitch
endfor

hg = load (file,"-mat");
if (isfield (hg,"hgS_070000"))
  hg = hg.hgS_070000;
elseif (isfield (hg,"hgS_050200"))
  hg = hg.hgS_050200;
else
  error ("Invalid Figure file format.");
endif

if (! copies)
  F = findobj (allchild(0),"Type","Figure","FileName",hg.properties.FileName);
  if (! isempty(F))
    F = F(end);
    if (! isempty (visibility))
      set(F, visibility{:});
    endif
    figure(F);
    #movegui (F,"onscreen");
    return;
  endif
endif

p = __struct2list__ (hg.properties);
F = figure (p{:},visibility{:});
#movegui (F,"onscreen"); # and change Position if too large?
__recdisp__ (F,hg.children);

endfunction

function __recdisp__ (F,hg)
for i=1:numel(hg)
  child = hg(i);
  p = __struct2list__ (child.properties, child.type);
  switch (child.type)
    case {"uicontrol","uipanel","uimenu","uicontextmenu"}
      if (isfield (child.properties,"Style") && strcmp(child.properties.Style,"frame"))
        # frame is deprecated: "convert" to uipanel
        child.type = "uipanel";
        p = __struct2list__ (child.properties, child.type);
      endif
      H = feval (child.type,F,p{:});
      __recdisp__ (H,child.children);
    case {"axes","text","image","line"}
      H = feval (child.type,"Parent",F,p{:});
      __recdisp__ (H,child.children);
    case {"patch"}
      H = patch (F,p{:});
      __recdisp__ (H,child.children);
    case {"uitable","uibuttongroup","uitab","uitabgroup"}
      warning ("'%s' type not implemented.",child.type);
    otherwise
      warning ("'%s' type unknown.",child.type);
  endswitch
endfor

endfunction

function p = __struct2list__ (p,t)
if (nargin < 2)
  t = '';
endif
b = {"ApplicationData","BackingStore","Behavior","DVIMode",...
     "HelpTopicKey","Serializable","CLimInclude","ALimInclude",...
     "i_CachedPosition","IncludeRenderer","CurrentAxesMode",...
     "CurrentCharacterMode","CurrentObjectMode","CurrentPointMode",...
     "SelectionTypeMode","PaperSizeMode","ScreenPixelsPerInchMode",...
     "ParentMode","CameraMode","ActivePositionPropertyMode","DataSpaceMode",...
     "ColorSpaceMode","ChildContainerMode","DecorationContainerMode",...
     "BoxFrameMode","XRulerMode","XBaselineMode","YRulerMode","YBaselineMode",...
     "ZRulerMode","ZBaselineMode","AmbientLightSourceMode","SortMethod",...
     "SortMethodMode","PositionMode","ValueMode","FaceMode","BehaviorMode",...
     "ColorMode","InterpreterMode","FontNameMode","FontUnitsMode","FontSizeMode",...
     "FontAngleMode","FontWeightMode","EdgeColorMode","LineStyleMode",...
     "LineWidthMode","BackgroundColorMode","MarginMode","ClippingMode",...
     "UnitsMode","IsContainer","IsContainerMode","HG1EraseMode",...
     "SelectionHighlightMode","HitTestMode","PickableParts","PickablePartsMode",...
     "XLimIncludeMode","YLimIncludeMode","ZLimIncludeMode","CLimIncludeMode",...
     "ALimIncludeMode","SerializableMode","HandleVisibilityMode","Internal"};
if (strcmp (t,"uicontrol"))
  b = [b,"CData"];
elseif (strcmp (t,"axes"))
  b = [b,"XLimSpec","YLimSpec","ZLimSpec","LooseInsetMode","XTickLabelsMode",...
       "YTickLabelsMode","ZTickLabelsMode","WarpToFill","WarpToFillMode"];
elseif (strcmp (t,"patch"))
  b = [b,"FacesMode","VerticesMode","XDataMode","YDataMode","ZDataMode"];
elseif (strcmp (t,"text"))
  b = [b,"DecorationContainer","Layer","LayerMode","FontSmoothing",...
         "FontSmoothingMode","Description","DescriptionMode",...
         "TransformForPrintFcnImplicitInvoke","TransformForPrintFcnImplicitInvokeMode"];
elseif (strcmp (t,"uipanel"))
  b = [b,"Enable","ListboxTop","String","Style"];
endif
for i=1:numel(b)
  if (isfield (p,b{i}))
    p = rmfield (p,b{i});
  endif
endfor
p = [fieldnames(p) struct2cell(p)]';

endfunction
