package AA::Vertex;

our @ISA = ('AA');

sub new($$) {
	my ($class, $id) = @_;
	my $v = AA::new($class, $id);
	$v->DefSet('x', 100);
	$v->DefSet('y', 100);
	$v->DefSet('color', [ 0.7, 0, 0.7 ]);
	$v->DefSet('gradient', 0.5);
	$v->DefSet('r', 30);
	$v->DefSet('rim', 2);
	$v->DefSet('rim-color', [ 1, 1, 1 ]);
	$v->Define('label');
	$v->DefSet('label-color', [ 1, 1, 1 ]);
	$v->DefSet('label-size', 1.5);
	$v->DefSet('d', 20);
	return $v;
}

sub Draw($$) {
	my ($v, $cairo) = @_;
	my ($x, $y, $r) = ($v->Get('x'), $v->Get('y'), $v->Get('r'));
	my $grad = $v->Get('gradient');
	my @col = @{$v->Get('color')};

	$cairo->arc($x, $y, $r, 0, $AA::TWOPI);
	if ($grad) {
		my $lg = Cairo::RadialGradient->create($x, $y, 0, $x, $y, $r);
		$lg->add_color_stop_rgb(0, @col);
		$col[0] *= $grad;
		$col[1] *= $grad;
		$col[2] *= $grad;
		$lg->add_color_stop_rgb(1, @col);
		$cairo->set_source($lg);
	} else {
		$cairo->set_source_rgb(@col);
	}
	$cairo->fill;

	$cairo->arc($x, $y, $r, 0, $AA::TWOPI);
	$cairo->set_source_rgb(@{$v->Get('rim-color')});
	$cairo->set_line_width($v->Get('rim'));
	$cairo->stroke;

	if ($v->Exists('label')) {
		my $label = $v->Get('label');
		$cairo->set_source_rgb(@{$v->Get('label-color')});
		$cairo->set_font_size($r * $v->Get('label-size'));
		my $xt = $cairo->text_extents($label);
		$cairo->move_to($x - $xt->{'width'}/2 - $xt->{'x_bearing'},
				$y - $xt->{'height'}/2 - $xt->{'y_bearing'});
		$cairo->show_text($label);
	}
}

package AA::Edge;

our @ISA = ('AA');

sub new($$$$) {
	my ($class, $id, $v, $w) = @_;
	my $e = AA::new($class, $id);
	$e->DefSet('color', [1, 1, 1]);
	$e->DefSet('width', 3);
	$e->DefSet('arrow', 0);
	$e->DefSet('arrow-dist', 20);
	$e->DefSet('arrow-span', 6);
	$e->DefBind('ends', sub {
		my $x1 = $v->Get('x');
		my $y1 = $v->Get('y');
		my $r1 = $v->Get('r');
		my $x2 = $w->Get('x');
		my $y2 = $w->Get('y');
		my $r2 = $w->Get('r');
		my $dx = $x2 - $x1;
		my $dy = $y2 - $y1;
		my $d = sqrt($dx*$dx + $dy*$dy);
		$x1 += $dx * $r1/$d;
		$y1 += $dy * $r1/$d;
		$x2 -= $dx * $r2/$d;
		$y2 -= $dy * $r2/$d;
		return [ $x1, $y1, $x2, $y2 ];
	});
	$e->DefBind('apos', sub {
		my $type = $e->Get('arrow') or return undef;
		my $span = $e->Get('arrow-span');
		my $dist = $e->Get('arrow-dist');
		my ($x1, $y1, $x2, $y2) = @{$e->Get('ends')};
		my $dx = $x2 - $x1;
		my $dy = $y2 - $y1;
		my $d = sqrt($dx*$dx + $dy*$dy);
		my $ax = $x2 - $dx * $dist/$d;
		my $ay = $y2 - $dy * $dist/$d;
		my $adx = -$dy;
		my $ady = $dx;
		($adx, $ady) = ($adx * $span/$d, $ady * $span/$d);
		return [ $ax+$adx, $ay+$ady,
			 $ax-$adx, $ay-$ady ];
	});
	$e->DefSet('d', 10);
	return $e;
}

sub Draw($$) {
	my ($v, $cairo) = @_;

	my ($x1, $y1, $x2, $y2) = @{$v->Get('ends')};
	$cairo->set_source_rgb(@{$v->Get('color')});

	$cairo->move_to($x1, $y1);
	$cairo->line_to($x2, $y2);
	$cairo->set_line_width($v->Get('width'));
	$cairo->stroke;

	if ($v->Get('arrow')) {
		my ($ax1, $ay1, $ax2, $ay2) = @{$v->Get('apos')};
		$cairo->move_to($x2, $y2);
		$cairo->line_to($ax1, $ay1);
		$cairo->line_to($ax2, $ay2);
		$cairo->close_path;
		$cairo->fill;
	}
}

1;
