#!/usr/bin/env python
#
# $Id: battery.py,v 1.3 2003/06/11 11:31:26 resolve Exp $
#
# Time-stamp: <2002-12-30 16:05:01 resolve>
#
# Copyright (C) Damien Elmes <resolve@repose.cx>, 2001.
# This file is licensed under the GPL. Please see COPYING for more details.
#


"""
Display a pyosd-based graph of how much of the battery has been used.
"""

threshold_warn = 11
threshold_shutdown = 9

import commands
import os
import re
import string
import pyosd, pyosd.daemon as pyd

class BatteryStatus:

    def __init__(self, battery=None):
        """The battery argument can be used to specify a particular battery to
        use, otherwise the first one will be."""
        self.data = {}

        ACPI_PROC_DIR = "/proc/acpi/battery/"

        if not battery:
            try:
                files = os.listdir(ACPI_PROC_DIR)
            except OSError:
                raise "Couldn't open dir: %s" % ACPI_PROC_DIR
            if not files:
                raise "No battery appears to be present"

            battery = files[0]

        try:
            self.file = open(ACPI_PROC_DIR + os.sep + battery + os.sep +
                          "state")
        except:
            raise "Couldn't open specified battery info: %s" % \
                  ACPI_PROC_DIR + os.sep + battery + \
                  os.sep + "state"

        self.total_capacity = 3736.0

    def check(self, battery=None):
        """Check and return battery status"""

        self.file.seek(0)
        lines = self.file.readlines()

        for line in lines:
            (id, val) = string.split(line, ":", maxsplit=1)
            self.data[id] = string.strip(val)

        self.remaining_capacity = int(string.split(self.data['remaining capacity'])[0])
        self.percent_used = (self.remaining_capacity / self.total_capacity * 100.0 )

    def __repr__(self):
        return `self.data`

class plugin:

    def __init__(self):
        self.plugin_name = "battery"
        self.plugin_desc = "Display ACPI battery status"
        self.plugin_keys = ["bat"]

        self.batstat = BatteryStatus()
        self.increment = 100

        self.check_battery()

    def check_battery(self):
        """Check battery status and warn when it reaches a certain level"""

        self.batstat.check()

        if self.batstat.data['charging state'] == 'discharging':
            # if the battery is dischanging, check we're not running out of
            # power

            if self.batstat.percent_used < threshold_shutdown:
                pyd.top.set_timeout(-1)
                pyd.top.display("Critical! Battery at less than 7%" +
                                " - shutting down")
                os.system("sync")
                os.system("sudo halt")
                return

            if self.batstat.percent_used < threshold_warn:
                pyd.top.set_timeout(-1)
                pyd.top.display("Alert! Battery at less than 10%")

            if self.batstat.percent_used < self.increment:
                self.bat()
                self.increment = self.batstat.percent_used - 5
        else:
            pyd.top.set_timeout(3)
            self.increment = 100

        pyd.reactor.callLater(30, self.check_battery)

    def bat(self, *args):
        """Display battery info"""

        self.batstat.check()

        if self.batstat.data['charging state'] == 'unknown':
            state = "On A/C power."
        else:
            state = self.batstat.data['charging state']

        state = state + " (at %d%%)" % self.batstat.percent_used

        pyd.top.set_colour("#bbbbFF")
        pyd.top.set_timeout(3)
        pyd.top.display(state)
        pyd.top.display(self.batstat.percent_used, type=pyosd.TYPE_PERCENT, line=1)

