##  Copyright (C) 2014  Daniel Kraft <d@domob.eu>
##  GNU Octave level-set package.
##
##  This program 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.
##
##  This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.

## -*- texinfo -*-
## @deftypefn  {Function File} {@var{geom} =} ls_absolute_geom (@var{geom}, @var{XX}, @var{YY})
##
## Extend the geometry structure @var{geom} of @code{ls_find_geometry}
## to include absolute coordinates.  In addition to @code{ls_find_geometry},
## this function has access to absolute grid-point coordinates, and uses them
## to set the additional @code{@var{geom}.ispts.coord} field to absolute
## coordinates.  The format is the same as the relative coordinates
## in @code{@var{geom}.ispts.incoord}.  Also, it adds the new entry
## @code{nodes} to @var{geom}, with the following fields:
##
## @table @code
## @item n
## Total number of nodes.  This is the number of entries in @var{phi}.
##
## @item coord
## @code{n} x 2 matrix containing the absolute coordinates of each node.
## The nodes are numbered in the range 1--@code{n} in the internal
## ordering of Octave.
## @end table
##
## Currently, only 2D is supported.  @var{XX} and @var{YY} should be the
## grid-point coordinates according to @code{meshgrid} or @code{ndgrid}.
## 
## @seealso{ls_find_geometry, meshgrid, ndgrid}
## @end deftypefn

function geom = ls_absolute_geom (geom, XX, YY)
  if (nargin () ~= 3)
    print_usage ();
  endif

  sz = size (XX);
  if (length (sz) ~= 2 || any (sz < 2))
    error ("ls_absolute_geom is only implemented for 2D");
  endif
  if (any (sz ~= size (YY)))
    error ("sizes mismatch");
  endif

  xCoords = XX(:);
  yCoords = YY(:);
  inpts = geom.ispts.inout(:, 1);
  geom.ispts.coord = [xCoords(inpts), yCoords(inpts)] + geom.ispts.incoord;
  geom.nodes = struct ("n", prod (sz), "coord", [xCoords, yCoords]);
endfunction

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Tests.

% Test for error conditions.
%!error <Invalid call to>
%!  ls_absolute_geom (1, 2);
%!error <Invalid call to>
%!  ls_absolute_geom (1, 2, 3, 4);
%!error <ls_absolute_geom is only implemented for 2D>
%!  x = [-1, 1];
%!  [XX, YY, ZZ] = ndgrid (x);
%!  ls_absolute_geom (struct (), XX, YY);
%!error <ls_absolute_geom is only implemented for 2D>
%!  ls_absolute_geom (struct (), [-1, 0, 1], [0, 0, 0]);
%!error <sizes mismatch>
%!  ls_absolute_geom (struct (), zeros (3, 2), zeros (2, 2));

% No real functional test for now.  It is 'tested' in the demo
% of ls_find_geometry, though.
