# -*- perl -*-
#
# $Id: LinuxAPM.pm,v 1.6 1999/01/09 14:23:57 ejb Exp $
# $Source: /home/ejb/source/perl/modules/RCS/LinuxAPM.pm,v $
# $Author: ejb $
#

require 5.002;
use strict;

package LinuxAPM;
my $package = "LinuxAPM";

# Field names
my $f_verbose = "verbose";
my $f_bios_version = "bios_version";
my $f_apm_flags = "apm_flags";
my $f_ac_line_status = "ac_line_status";
my $f_battery_status = "battery_status";
my $f_battery_flag = "battery_flag";
my $f_percent_charge = "percent_charge";
my $f_battery_time = "battery_time";
my $f_unit = "unit";

# Static Variables
my $desired_proc_apm_version = "1.\\d+";
my $apm_file = "/proc/apm";

# Routines

sub new
{
    my $class = shift;
    my $verbose = 0;
    if (@_)
    {
	$verbose = shift;
    }
    my $rep = +{$package => {} };

    $rep->{$package}{$f_verbose} = $verbose;

    bless $rep, $class;
    $rep->refresh();
}

sub refresh
{
    my $rep = shift;
    
    my $apm = undef;
    open(APM, "<$apm_file") or die "$package: can't read $apm_file: $!\n";
    chop ($apm = scalar(<APM>));
    close(APM);
    defined($apm) or die "$package: unable to get apm information\n";

    my @apm = split(/\s+/, $apm);
    if ($apm[0] !~ m/^$desired_proc_apm_version$/)
    {
	die "$package: unknown apm version ($apm[0]) -- " .
	    "only versions matching $desired_proc_apm_version are known\n";
    }
    my ($junk, $bios_version, $apm_flags, $ac_line_status, $battery_status,
	$battery_flag, $percent_charge, $battery_time, $unit) = @apm;

    $rep->{$package}{$f_bios_version} = $bios_version;
    $rep->{$package}{$f_apm_flags} = $apm_flags;
    $rep->{$package}{$f_ac_line_status} = $ac_line_status;
    $rep->{$package}{$f_battery_status} = $battery_status;
    $rep->{$package}{$f_battery_flag} = $battery_flag;
    $rep->{$package}{$f_percent_charge} = $percent_charge;
    $rep->{$package}{$f_battery_time} = $battery_time;
    $rep->{$package}{$f_unit} = $unit;

    # Return self so that constructors can call refresh as their last
    # statement
    $rep;
}

sub p_verbose
{
    my $rep = shift;
    $rep->{$package}{$f_verbose};
}

sub p_bios_version
{
    my $rep = shift;
    $rep->{$package}{$f_bios_version};
}

sub p_apm_flags
{
    my $rep = shift;
    $rep->{$package}{$f_apm_flags};
}

sub p_ac_line_status
{
    my $rep = shift;
    $rep->{$package}{$f_ac_line_status};
}

sub p_battery_status
{
    my $rep = shift;
    $rep->{$package}{$f_battery_status};
}

sub p_battery_flag
{
    my $rep = shift;
    $rep->{$package}{$f_battery_flag};
}

sub p_percent_charge
{
    my $rep = shift;
    $rep->{$package}{$f_percent_charge};
}

sub p_battery_time
{
    my $rep = shift;
    $rep->{$package}{$f_battery_time};
}

sub p_unit
{
    my $rep = shift;
    $rep->{$package}{$f_unit};
}

sub apm_file
{
    $apm_file;
}

sub percentage
{
    my $rep = shift;
    my $percent_charge = $rep->p_percent_charge();
    $percent_charge =~ s/\%//;
    $percent_charge;
}

sub plugged_in
{
    my $rep = shift;
    my $ac_line_status = oct($rep->p_ac_line_status());
    (($ac_line_status == 1) ? 1 : 0);
}

sub printable_status
{
    my $rep = shift;
    my $result = "";

    my $verbose = $rep->p_verbose();
    my $bios_version = $rep->p_bios_version();
    my $apm_flags = $rep->p_apm_flags();
    my $ac_line_status = $rep->p_ac_line_status();
    my $battery_status = $rep->p_battery_status();
    my $battery_flag = $rep->p_battery_flag();
    my $percent_charge = $rep->p_percent_charge();
    my $battery_time = $rep->p_battery_time();
    my $unit = $rep->p_unit();

    $result .= "APM BIOS version: $bios_version\n" if $verbose;
    # XXX APM FLAGS
    $result .= "APM flags: $apm_flags\n" if $verbose;
    $ac_line_status = oct($ac_line_status);
    my $ac = (($ac_line_status == 0) ? "off-line" :
	      ($ac_line_status == 1) ? "on-line" :
	      ($ac_line_status == 2) ? "on backup power" :
	      "unknown");
    $result .= "AC power is $ac\n";
    $battery_flag = oct($battery_flag);
    $result .= "Battery charge is high\n" if $battery_flag & (1 << 0);
    $result .= "Battery charge is low\n" if $battery_flag & (1 << 1);
    $result .= "\aBattery charge is critical\n" if $battery_flag & (1 << 2);
    $result .= "Battery is charging\n" if $battery_flag & (1 << 3);
    $result .= "Battery is not present\n" if $battery_flag & (1 << 7);
    $result .= "Battery charge level: $percent_charge\n";
    if ($battery_time != -1)
    {
	$result .= "Battery life remaining: $battery_time $unit\n";
    }

    $result;
}

1;

#
# END OF LinuxAPM
#
