#!/usr/bin/perl -w

use strict;
use Tk;
use Tk::Canvas;
use Getopt::Std;
use Math::Trig;
use lib ('../Vector2D');
use lib ('../Triangul');
use lib ('../Viewport');
use Vector2D;
use Triangul;
use Viewport;
use constant EPS => 1e-6;

my $width = 500;
my $height = 500;
my $background = 'blue';
my $fill = 'yellow';
my %opts = ();
getopts( 'w:h:b:f:', \%opts );
if( $opts{w} ) { $width = $opts{w} ; }
if( $opts{h} ) { $height = $opts{h} ; }
if( $opts{b} ) { $background = $opts{b} ; }
if( $opts{f} ) { $fill = $opts{f} ; }

my $vp = new Viewport();
my $pidiv180 = atan(1)/45;
my $top 	= MainWindow->new();
my $frame 	= $top->Frame();
my $can = $top->Canvas( -width => $width, -height=> $height, -background=>$background );
my $x_max 	= $width;
my $y_max 	= $height;
my $x_min 	= 5;
my $y_min 	= 5;
my $x_center 	= $can->reqwidth()/2.0;
my $y_center 	= $can->reqheight()/2.0;
my $r_max 	= $can->reqwidth()/2;

$can->packAdjust( -side => 'left', -fill => 'both', -delay => 1 );
$frame->pack( -side 	=> 'left', -fill 	=> 'y', -expand => 'y', -anchor => 'w' );

my $doButton = $frame->Button( 
	-relief 	=> "groove", 
	-text 		=> "Draw", 
	-command	=> \&doit  )->pack(  anchor => 'w' );

my $clearButton = $frame->Button( 
	-relief 	=> "groove", 
	-text 		=> "Clear", 
	-command	=> \&clear  )->form( 
	-left => [$doButton,0] );

my @p = (); # array of Vector2Ds
my $i = 0;
my $n = <>;
my @nrspol = ( 0..$n-1 );
my @nrs = ();
while(<>) {
	chomp;
	my ( $x, $y ) = split /,/;
	push ( @p, new Vector2D( $x, $y ) );
	$vp->updatewindowboundaries( $x, $y );
}
$vp->viewportboundaries ( $x_min, $x_max, $y_min, $y_max, 0.9 );
$can->create ( 'line', $x_min, $y_min, $x_min, $y_max );
$can->create ( 'line', $x_min, $y_max, $x_max, $y_max );
$can->create ( 'line', $x_max, $y_max, $x_max, $y_min );
$can->create ( 'line', $x_max, $y_min, $x_min, $y_min );
my $rc = &Triangul::triangul ( \@nrspol, $n, \@nrs, \&orienta, \@p );

if( $rc == -1 ) { die "Bad poly\n"; }
if( $rc == -2 ) { die "out of mem\n"; }
&drawPoly ( @p );

&drawTriangles( \@p, \@nrs, $rc );


MainLoop;

sub drawPoly {
	my @p = @_; #Array of  Vector2Ds

	my $start_point = pop( @p );
	my $first_point = $start_point;
	while( my $end_point = pop( @p ) ) {
		$can->create( 'line', 
			$vp->x_viewport($start_point->getx()),
			$vp->y_viewport($start_point->gety()),
			$vp->x_viewport($end_point->getx()),
			$vp->y_viewport($end_point->gety()),
			-fill => $fill);
		$start_point = $end_point;
	}
#	$can->create( 'line', 
#		$vp->x_viewport($first_point->getx()),
#		$vp->y_viewport($first_point->gety()),
#		$vp->x_viewport($start_point->getx()),
#		$vp->y_viewport($start_point->gety()),
#		-fill => $fill);
#	
} #end drawPoly


sub drawTriangles {
	my $refp    	= shift; #ref to an array
	my $refnrs  	= shift; #ref to an array
	my $m   	= shift; #scalar

	my @p 	= @$refp;
	my @nrs = @$refnrs;

	my $Centroid = new Vector2D( 0, 0 );
	# my $A  = new Vector2D( 0, 0 );
	# my $B  = new Vector2D( 0, 0 );
	# my $C  = new Vector2D( 0, 0 );
	my $A1 = new Vector2D( 0, 0 );
	my $B1 = new Vector2D( 0, 0 );
	my $C1 = new Vector2D( 0, 0 );
	for( my $j=0; $j<$m; $j++ ) {
		my $A = $p[$nrs[$j]->{A}];
		my $B = $p[$nrs[$j]->{B}];
		my $C = $p[$nrs[$j]->{C}];
		$Centroid = 0.3333333 * ( $A + $B + $C );
		$A1 = $Centroid + 0.9 * ( $A - $Centroid );
		$B1 = $Centroid + 0.9 * ( $B - $Centroid );
		$C1 = $Centroid + 0.9 * ( $C - $Centroid );
		$can->create( 'line' ,
			$vp->x_viewport($A1->getx()), $vp->y_viewport($A1->gety()),
			$vp->x_viewport($B1->getx()), $vp->y_viewport($B1->gety()),
			-fill => 'red');
			#-fill => $fill);
		$can->create( 'line' ,
			$vp->x_viewport($B1->getx()), $vp->y_viewport($B1->gety()),
			$vp->x_viewport($C1->getx()), $vp->y_viewport($C1->gety()),
			-fill => 'red');
			#-fill => $fill);
		$can->create( 'line' ,
			$vp->x_viewport($C1->getx()), $vp->y_viewport($C1->gety()),
			$vp->x_viewport($A1->getx()), $vp->y_viewport($A1->gety()),
			-fill => 'red');
			#-fill => $fill);
	}
} #end drawTriangles

sub orienta {
	my ( $Pnr, $Qnr, $Rnr, $PP ) = @_;
	my $A = new Vector2D( 0, 0 );
	my $B = new Vector2D( 0, 0 );
	$A = $PP->[$Qnr]->minus( $PP->[$Pnr] );
	$B = $PP->[$Rnr] - $PP->[$Pnr];
	my $determinant = $A->getx() * $B->gety() - $A->gety() * $B->getx();
	if ($determinant < (-1 * EPS) ) { return -1; }
	if ($determinant > EPS ) { return 1; }
	if ($determinant < EPS ) { return 0; }
	return 0;
}
