#!/usr/bin/perl
#Versjon 0.1.1

#use-stuff
use Gtk2 '-init';
use Gtk2::Helper;
use strict;
use FileHandle;
use Data::Dumper;  # for debugging purposes

#Definering av ting..

my $logfile = "/var/log/emerge.log";
my @package_list;
my $lastline;
my $status;
my $tag;
my @cols = (
	{ title => 'Name',	type => 'Glib::String',	},
	{ title => 'Date',	type => 'Glib::String',	},
	{ title => 'Status',	type => 'Glib::String',	},
);

#initsialisere ting..
my $store = Gtk2::ListStore->new( map {$_->{type}} @cols );
my $window = Gtk2::Window->new;
my $vbox = Gtk2::VBox->new;
my $sw = Gtk2::ScrolledWindow->new(undef, undef);
my $progressbar = Gtk2::ProgressBar->new;
my $buttonbox = Gtk2::HButtonBox->new;
my $exitbutton = Gtk2::Button->new("Lukk");
my $treeview = Gtk2::TreeView->new_with_model($store);
my $progressbar_timer = Glib::Timeout->add(100, \&update_progress_bar);

#sette parametre..
$window->set_default_size(600,400);
$window->set_title("Emerge Progress");
$sw->set_policy('automatic','automatic');
$buttonbox->set_layout_default("end");
$buttonbox->set_spacing_default(12);
$progressbar->set_pulse_step("0.2");
$exitbutton->signal_connect(clicked => sub { Gtk2->main_quit; });
$window->signal_connect(destroy => sub { Gtk2->main_quit; });

#vis ting..
$buttonbox->pack_start($exitbutton,0,0,0);
$vbox->pack_start($progressbar,0,0,0);
$window->add($vbox);
$window->show_all();
#Start programmet..
Gtk2->main;

sub sett_opp
{
	$sw->add($treeview);
	$vbox->pack_start($sw,1,1,0);
	$vbox->pack_end($buttonbox,0,0,0);
	$window->show_all;
	&sett_opp_kolonner;
	&parselog("emerge");
	my $timer = Glib::Timeout->add(10000, &test);
	&test;
}

sub sett_opp_kolonner
{
	my $renderer;
	my $i = 0;
	foreach (@cols)
	{
		$renderer = Gtk2::CellRendererText->new;
		$renderer->signal_connect (edited => sub {
			my ($cell, $text_path, $new_text, $store) = @_;
			my $path = Gtk2::TreePath->new_from_string ($text_path);
			my $iter = $store->get_iter ($path);
			$store->set ($iter, 2, $text_path);
		}, $store);
		my $column = Gtk2::TreeViewColumn->new_with_attributes(
			$_->{title}, $renderer, text => $i );
		$treeview->append_column($column);
		$i++;
	}
	return 1;
}

sub parselog
{
	my $fh = FileHandle->new;
	$lastline = `tail -n1 $logfile`;
	chomp($lastline);
	if($_[0] eq 'emerge')
	{
		open($fh, q^tail -n100 "/var/log/emerge.log" | grep ">>> emerge"|^) or &error;
	}
	
	$tag = Gtk2::Helper->add_watch ( $fh->fileno, 'in', sub
	{
		watcher_callback( $fh, $tag );
	});
	return 1;
}

sub watcher_callback
{
	my ( $fh, $tag) = @_;
	
	if ( eof($fh))
	{
		Gtk2::Helper->remove_watch ($tag) or &error;
		close($fh);
		return 1;
	}
	
	my $line = <$fh>;
	my $time = (split /:/, $line)[0];
	my $package = (split /\//, $line)[1];
	$package = (split /\ /, $package)[0];
	my $package_group = (split/\//, $line)[0];
	$package_group = (split /\ /, $package_group)[7];

	my $tid = sprintf("%d",$time);
	$tid = gmtime($tid);

	my @data=(
			{ Name => "$package", Time => "$tid", Status => 'unknown' }
	);

	foreach(@data)
	{
		my $iter = $store->append;
		$store->set($iter,
			0, $_->{'Name'},
			1, $_->{'Time'},
			2, $_->{'Status'}
		);
	}
	push(@package_list, int($time));
	push(@package_list, "$package_group");
	push(@package_list, "$package");
	return 1;
}

sub test
{
	my $testline = `tail -n1 $logfile`;
	chomp($testline);
	if($testline eq $lastline)
	{
		my $i = 0;
		my $i2 = 0;
		while($i < scalar(@package_list))
		{
			$status = &status_package($package_list[$i + 2]);
			my $path = Gtk2::TreePath->new_from_string($i2);
			my $iter = $store->get_iter($path);
			$store->set($iter, 2, $status);
			$i++;
			$i++;
			$i++;
			$i2++;
		}
		return 1;
	}
	else
	{
		@package_list = ();
		$store->clear;
		&parselog("emerge");
	}
}

sub status_package
{
	my $test = `tail -n100 $logfile | grep "$_[0]"| tail -n1`;
	my $isdone = (split /:::/, $test)[1];
	if((split / /, $isdone)[1] eq "completed")
	{
		return("completed");
	}
	else
	{
		my $antatt_status = (split / /, $test)[6];
		my $alternativ_status = (split / /, $test)[3];
		if($antatt_status eq "Compiling/Merging")
		{
			my $prosent = &prosent($_[0]);
			if($prosent eq "Ukjent status..")
			{
				return($antatt_status);
			}
			else
			{
				return($prosent);
			}
		}
		else
		{
			return($antatt_status);	
		}
	}

}

sub prosent
{
	my $progress;
	my $total = `find /var/tmp/portage/$_[0] -iname "*.c" -or -iname "*.cpp" -or -iname "*.cc" | wc -l`;
	chomp($total);
	unless($total eq "0")
	{
		$progress = `find /var/tmp/portage/$_[0] -iname "*.o" | wc -l`;
		chomp($progress);
	}
	unless($progress eq "0" || $total eq "0")
	{	
		my $prosent = ($progress / $total * 100);
		$prosent = sprintf("%.2f", $prosent);
		return("$prosent%");
	}
	else
	{
		return("Ukjent status..");
	}
}

sub update_progress_bar
{
	my $percentage = $progressbar->get_fraction;
	if($percentage < 1)
	{
		$progressbar->set_fraction($percentage + 0.1);
		return 1;
	}
	if($percentage == 1)
	{
		my $timer = Glib::Timeout->add(10000, \&test);
		&sett_opp;
		$progressbar->destroy;
		return 0;
	}
}

sub error
{
	print 'Faen i helvete :)',"\n";
	Gtk2->main_quit;
}
