#!/usr/bin/perl

use strict;
use warnings;

use Gtk2 -init;
use Cairo;

my $area = Gtk2::DrawingArea->new();
my $cairo;
my $PI = 3.1415926535;
my $TWOPI = 2*$PI;

my $rad = 30;
my $rim = 2;
my $arrow_dist = 10;
my $arrow_span = 5;

sub draw_vertex($$) {
	my ($x, $y) = @_;

	my $lg = Cairo::RadialGradient->create($x, $y, 0, $x, $y, $rad);
	$lg->add_color_stop_rgb(0, 0.7, 0, 0.7);
	$lg->add_color_stop_rgb(1, 0.3, 0, 0.3);

	$cairo->arc($x, $y, $rad, 0, $TWOPI);
	$cairo->set_source($lg);
	$cairo->fill;

	$cairo->arc($x, $y, $rad, 0, $TWOPI);
	$cairo->set_source_rgb(1, 1, 1);
	$cairo->set_line_width($rim);
	$cairo->stroke;

	$cairo->set_font_size(0.6*$rad);
	my $xt = $cairo->text_extents('Brum');
	$cairo->move_to($x - $xt->{'width'}/2 - $xt->{'x_bearing'},
			$y - $xt->{'height'}/2 - $xt->{'y_bearing'});
	$cairo->show_text("Brum");
}

sub draw_edge($$$$) {
	my ($x1, $y1, $x2, $y2) = @_;
	my $dx = $x2 - $x1;
	my $dy = $y2 - $y1;
	my $d = sqrt($dx*$dx + $dy*$dy);

	$x1 += $dx * $rad/$d;
	$y1 += $dy * $rad/$d;
	$x2 -= $dx * $rad/$d;
	$y2 -= $dy * $rad/$d;

	$cairo->set_source_rgb(1, 1, 1);

	$cairo->move_to($x1, $y1);
	$cairo->line_to($x2, $y2);
	$cairo->set_line_width(2);
	$cairo->stroke;

	my $ax = $x2 - $dx * $arrow_dist/$d;
	my $ay = $y2 - $dy * $arrow_dist/$d;
	my $adx = -$dy;
	my $ady = $dx;
	($adx, $ady) = ($adx * $arrow_span/$d, $ady * $arrow_span/$d);
	$cairo->move_to($x2, $y2);
	$cairo->line_to($ax+$adx, $ay+$ady);
	$cairo->line_to($ax-$adx, $ay-$ady);
	$cairo->close_path;
	$cairo->fill;
}

my $xx=0;
my $pixmap;
my ($lastw, $lasth, $lastd) = (-1, -1, -1);
my ($pixw, $pixh) = (-1, -1);
sub draw($) {
	my ($force) = @_;
	my $win = $area->window;
	my $wgc = Gtk2::Gdk::GC->new($win);
	my $alloc = $area->allocation;
	my $w = $alloc->width;
	my $h = $alloc->height;
	my $d = $win->get_depth;
	# print "Area $w x $h x $d, xx=$xx\n";

	if (!defined($pixmap) || $lastw != $w || $lasth != $h || $lastd != $d) {
		($lastw, $lasth, $lastd) = ($w, $h, $d);
		if ($w/$h >= 4/3) {
			$pixh = $h;
			$pixw = int($h/3*4);
		} else {
			$pixw = $w;
			$pixh = int($w/4*3);
		}
		print "Resized to ${w}x${h}, pixmap size ${pixw}x${pixh}\n";

		$pixmap = Gtk2::Gdk::Pixmap->new($win, $pixw, $pixh, $d);
		$cairo = Gtk2::Gdk::Cairo::Context->create($pixmap);
		$cairo->select_font_face('URW Palladio L', 'normal', 'normal');
		my $scale = $pixw/1024;
		$cairo->scale($scale, $scale);
	}

	if ($force) {
		$wgc->set_rgb_background(0);
		$wgc->set_rgb_foreground(0);
		$win->draw_rectangle($wgc, 1, 0, 0, $w, $h);
	}

	$cairo->rectangle(0, 0, 1024, 768);
	$cairo->set_source_rgb(0, 0, 0);
	$cairo->fill;

	my @v = ();
	for (my $i=0; $i<6; $i++) {
		my $a = $TWOPI/6 * $i + $TWOPI/400*$xx;
		my $x = int(1024/2 + 300*cos($a));
		my $y = int(768/2 + 300*sin($a));
		draw_vertex($x, $y);
		push @v, { 'x' => $x, 'y' => $y };
	}

	for (my $i=1; $i<6; $i++) {
		for (my $j=0; $j<$i; $j++) {
			my $v = $v[$i];
			my $w = $v[$j];
			draw_edge($v->{'x'}, $v->{'y'}, $w->{'x'}, $w->{'y'});
		}
	}

	$win->draw_drawable($wgc, $pixmap, 0, 0, 0, 0, $pixw, $pixh);
}

sub step() {
	draw(0);
	$xx++;
}

my $timer;
my $stopped = 0;
$area->signal_connect("expose-event" => sub {
	draw(1);
	if (!defined $timer) {
		$timer = Glib::Timeout->add(30, sub { $stopped || step(); return 1; });
	}
});
$area->set_flags('can-focus');
# $area->add_events('key-press-mask');
$area->signal_connect('key-press-event' => sub {
	my ($w, $evt) = @_;
	my $k = Gtk2::Gdk::keyval_name(0, $evt->keyval);
	print "Pressed key $k\n";
	if ($k eq "Escape") {
		Gtk2->main_quit;
	} elsif ($k eq "space") {
		$stopped = !$stopped;
	}
});

my $window = Gtk2::Window->new ('toplevel');
$window->signal_connect ("delete-event" => sub { Gtk2->main_quit });
$window->set_title("Brum");
$window->set_wmclass("anim", "Anim");
$window->set_default_size(640, 480);
$window->add ($area);
$window->show_all;
#$window->fullscreen;

Gtk2->main;
