#  Copyright (c) 1997-2004
#  Ewgenij Gawrilow, Michael Joswig (Technische Universitaet Berlin, Germany)
#  http://www.math.tu-berlin.de/polymake,  mailto:polymake@math.tu-berlin.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: VisualPolygon.pm,v 1.8 2004/10/26 19:00:06 gawrilow Exp $

###############################################################################
#
#  Visual::PointSet  - a cloud of points
#

package Visual::PointSet;

use Struct (
   [ '@ISA' => 'Visual::Object' ],

   # [ "coord vector", ... ]
   [ '@Vertices | Points' => 'check_points( #% )', 'croak("Points missing")' ],

   # ambient dimension (detected by Points)
   '$Dim',

   #    "string sting ..."	to be split on the white spaces
   # or [ "string", ... ]
   # or "hidden"		suppress any labels
   #    default: point indices (0,1,...) as labels
   [ '$VertexLabels | PointLabels' => 'unify_labels( #% )', 'undef' ],

   #    "R G B"			same color for all points
   # or [ "R G B", ... ]	indexed by point number
   # or { number => "R G B" }	keyed by point number
   # or sub { }			point number -> "R G B"
   [ '$VertexColor | PointColor' => 'unify_decor( #% )', '$Visual::Color::vertices' ],

   #  the same formats as for PointColor
   #  recognized values:
   #    "thickness N"		diameter of circles representing the points
   #    "hidden"		draw neither circles nor point labels
   [ '$VertexStyle | PointStyle' => 'unify_decor( #% )' ],

   # boolean: don't show this object at the session start (only makes sense for interactive viewers)
   '$Hidden',
);

sub new {
   my $self=&_new;
   $self->Dim ||= dim($self->Points);
   $self;
}

declare %decorations=( PointLabels => enum('hidden'), VertexLabels => enum('hidden') );
@decorations{qw( Name PointColor PointStyle VertexColor VertexStyle Hidden )}=();

###############################################################################
#
#  Visual::Polygon  - a flat polygon embedded in R^2 or R^3
#

package Visual::Polygon;

use Struct (
   [ '@ISA' => 'Visual::PointSet' ],
   [ '@Vertices' => 'check_points( #% )' ],

   [ '$VertexStyle' => 'unify_decor( #% )' ],
   #  { index ... }	if this Polygon shares the vertices with other visual objects
   #			OR the proper cyclic drawing order of Vertices
   '$Facet',

   #  "R G B"		to fill the inner area
   [ '$FacetColor' => '$Visual::Color::facets' ],

   #  "hidden"		if the inner area must be transparent
   '$FacetStyle',

   #  "R G B"                the facet borders
   '$EdgeColor',

   #  "thickness N | hidden"
   '$EdgeStyle',
);

sub new {
   my $self=&Visual::PointSet::new;
   if (!$self->Facet && !@{$self->Vertices}) {
      croak("Vertices or Facet must be given");
   }
   $self;
}

declare %decorations=%Visual::PointSet::decorations;
@decorations{qw( FacetColor FacetStyle EdgeColor EdgeStyle )}=();

###############################################################################
#
#  Visual::Polygons - a collection of Visual::Polygon objects sharing the same vertex set
#                     and making up a single geometric object
#		      (this makes a difference for some visualizers, esp. javaview.)

package Visual::Polygons;

use Struct (
   [ '@ISA' => 'Visual::Polygon' ],
   [ new => '$%' ],

   # the same as VertexColor
   [ '$FacetColor' => 'unify_decor( #% )' ],

   # the same as VertexStyle (excluding thickness)
   [ '$FacetStyle' => 'unify_decor( #% )' ],

   [ '@Polygons' => '#1' ],
);

#
#  Constructor parameters:
#  Attibute => value, ... , Visual::Polygon, ...
#
#  The leading attributes apply to all contained Polygons.
#  The rest of the argument list must be Visual::Polygon objects.
#

my %common_decor=( FacetColor => $Visual::Color::facets,
		   FacetStyle => undef,
		   EdgeColor => "0 0 0",
		   EdgeStyle => undef );
sub new {
   my (%diff_decor);
   for (my $i=$#_; $i>0; --$i) {
      if (is_object($_[$i]) && $_[$i]->isa("Visual::Polygon")) {
	 foreach my $decor (keys %common_decor) {
	    $diff_decor{$decor} ||= $_[$i]->$decor;
	 }
      } else {
	 splice @_, 1, 0, [ splice @_, $i+1 ];
	 last;
      }
   }
   my $self=&Visual::PointSet::new;
   while (my ($decor, $default)=each %common_decor) {
      if ($diff_decor{$decor} && !$self->$decor) {
	 $self->$decor=sub { $self->Polygons->[$_[0]]->$decor || $default };
      }
   }
   $self;
}

1

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