#! /usr/bin/perl -w
#
# MiKael
# 2007-05-21

use strict;

use POSIX qw(strftime);
use Time::Local;

my $maxbat = 0;
my $cmpt = 0;

sub load() {
    open(IN, "< /proc/loadavg") or return "";
    my $l = <IN>;
    close(IN);
    $l =~ /^((\d\.\d\d ){2}(\d\.\d\d)) /;
    return $1;
}

sub temperature() {
    open(IN, "< /proc/acpi/thermal_zone/THM/temperature") or return "";
    my $l = <IN>;
    close(IN);
    $l =~ /^temperature:\s+(\d+) C$/;
    return $1."°";
}

sub acpi() {
    my $cur = -1;
    my $l;
    my $msg = " ";
    my $v;

    if ($cmpt++ % 60 == 0 || $maxbat == 0) {
        # Read the battery's maximum capacity
        open(IN, "< /proc/acpi/battery/BAT0/info") or return "";
        while ($l = <IN>) {
            if ($l =~ /^last full capacity:\s*(\d+) mAh/) {
                $maxbat = $1;
                last;
            }
        }
        close(IN);
    }
    return ""  if ($maxbat == 0);

    # Read the remaining capacity and charging state
    open(IN, "< /proc/acpi/battery/BAT0/state") or return "";
    while ($l = <IN>) {
        if ($l =~ /^charging state:\s*(\w+)/) {
            if ($1 eq "discharging") {
                $msg = "-";
            } elsif ($1 eq "charging") {
                $msg = "+";
            }
        } elsif ($l =~ /^remaining capacity:\s*(\d+) mAh/) {
            $cur = $1;
            last; # Charging state is given before capacity, usually
        }
    }
    close(IN);
    return $msg  if ($cur == -1);
    $v = int($cur*100/$maxbat);
    return $msg.($v > 100 ? 100 : $v)."%";
}

sub date() {
    return strftime("%a %d %b %R", localtime());
}

# Autoflush stdout...
$| = 1;

my $status;

# Main loop
while (1) {
    $status = acpi();
    $status .= "  ".temperature();
    $status .= "  [".load()."]";
    $status .= " - ".date();

    $status =~ s/^\s+//;
    print $status, "\n";
    sleep 2;
}