#  Copyright (c) 1997-2018
#  Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
#  http://www.polymake.org
#
#  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 2, or (at your option) any
#  later version: http://www.gnu.org/licenses/gpl.txt.
#
#  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.
#-------------------------------------------------------------------------------

use JavaView;
use InteractiveViewer;

package JavaView::Viewer;

# installation directory
custom $install_top;

# CLASSPATH listing all jar files belonging to javaview
custom $classpath;

CONFIGURE {
   my $configured=load_extension_config_vars();
   do {
      $install_top=$configured->{JavaViewPath}
        and
      $classpath=$configured->{JavaViewClassPath};
   } or die "Extension configuration script did not produce expected results\n";
}

# location of the license file (for docker image users)
custom $license_file="";

###########################################################################################
package JavaView::default;

# background color for JavaView Viewer
custom $bgColor="255 255 255";

# absolute size of point circles in JavaView measurement units
custom $points_thickness = 4;

# absolute width of lines in JavaView measurement units
custom $lines_thickness = 3;

# intensity of ambient light
custom $ambientIntensity=0.2;

# diffuse reflection of polygons
custom $diffuseColor   = "204 204 204";

# emissive color of polygons
custom $emissiveColor  = "0 0 0";

# shininess of polygons
custom $shininess      = 10.0;

# specular color of polygons
custom $specularColor  = "255 255 255";

###########################################################################################
package JavaView::Viewer::Window;

use Polymake::Struct (
   [ '@ISA' => 'InteractiveViewer::Window' ],
   [ '$class' => '"de.tuberlin.polymake.common.javaview.StaticControl"' ],
);

method detect_dynamic($) { 0 }

###########################################################################################
package JavaView::Viewer;

use Polymake::Struct (
   [ '@ISA' => 'InteractiveViewer' ],
);

sub host_install_top {
   state $host_install_top=do {
      local $_="$Resources/javaview";
      unless (-d) {
         system("cp -pR $install_top $_")
           and die "can't copy JavaView files into $_\n";
      }
      unless (-l "$_/rsrc/jv-lic.lic") {
         if (length($license_file)) {
            if ($license_file =~ m{^/.+/jv-lic\.lic$}) {
               symlink $license_file, "$_/rsrc/jv-lic.lic"
                 or die "can't create a symlink $_/rsrc/jv-lic.lic => $license_file: $!\n";
            } else {
               err_print("Custom variable \$JavaView::Viewer::license_file set to a wrong value,\n",
                         "it must be an absolute path of a file named jv-lic.lic\n");
            }
         } else {
            warn_print(<<'---');
No JavaView license file configured!

Please register at www.javaview.de,
a license file will be sent to you as an e-mail attachment.
Save it somewhere in your home directory tree and set the custom variable
$JavaView::Viewer::license_file to the absolute path.

For example:
  set_custom $JavaView::Viewer::license_file="$ENV{HOME}/my-license/jv-lic.lic";
---
         }
      }
      $_
   };
}

# the active Viewer instance
sub instance : lvalue { state $active }

{  # capture the own extension
   my $ext=$Polymake::Core::Application::extension;

   sub java_extensions { @{$ext->requires}, $ext }
}

# to be filled in the command line
sub start_properties {
   state $bg_color=Visual::get_RGB($JavaView::default::bgColor)->toInt;
   my %jre_properties=( 'jv.licence' => $ENV{POLYMAKE_HOST_AGENT} ? host_install_top() : $install_top,
                        'polymake.javaview.bgcolor' => "\"$bg_color\"" );
   if ($DebugLevel) {
      $jre_properties{"polymake.debug"}=$DebugLevel>=2 ? "max" : "yes";
   }

   \%jre_properties
}

sub classpath {
   if ($ENV{POLYMAKE_HOST_AGENT}) {
      state $copy=do {
         my $in_resources=host_install_top();
         local $_=$classpath;
         s{(?:^|:)\K\Q$install_top\E}{$in_resources}g;
         $_
      };
   } else {
      $classpath
   }
}

sub new_drawing {
   my ($self, $title)=@_;
   push @{$self->new_windows}, new Window(new File($title));
   $self;
}

# for feedback routines
sub visualize {
   shift;
   javaview(@_);        # call the user function in void context
   ()
}

###########################################################################################
#
#  Drawing methods for graphical primitives defined in this application
#

# @category Visualization
# Use [[wiki:external_software#javaview|JavaView]], the default tool for the visualization of 3- or 4-dimensional geometric objects.
#
# You can also use it for graph visualization.  The 3-d spring embedder starts with random node placement,
# so you have a chance to get various embeddings when trying it several times.
label javaview

global_method javaview.geometry: draw(Visual::PointSet, @) {
   my ($self, $P)=@_;
   $self->append(new PointSet($P));
}

global_method javaview.geometry: draw(Visual::Polygon, @) {
   my ($self, $P)=@_;
   if (@{$P->Vertices} >= 3) {
      $self->append(new Solid($P));
   } else {
      $self->append(new Wire(new Visual::DegeneratedPolygon($P)));
   }
}

global_method javaview.geometry: draw(Visual::Polygons, @) {
   my ($self, $P)=@_;
   $self->append(new Solid($P));
}

global_method javaview.geometry: draw(Visual::Wire, @) {
   my ($self, $G)=@_;
   $self->append(new Wire($G));
}

###########################################################################################
#
#  Direct writing to a JVX file without starting a GUI
#

package JavaView::File::Writer;
import Visual::FileWriter;

sub file_suffix { ".jvx" }

sub new_drawing {
   my ($self, $title)=@_;
   $self->title=$title;
   $self;
}

sub DESTROY { }

package application;

# @category Visualization
# Run [[wiki:external_software#javaview|JavaView]] with the given visual objects.
#
# @param Visual::Object vis_obj ... objects to display
#
# @option String File "filename" or "AUTO"
#  Store the object description in a JVX file without starting the interactive GUI.
#  The ''.jvx'' suffix is automatically added to the file name.
#
#  Specify //AUTO// if you want the filename be automatically derived
#  from the drawing title.
#
#  You can also use any expression allowed for the ''open'' function,
#  including "-" for terminal output, "&HANDLE" for an already opened file handle,
#  or "| program" for a pipe.

user_function javaview(Visual::Object+, { File => undef }) {
   visualize_explicit(@_, "JavaView");
}


# Local Variables:
# mode: perl
# cperl-indent-level:3
# indent-tabs-mode:nil
# End:
