#!/usr/bin/perl -w

# Quick hack to get a battery status display.
# Uses Pedro Venda's modified version of Bruno Ducrot's version
# of the smart battery reader (not included).
#
# Copyright 2005 Johan Vromans, Squirrel Consultancy.
#
# 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 of the License, or
# (at your option) any later version.

use strict;
use Tk;
use Tk::ProgressBar;

################ Configuration ################

my $interval = 10;		# Poll interval
my $prog = "smartbattery2 0";	# command

# Regular output of $prog is:
#
#	status:			discharging	initialized
#	mode:			capacity in 10 mW/mWh
#	design voltage:		14800 mV
#	design charge capacity:	4400 mAh or mWh
#	absolute charge:	90%
#	full charge capacity:	4270 mAh or mWh
#	relative charge:	93%
#	current:		-908 mA
#	voltage:		16271 mV
#	remain:			3966 mA
#	average time to empty:	261 minutes
#	average time to full:	65535 minutes
#	temperature:		24.2 C
#	cycle count:		12

################ End Configuration ################

my $status = 0;

my $mw = MainWindow->new;
$mw->title("Battery: Starting");

my $p = $mw->ProgressBar
  (-troughcolor => 'LightSkyBlue3',
   -borderwidth => 0,
   -length => 120,
   -width => 8,
   -variable => \$status,
   -colors => [0 => 'red', 10 => 'yellow', 20 => 'green'],
   #	 -blocks => 10,		# default
   -anchor => 'w',
   -from => 0,
   -to => 100,
  )->pack(-expand => 1);

# Check every 10 seconds.
$mw->repeat (10000, \&update);

my $state = 0;
update();

MainLoop;

sub update {

    my $res = `smartbattery2 $smbus 2>&1`;
    return unless $res;

    my ($current, $fill, $time, $tp);
    $current = $1 if $res =~ /current:\s+(-?\d+)\s+ma/i;
    $tp = $current < 0 ? 'empty' : 'full';
    $fill = $1    if $res =~ /relative charge:\s+(\d+)%/i;
    $time = $1    if $res =~ /average time to $tp:\s+(\d+)\s+minutes/i;
    if ( $time ) {
	my ($h, $m);
	$h = int($time / 60);
	$m = $time % 60;
	$time = sprintf("%d:%02d", $h, $m);
    }

    if ( $current > 0 ) {	# charging
	$status = 0;
    }
    elsif ( $current < 0 ) {	# discharging
	$status = $fill;
    }
    else {			# fully charged
	$status = 100;
    }
    $mw->title("Battery: $time ($status%)");

    # This is a kludge to get the ProgressBar to display uniform, but
    # different colours depending on the fill status.

    if ( $status >= 30 ) {
	if ( $state < 30 ) {
	    $p->{Configure}{-colors} = [ 0, 'green' ];
	    $p->{Configure}{-troughcolor} = 'darkgreen';
	    Tk::ProgressBar::_layoutRequest($p, 1);
	    $state = 30;
	}
    }
    elsif ( $status >= 10 ) {
	if ( $state < 10 || $state >= 30 ) {
	    $p->{Configure}{-colors} = [ 0, 'yellow' ];
	    $p->{Configure}{-troughcolor} = 'orange';
	    Tk::ProgressBar::_layoutRequest($p, 1);
	    $state = 10;
	}
    }
    elsif ( $state >= 10 ) {
	$p->{Configure}{-colors} = [ 0, 'red' ];
	$p->{Configure}{-troughcolor} = 'darkred';
	Tk::ProgressBar::_layoutRequest($p, 1);
	$state = 0;
    }
}
