property script_author : "JNSoftware LLC"
property script_name : "Battery Info"
property script_version : "1.1"
property script_release_date : date "Friday, May 27, 2005 1:00:00 PM"
property script_copyright : "© 2005 " & script_author & ". All Rights Reserved."

property first_run : true
property script_license : "
This script is free software; you canredistribute 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.

This script 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 script; if not, write to:

        Free Software Foundation, Inc.
        59 Temple Place, Suite 330
        Boston, MA 02111-1307 USA"

property the_codes : {"80", "81", "70", "71", "60", "61", "50", "51", "40", "41", "30", "31", "20", "21", "10", "11"}
property the_descriptions : {"Not Connected", "Connected", "Not Charging", "Charging", "Not Installed", "Installed", "Not Installed", "Installed", "Above Warning Level", "Below Warning Level", "", "Depleted", "", "No Charging Capability", "", "Raw Low Signal"}
property battery_flags : {6, 4, 3, 1}
property charger_flags : {8, 7, 2}
property ups_flags : {5}

if first_run then
    my get_script_info()
    set first_run to false
end if

display dialog (my get_battery_properties()) buttons {"OK"} default button 1 giving up after 30

on get_battery_properties()
    try
        set the_vals to (do shell script "ioreg -p IODeviceTree -n battery -w 0| grep IOBatteryInfo |cut -d'{' -f2 | cut -d'}' -f1 | tr -d '\"' | tr , '\\n'")'s paragraphs
        repeat with i from 1 to (count the_vals)
            set item i of the_vals to (my string_to_list(item i of the_vals, "="))'s item 2
            try
                set item i of the_vals to (item i of the_vals) as integer
            on error
                set item i of the_vals to (character 1 of item i of the_vals) as integer
            end try
        end repeat
        set MacOS_version to (my gestalt_version_info("sysv", 4))
        set cycles to missing value
        if MacOS_version < "10.3" then
            set {voltage, power_mode, amps, max_power, current_power} to the_vals
        else if MacOS_version < "10.3.7" then
            set {max_power, amps, current_power, voltage, power_mode} to the_vals
        else
            set {max_power, amps, cycles, current_power, voltage, power_mode, absolute_max_power} to the_vals
        end if
        set battery_string to "Battery Voltage:" & tab & (voltage / 1000) & " V" & return & ¬
            "Battery Amperage:" & tab & (amps / 1000) & " A" & return & ¬
            "Battery Maximum Charge:" & tab & max_power & return & ¬
            "Battery Current Charge:" & tab & current_power & return & ¬
            "Battery Percent Charged:" & tab & (round ((current_power / max_power) * 100)) & "%"
        if cyclesmissing value then set battery_string to battery_string & return & "Cycle Count:" & tab & cycles
        set battery_string to battery_string & return & return & my get_all_descriptions(my decimal_to_binary(power_mode))
    on error e
        return e
        set battery_string to "Couldn't determine battery information."
    end try
    return battery_string
end get_battery_properties

on get_all_descriptions(this_flag)
    set this_battery_description to "Battery:" & tab & my get_description(this_flag, battery_flags) & return
    set this_charger_description to "Charger:" & tab & my get_description(this_flag, charger_flags) & return
    set this_UPS_description to "UPS:" & tab & my get_description(this_flag, ups_flags)
    return this_battery_description & this_charger_description & this_UPS_description
end get_all_descriptions

on get_description(this_flag, use_flags)
    set these_descriptions to {}
    repeat with i from (count this_flag) to 1 by -1
        if i is in use_flags then
            set this_code to ((i as Unicode text) & (this_flag's character i))
            set the_value to my key_value_match(this_code, the_codes, the_descriptions, "")
            if the_value ≠ "" then set end of these_descriptions to the_value
        end if
    end repeat
    tell (a reference to my text item delimiters)
        set {old_tids, contents} to {contents, ", "}
        set {these_descriptions, contents} to {these_descriptions as Unicode text, old_tids}
    end tell
    return these_descriptions
end get_description

on key_value_match(the_key, key_list, value_list, no_match_value)
    repeat with i from 1 to (count key_list)
        if key_list's item i = the_key then return value_list's item i
    end repeat
    return no_match_value
end key_value_match

on decimal_to_binary(the_decimal)
    set {the_binary, i} to {"", 0}
    repeat until i = 1
        set {the_binary, the_decimal} to {(((((the_decimal) - (2 * (the_decimal div 2))) as integer) as Unicode text) & the_binary), (the_decimal div 2)}
        if the_decimal = 0 then set i to (i + 1)
    end repeat
    try
        return the_binary's text -8 thru -1
    on error
        return my add_leading_zeros(the_binary, "10000")
    end try
end decimal_to_binary

on add_leading_zeros(the_number, total_number)
    set {i, j, z} to {(count (total_number as Unicode text)), (count (the_number as Unicode text)), ""}
    repeat while j < i
        set {z, j} to {(z & "0"), (j + 1)}
    end repeat
    return {z, the_number} as Unicode text
end add_leading_zeros

on string_to_list(s, d)
    tell (a reference to my text item delimiters)
        set {o, contents} to {contents, d}
        set {s, contents} to {s's text items, o}
    end tell
    return s
end string_to_list

on gestalt_version_info(gestalt_code, string_length)
    try
        set {a, b, c, d} to (my num_to_hex((system attribute gestalt_code), string_length))
        if a = "0" then set a to ""
        return {a, b, ".", c, ".", d} as Unicode text
    on error
        return "unknown"
    end try
end gestalt_version_info

on num_to_hex(hex_data, string_length)
    set hex_string to {}
    repeat with i from string_length to 1 by -1
        set hex_string to ((hex_data mod 16) as Unicode text) & hex_string
        set hex_data to hex_data div 16
    end repeat
    return (hex_string as Unicode text)
end num_to_hex

on get_script_info()
    display dialog (script_name & " v" & script_version & return & ¬
        "by " & script_author & return & return & ¬
        script_copyright & return & return & ¬
        "Released " & (script_release_date as Unicode text)) buttons {"Continue"} default button 1 with icon 1
end get_script_info