# -*- python -*-

# This is a small example that inverts the colours when the
# battery's capacity is low.


# Copyright © 2014  Mattias Andrée (maandree@member.fsf.org)
# 
# 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 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.



# Invert the colours when the battery capacity is below this threshold.
threshold = 5 # percent


# Current status.
inverted = False

def get_capacity():
    '''
    Get the current capacity and charging status
    
    @return  (:bool, :float)  Whether the battery is discharging and the capacity (in percents)
    '''
    capacity, discharging = None, None
    
    # Get capacity.
    #with open('/sys/class/power_supply/BAT1/capacity', 'r') as file:
    #    capacity = int(file.read().split('\n')[0])
    
    # More accurate capacity.
    charge_full, charge_now = None, None
    with open('/sys/class/power_supply/BAT1/charge_full', 'r') as file:
        charge_full = int(file.read().split('\n')[0])
    with open('/sys/class/power_supply/BAT1/charge_now', 'r') as file:
        charge_now = int(file.read().split('\n')[0])
    capacity = charge_now * 100 / charge_full
    
    # Is the battery discharging?
    with open('/sys/class/power_supply/BAT1/status', 'r') as file:
        discharging = file.read().split('\n')[0] == 'Discharging'
    
    return (discharging, capacity)


# Lets wait only 30 seconds, instead of a minute before running again.
wait_period = 30

# Do not fade in or out.
fadeout_time = None
fadein_time = None


def periodically(year, month, day, hour, minute, second, weekday, fade):
    '''
    Invoked periodically
    
    If you want to control at what to invoke this function next time
    you can set the value of the global variable `wait_period` to the
    number of seconds to wait before invoking this function again.
    The value does not need to be an integer.
    
    @param  year:int     The year
    @param  month:int    The month, 1 = January, 12 = December
    @param  day:int      The day, minimum value is 1, probable maximum value is 31 (*)
    @param  hour:int     The hour, minimum value is 0, maximum value is 23
    @param  minute:int   The minute, minimum value is 0, maximum value is 59
    @param  second:int   The second, minimum value is 0, probable maximum value is 60 (**)
    @param  weekday:int  The weekday, 1 = Monday, 7 = Sunday
    @param  fade:float?  Blueshift can use this function to fade into a state when it start
                         or exits. `fade` can either be negative, zero or positive or `None`,
                         but the magnitude of value cannot exceed 1. When Blueshift starts,
                         this function will be invoked multiple with the time parameters
                         of the time it is invoked and each time `fade` will increase towards
                         1, starting at 0, when the value is 1, the settings should be applied
                         to 100 %. After this this function will be invoked once again with
                         `fade` being `None`. When Blueshift exits the same behaviour is used
                         except, `fade` decrease towards -1 but start slightly below 0, when
                         -1 is reached all settings should be normal. Then Blueshift will NOT
                         invoke this function with `fade` being `None`, instead it will by
                         itself revert all settings and quit.
    
    (*)  Can be exceeded if the calendar system is changed, like in 1712-(02)Feb-30
    (**) See https://en.wikipedia.org/wiki/Leap_second
    '''
    global inverted
    
    (discharging, capacity) = get_capacity()
    should_invert = discharging and (capacity <= threshold)
    
    if should_invert ^ inverted:
        inverted = should_invert
        start_over()
        if should_invert:
            negative()
        monitor_controller()