#  Copyright (c) 1997-2010
#  Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Darmstadt, Germany)
#  http://www.polymake.de
#
#  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.
#-------------------------------------------------------------------------------
#  $Project: polymake $$Id: visual.rules 9562 2010-03-12 18:52:58Z smoeser $


###############################################################################
#
#  some common colors
#
package Visual::Color;

# @topic custom
# All colors defined here are RGB values in integer representation (0..255)
# You may use symbolic names defined in the file $RGBtxt as well.

# file with symbolic color names (as shipped with X11 system)
custom $RGBtxt_path;

CONFIGURE {
   $RGBtxt_path="";
   foreach my $dir (qw( /usr/X11/lib/X11 /usr/share/X11 /usr/X11/share/X11 /usr/X11R6/lib/X11
			/usr/local/X11/lib/X11 /usr/local/X11R6/lib/X11 /usr/openwin/lib/X11 )) {
      if (-f (my $f="$dir/rgb.txt")) {
	 $RGBtxt_path=$f; last;
      }
   }
   warn_print("file rgb.txt not found - no symbolic color names will be allowed") unless $RGBtxt_path;
   1;  # go on compiling anyway
}

# facets in famous polymake-green
custom $facets="119 236 158";

# edges of facets and graphs: black
custom $edges="0 0 0";

# vertices: red
custom $vertices="255 0 0";

# color for artificial facets resulting from cutting off
custom $cutoff="255 0 0";

###############################################################################
package application;

require Visual;
require Visual::PointSet;
require Visual::Polygon;

declare property_type RGB : c++ (include=>["color.h"]) {

   method parse_string {
      my ($proto, $value)=@_;
      if ($value =~ /[^\s\d.]/) {
	 # symbolic color name?
	 Visual::get_sym_color($value) or croak("unknown color name '$value'");
      } else {
	 &CPlusPlus::construct_parsed;
      }
   }

   method construct(Int,Int,Int) : c++;

   method construct(Float,Float,Float) : c++;

   method toInt { join($_[1] || " ", map { POSIX::ceil($_*255) } @{$_[0]}) }

   method toHex	{ sprintf "#%02X%02X%02X", map { POSIX::ceil($_*255) } @{$_[0]} }

   method toFloat { my $sep=$_[1] || " "; sprintf "%.4g$sep%.4g$sep%.4g", @{$_[0]} }
}

declare property_type HSV : c++ (include=>["color.h"]) {

   method construct(Float,Float,Float) : c++;

   method construct(RGB) : c++;

   method toFloat { my $sep=$_[1] || " "; sprintf "%.4g$sep%.4g$sep%.4g", @{$_[0]} }
}

property_type RGB {

   method construct(HSV) : c++;
}

# @category Visualization
# Create a composite drawing of several objects.
# @param Visual::Object vis_obj one or more objects to be drawn together
# @option String Title name of the whole drawing; per default the name of the first Object is taken.
# @option any decorations to be applied to all components as default values.
# @return Visual::Container if called in void context, immediately starts the preferred rendering program.

user_function compose(Visual::Object+ %) {
   my $decor=pop;
   visualize(new Visual::Container(Title => defined(delete $decor->{Title} || $_[0]->Title || $_[0]->Name),
				   defaults => $decor, @_));
}

# @category Visualization
# Add new objects to a composite drawing.
# @param Visual::Container vis_container drawing produced by some visualization function
# @param Visual::Object vis_obj one or more objects to be added
# @option String Title  new name for the drawing
# @option any decorations  to be applied to all components as default values.
# @return Visual::Container if called in void context, immediately starts the preferred rendering program.

user_function compose(Visual::Container Visual::Object+ %) {
   my $container=shift;
   my $decor=pop;
   if (defined (my $title=delete $decor->{Title})) {
      $container->Title=$title;
   }
   push %{$container->defaults}, %$decor if keys %$decor;
   push @{$container->elements}, @_;
   visualize($container);
}

function bounding_box(Visual::Interactive) {
   my $emb=shift;
   my $dummy=@$emb;	# enforce computations
   bounding_box($emb->coord);
}

sub enforce_static_coord {
   my ($vis, $attr)=@_;
   my $dummy=@{$vis->$attr};
}

function enforce_static(Visual::Object) { }

function enforce_static(Visual::Container) {
   my $c=shift;
   foreach my $vis (@{$c->elements}) {
      enforce_static($vis);
   }
}

function enforce_static(Visual::PointSet) {
   enforce_static_coord($_[0], "Vertices");
}

function enforce_static($) {
   croak( "don't know how to disable dynamic coordinates in ", (ref($_[0]) || "'$_[0]'") ) unless is_ARRAY($_[0]);
   foreach (@{$_[0]}) {
      enforce_static($_);
   }
}

# @category Visualization
# Suppress creation of dynamic (interactive) scenes.
# @param Visual::Object vis_obj drawing, e.g. created by ''VISUAL_GRAPH'' or ''SCHLEGEL''.
# @return Visual::Object if called in void context, immediately starts the preferred rendering program.

user_function static(Visual::Object) {
   enforce_static($_[0]);
   visualize($_[0]);
}

# Local Variables:
# mode: perl
# c-basic-offset:3
# End:
