## Copyright (C) 2016 Markus Muetzel
##
## 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  {Function File} {} light ()
## @deftypefnx {Function File} {} light (@dots{}, @var{prop}, @var{val}, @dots{})
## @deftypefnx {Function File} {} light (@var{hax}, @dots{})
## @deftypefnx {Function File} {@var{h} =} light (@dots{})
## Create light object in the current axes or for axes @var{hax}.
##
## When a light object is present in an axes object and the properties
## @qcode{"EdgeLighting"} or @qcode{"FaceLighting"} of a @command{patch} or
## @command{surface} object are set to a value other than @qcode{"none"}, these
## objects are drawn with light and shadow effects. Supported values for these
## properties are "none" (no lighting effects), "flat" (facetted look of the
## objects), "gouraud" (linear interpolation of the lighting effects between the
## vertices) and "phong" (not implemented, "gouraud" lighting is used instead).
## For @command{patch} objects, the normals must be set manually (property
## @qcode{"VertexNormals"}).
## The value of the property @qcode{"BackFaceLighting"} of @command{patch} and
## @command{surface} objects is ignored. The lighting is always done as if
## @qcode{"BackFaceLighting"} was set to @qcode{"lit"}.
##
## Only one light object per axes is supported.
##
## Lighting is only supported for graphics toolkits supporting OpenGL (i.e.
## "fltk" and "qt").
##
## The following properties specific to the light object can be passed with
## their respective values:
##
## @table @asis
## @item @qcode{"Color":} The color of the light object can be passed as an 
## RGB-vector (e.g. @qcode{[1 0 0]} for red) or as a string (e.g. 'r' for red).
## The default color is white (@qcode{[1 1 1]}).
##
## @item @qcode{"Position":} The direction from which the light emanates as an
## 1x3-vector. The default direction is @qcode{[1 0 1]}.
##
## @item @qcode{"Style":} This string defines whether the light emanates from a
## light source at infinite distance ("infinite") or from a local point source
## ("local"). Only the default value "infinite" is supported.
## @end table
##
## If @command{light} is called with an axes handle @var{hax}, it must be passed
## as the first argument.
##
## Optionally, the handle to the light object is returned in @var{h}.
##
## @seealso{get, set, patch, surface}
## @end deftypefn

## Author: mmuetzel

function h = light (varargin)

  [hax, varargin] = __plt_get_axis_arg__ ("light", varargin{:});

  if (isempty (hax))
    hax = gca ();
  else
    hax = hax(1);
  endif

  htmp = __go_light__ (hax, varargin{:});

  if (nargout > 0)
    h = htmp;
  endif

endfunction


%!demo
%! %% Demonstrate effects of lighting
%! clf;
%! %% patches
%! h_axes1 = subplot (2, 2, 1);
%! [x,y,z] = meshgrid (-2:0.2:2, -2:0.2:2, -2:0.2:2);
%! val = x.^2 + y.^2 + z.^2;
%! fv1 = isosurface (x, y, z, val, 1);
%! h_patch1 = patch (fv1, "FaceColor", "c", "EdgeColor", "none", "FaceLighting", "Gouraud");
%! isonormals (x, y, z, val, h_patch1)
%! fv2 = isosurface (x, y+3, z, val, 1);
%! h_patch2 = patch (fv2, "FaceColor", "r", "EdgeColor", "none", "FaceLighting", "Gouraud");
%! isonormals (x, y+3, z, val, h_patch2)
%! axis equal; axis tight
%! title ("Patch with lighting");
%! view (3)
%! h_light = light ();
%!
%! h_axes2 = subplot(2, 2, 2);
%! patch (fv1, "FaceColor", "c", "EdgeColor", "none");
%! patch (fv2, "FaceColor", "r", "EdgeColor", "none");
%! axis equal; axis tight
%! title ("Patch without lighting");
%! view (3)
%!
%! %% surfaces
%! h_axes3 = subplot(2, 2, 3);
%! h_surf1 = surf (h_axes3, peaks, "LineStyle", "none", "FaceLighting", "Gouraud");
%! title ("Surface with lighting");
%! view (3)
%! h_light = light ();
%!
%! h_axes3 = subplot(2, 2, 4);
%! h_surf2 = surf (h_axes3, peaks, "LineStyle", "none");
%! title ("Surface without lighting");
%! view (3)

%!test
%! hf = figure ("Visible", "off");
%! unwind_protect
%!   h = light ();
%!   assert (findobj (hf, "Type", "light"), h);
%!   assert (get (h, "Position"), [1, 0, 1]);
%!   assert (get (h, "Color"), [1, 1, 1]);
%!   assert (get (h, "Style"), "infinite");
%! unwind_protect_cleanup
%!   close (hf);
%! end_unwind_protect

%!test
%! hf = figure ("Visible", "off");
%! ha = gca;
%! unwind_protect
%!   h = light (ha, "Position", [1 2 3], "Color", "r");
%!   assert (get (h, "Position"), [1 2 3]);
%!   assert (get (h, "Color"), [1 0 0]);
%! unwind_protect_cleanup
%!   close (hf);
%! end_unwind_protect

