 /**************************************************************************
 *   Copyright (C) 2006-2007 by Danny Kukawka                              *
 *                           <dkukawka@suse.de>, <danny.kukawka@web.de>    *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of version 2 of the GNU General Public License     *
 *   as published by the Free Software Foundation.                         *
 *                                                                         *
 *   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, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.             *
 ***************************************************************************/

/*! 
 * \file 	hardware_battery.cpp
 * \brief 	In this file can be found the Battery related code.
 * \author 	Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de>
 * \date    	2006-2007
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "hardware_battery.h"

// FOR REFERENCE
// udi = '/org/freedesktop/Hal/devices/bme'
//   info.addons = { 'hald-addon-bme' } (string list)
//   maemo.charger.type = 'host 500 mA'  (string)
//   maemo.charger.connection_status = 'connected'  (string)
//   maemo.rechargeable.charging_status = 'on'  (string)
//   maemo.rechargeable.positive_rate = true  (bool)
//   battery.present = true  (bool)
//   info.product = 'Battery (BME-HAL)'  (string)
//   info.subsystem = 'unknown'  (string)
//   battery.is_rechargeable = true  (bool)
//   info.udi = '/org/freedesktop/Hal/devices/bme'  (string)
//   battery.charge_level.unit = 'bars'  (string)
//   battery.remaining_time = 7200  (0x1c20)  (int)
//   battery.type = 'pda'  (string)
//   battery.charge_level.percentage = 71  (0x47)  (int)
//   battery.charge_level.design = 8  (0x8)  (int)
//   battery.charge_level.capacity_state = 'ok'  (string)
//   battery.rechargeable.is_discharging = false  (bool)
//   battery.charge_level.last_full = 7  (0x7)  (int)
//   battery.reporting.design = 1258  (0x4ea)  (int)
//   battery.reporting.last_full = 867  (0x363)  (int)
//   battery.reporting.current = 903  (0x387)  (int)
//   battery.voltage.unit = 'mV'  (string)
//   battery.voltage.design = 4200  (0x1068)  (int)
//   info.category = 'battery'  (string)
//   battery.voltage.current = 3947  (0xf6b)  (int)
//   battery.remaining_time.calculate_per_time = false  (bool)
//   info.parent = '/org/freedesktop/Hal/devices/computer'  (string)
//   battery.charge_level.current = 7  (0x7)  (int)
//   battery.rechargeable.is_charging = true  (bool)
//   info.capabilities = { 'battery' } (string list)
//   battery.reporting.unit = 'mAh'  (string)

/*! The default constructor of the class Battery. */ 
Battery::Battery( TQString _udi ) {
	if (trace) kdDebug() << funcinfo << "IN , udi: " << udi << endl;

	m_hwdevices = TDEGlobal::hardwareDevices();
	m_hwdevices->setBatteryUpdatesEnabled(true);

	udi = _udi;

	connect(m_hwdevices, TQ_SIGNAL(hardwareUpdated(TDEGenericDevice*)), this, TQ_SLOT(updateProperty(TDEGenericDevice*)));

	initialized = false;

	initDefault();
	init();

	kdDebugFuncOut(trace);
}

/*! The default destructor of the class Battery. */
Battery::~Battery() {
	kdDebugFuncIn(trace);

}

//! init a battery with default values
void Battery::initDefault() {
	kdDebugFuncIn(trace);

	present = false;
	type = BAT_UNKNOWN;
	state = BAT_NORM;
	capacity_state = "ok";
	charging_state = UNKNOWN_STATE;
	charge_level_unit = "Ah";
	charge_level_current = 0;
	charge_level_lastfull = 0;
	charge_level_percentage = 0;
	design_capacity = 0;
	present_rate = 0;
	remaining_minutes = 0;
	serial = "";
	
	warn_level = 12;
	low_level = 7;
	crit_level = 2;
	
	kdDebugFuncOut(trace);
}

//! initialize this battery object
void Battery::init() {
	kdDebugFuncIn(trace);

	// read battery information
	recheck(); //fills all values

	initialized = true;
	kdDebugFuncOut(trace);
}

//! rechecks only minimalistic set properties
/*!
* Will only recheck properties regarding current battery states/levels.
*/
void Battery::minRecheck() {
	kdDebugFuncIn(trace);

	// First make sure the battery object is still available
	TDEBatteryDevice* bdevice = dynamic_cast<TDEBatteryDevice*>(m_hwdevices->findByUniqueID(udi));
	if (!bdevice) {
		//grr... no luck
		kdError() << "Battery::recheck couldn't find battery" << endl;
		kdDebugFuncOut(trace);
		return;
	}

	checkBatteryPresent();
	if (!present) {
		kdDebug() << "No need to update other properties, battery not present." << endl;
		kdDebugFuncOut(trace);
		return;
	} else {
		checkCapacityState();
		checkChargeLevelCurrent();
		checkRemainingPercentage();	
		checkChargingState();
		checkChargeLevelRate();
		checkRemainingTime();
	}

	kdDebugFuncOut(trace);
}

//! recheck all properties of the battery
/*!
 * Check and set the properties of a battery or collect the information for all
 * primary batteries in one object.
 */
void Battery::recheck() {
	kdDebugFuncIn(trace);

	// First make sure the battery object is still available
	TDEBatteryDevice* bdevice = dynamic_cast<TDEBatteryDevice*>(m_hwdevices->findByUniqueID(udi));
	if (!bdevice) {
		//grr... no luck
		kdError() << "Battery::recheck couldn't find battery" << endl;
		kdDebugFuncOut(trace);
		return;
	}

	checkBatteryPresent();
	checkBatteryType();
	if (!present) {
		kdDebug() << "Warning: No need to update properties, battery not present." << endl;
		kdDebugFuncOut(trace);
		return;
	} else {
		checkBatteryTechnology();
		checkCapacityState();
		checkChargeLevelCurrent();
		checkChargeLevelLastfull();
		checkRemainingPercentage();	
		checkChargingState();
		checkChargeLevelUnit();
		checkChargeLevelDesign();
		checkChargeLevelRate();
		checkRemainingTime();
	}

	kdDebugFuncOut(trace);
}

// ---> query for properties SECTION : START <----

//! to check battery.present
/*!
 * function to update \ref present from property battery.present
 * \return boolean with the result of the operation
 * \retval true 	if the update was successfull
 * \retval false 	if the update couldn't be applied
 */
bool Battery::checkBatteryPresent () {
	kdDebugFuncIn(trace);

	bool _present = false;

	// First make sure the battery object is still available
	TDEBatteryDevice* bdevice = dynamic_cast<TDEBatteryDevice*>(m_hwdevices->findByUniqueID(udi));
	if (!bdevice) {
		//grr... no luck
		kdError() << "Battery::checkBatteryPresent couldn't find battery" << endl;
		kdDebugFuncOut(trace);
		return false;
	}

	_present = bdevice->installed();
	if (_present != present) {
		present = _present;
		
		// force depending changes
		if (_present) {
			// should be now present
			recheck();
		}
		if (!_present) {
			//Uhhh, battery is not present, so we need to reset battery to default.
			initDefault();
			checkBatteryType();
			state = BAT_NONE;
		}

		if (initialized) {
			emit changedBatteryPresent();
			emit changedBattery();
		}
	}

	// also query the serial ...  no need to do this in a extra place
	serial = bdevice->serialNumber();
	
	kdDebugFuncOut(trace);
	return true;
}

//! to check battery.type
/*!
 * function to update \ref type from property battery.type
 * \return boolean with the result of the operation
 * \retval true 	if the update was successfull
 * \retval false 	if the update couldn't be applied
 */
bool Battery::checkBatteryType () {
	kdDebugFuncIn(trace);
	
	TQString tmp_qstring;

	// First make sure the battery object is still available
	TDEBatteryDevice* bdevice = dynamic_cast<TDEBatteryDevice*>(m_hwdevices->findByUniqueID(udi));
	if (!bdevice) {
		//grr... no luck
		kdError() << "Battery::checkBatteryType couldn't find battery" << endl;
		kdDebugFuncOut(trace);
		return false;
	}

	// FIXME
	// How can we get battery type from TDE HW library (i.e. how to get type from sysfs)?
	// For now just report any batteries as primary...
	type = BAT_PRIMARY;
	return true;
}

//! to check battery.technology
/*!
 * function to update \ref technology from property battery.technology
 * \return boolean with the result of the operation
 * \retval true 	if the update was successfull
 * \retval false 	if the update couldn't be applied
 */
bool Battery::checkBatteryTechnology () {
	kdDebugFuncIn(trace);
	
	TQString tmp_qstring;

	// First make sure the battery object is still available
	TDEBatteryDevice* bdevice = dynamic_cast<TDEBatteryDevice*>(m_hwdevices->findByUniqueID(udi));
	if (!bdevice) {
		//grr... no luck
		kdError() << "Battery::checkBatteryTechnology couldn't find battery" << endl;
		kdDebugFuncOut(trace);
		return false;
	}

	if (!present) {
		kdWarning() << "No need to update property, battery not present." << endl;
		kdDebugFuncOut(trace);
		return false;
	}

	tmp_qstring = bdevice->technology();
	if (!tmp_qstring.isEmpty()) {
		technology = TQString(tmp_qstring);
	} else {
		technology = TQString("UNKNOWN");
	}
	kdDebugFuncOut(trace);
	return true;
}


//! to check battery.charge_level.capacity_state
/*!
 * function to update \ref capacity_state from battery.charge_level.capacity_state
 * \return boolean with the result of the operation
 * \retval true 	if the update was successfull
 * \retval false 	if the update couldn't be applied
 */
bool Battery::checkCapacityState () {
	kdDebugFuncIn(trace);

	TQString tmp_qstring;

	// First make sure the battery object is still available
	TDEBatteryDevice* bdevice = dynamic_cast<TDEBatteryDevice*>(m_hwdevices->findByUniqueID(udi));
	if (!bdevice) {
		//grr... no luck
		kdError() << "Battery::checkCapacityState couldn't find battery" << endl;
		kdDebugFuncOut(trace);
		return false;
	}

	if (!present) {
		kdWarning() << "No need to update property, battery not present." << endl;
		kdDebugFuncOut(trace);
		return false;
	}

	capacity_state = "unknown";
	TDEBatteryStatus::TDEBatteryStatus batteryStatus = bdevice->status();
	if (batteryStatus == TDEBatteryStatus::Charging) {
		capacity_state = "charging";
	}
	if (batteryStatus == TDEBatteryStatus::Discharging) {
		capacity_state = "discharging";
	}
	if (batteryStatus == TDEBatteryStatus::Full) {
		capacity_state = "full";
	}

	kdDebugFuncOut(trace);
	return true;
}


//! to check battery.charge_level.current
/*!
 * function to update \ref charge_level_current from property battery.charge_level.current
 * \return boolean with the result of the operation
 * \retval true 	if the update was successfull
 * \retval false 	if the update couldn't be applied
 */
bool Battery::checkChargeLevelCurrent () {
	kdDebugFuncIn(trace);

	// First make sure the battery object is still available
	TDEBatteryDevice* bdevice = dynamic_cast<TDEBatteryDevice*>(m_hwdevices->findByUniqueID(udi));
	if (!bdevice) {
		//grr... no luck
		kdError() << "Battery::checkChargeLevelCurrent couldn't find battery" << endl;
		kdDebugFuncOut(trace);
		return false;
	}

	if (!present) {
		kdWarning() << "No need to update property, battery not present." << endl;
		kdDebugFuncOut(trace);
		return false;
	}

	// FIXME VERIFY CORRECTNESS
	// what does tdepowersave expect to see in charge_level_current (battery.charge_level.current)?
	charge_level_current = bdevice->energy();
	if (charge_level_current < 0) {
		//overflow?
		charge_level_current = 0;
	}
	kdDebugFuncOut(trace);
	return true;
}


//! to check battery.charge_level.last_full
/*!
 * function to update \ref charge_level_lastfull from property battery.charge_level.last_full
 * \return boolean with the result of the operation
 * \retval true 	if the update was successfull
 * \retval false 	if the update couldn't be applied
 */
bool Battery::checkChargeLevelLastfull () {
	kdDebugFuncIn(trace);
	
	// First make sure the battery object is still available
	TDEBatteryDevice* bdevice = dynamic_cast<TDEBatteryDevice*>(m_hwdevices->findByUniqueID(udi));
	if (!bdevice) {
		//grr... no luck
		kdError() << "Battery::checkChargeLevelLastfull couldn't find battery" << endl;
		kdDebugFuncOut(trace);
		return false;
	}

	if (!present) {
		kdWarning() << "No need to update property, battery not present." << endl;
		kdDebugFuncOut(trace);
		return false;
	}

	// FIXME VERIFY CORRECTNESS
	// what does tdepowersave expect to see in charge_level_lastfull (battery.charge_level.last_full)?
	charge_level_lastfull = bdevice->maximumEnergy();
	if (charge_level_lastfull < charge_level_current ) {
		//possible overflow?
		charge_level_lastfull = charge_level_current;
	}
	kdDebugFuncOut(trace);
	return true;
}

//! to check battery.charge_level.rate
/*!
 * function to update \ref present_rate from property battery.charge_level.rate
 * \return boolean with the result of the operation
 * \retval true 	if the update was successfull
 * \retval false 	if the update couldn't be applied
 */
bool Battery::checkChargeLevelRate () {
	kdDebugFuncIn(trace);

	// First make sure the battery object is still available
	TDEBatteryDevice* bdevice = dynamic_cast<TDEBatteryDevice*>(m_hwdevices->findByUniqueID(udi));
	if (!bdevice) {
		//grr... no luck
		kdError() << "Battery::checkChargeLevelRate couldn't find battery" << endl;
		kdDebugFuncOut(trace);
		return false;
	}

	if (!present) {
		kdWarning() << "No need to update property, battery not present." << endl;
		kdDebugFuncOut(trace);
		return false;
	}

	double _rate = present_rate;

	// Note that the units used for charge_level_unit and present_rate_unit
	// are different. This is intentionally because the battery charge
	// values are in Ah while the power consumption is displayed in W.
	present_rate = bdevice->dischargeRate()*bdevice->voltage();
	if (present_rate < 0 )
		present_rate = 0;

	if (present_rate != _rate) {
		emit changedBattery();
	}

	kdDebugFuncOut(trace);
	return true;
}


//! to check battery.charge_level.unit
/*!
 * function to update \ref charge_level_unit from property battery.charge_level.unit
 * \return boolean with the result of the operation
 * \retval true 	if the update was successfull
 * \retval false 	if the update couldn't be applied
 */
bool Battery::checkChargeLevelUnit () {
	kdDebugFuncOut(trace);

	// First make sure the battery object is still available
	TDEBatteryDevice* bdevice = dynamic_cast<TDEBatteryDevice*>(m_hwdevices->findByUniqueID(udi));
	if (!bdevice) {
		//grr... no luck
		kdError() << "Battery::checkChargeLevelUnit couldn't find battery" << endl;
		kdDebugFuncOut(trace);
		return false;
	}

	if (!present) {
		kdWarning() << "No need to update property, battery not present." << endl;
		kdDebugFuncOut(trace);
		return false;
	}

	// Power supply energy informations in sysfs are always in uWh.
	// https://www.kernel.org/doc/Documentation/power/power_supply_class.txt
	// TDE hardware library internally uses Wh.
	// Since charge level unit are always Wh.
	charge_level_unit = "Wh";
	kdDebugFuncOut(trace);
	return false;
}

//! to check battery.charge_level.design
/*!
 * function to update \ref design_capacity from property battery.charge_level.design
 * \return boolean with the result of the operation
 * \retval true 	if the update was successfull
 * \retval false 	if the update couldn't be applied
 */
bool Battery::checkChargeLevelDesign () {
	kdDebugFuncIn(trace);
	
	// First make sure the battery object is still available
	TDEBatteryDevice* bdevice = dynamic_cast<TDEBatteryDevice*>(m_hwdevices->findByUniqueID(udi));
	if (!bdevice) {
		//grr... no luck
		kdError() << "Battery::checkChargeLevelDesign couldn't find battery" << endl;
		kdDebugFuncOut(trace);
		return false;
	}

	if (!present) {
		kdWarning() << "No need to update property, battery not present." << endl;
		kdDebugFuncOut(trace);
		return false;
	}

	// FIXME VERIFY CORRECTNESS
	// what does tdepowersave expect to see in design_capacity (battery.charge_level.last_full)?
	design_capacity = bdevice->maximumDesignEnergy();
	if (design_capacity < 0) {
		design_capacity = 0;
	}

	kdDebugFuncOut(trace);
	return true;
}


//! to check battery.charge_level.percentage
/*!
 * function to update \ref charge_level_percentage from property battery.charge_level.percentage
 * \return boolean with the result of the operation
 * \retval true 	if the update was successfull
 * \retval false 	if the update couldn't be applied
 */
bool Battery::checkRemainingPercentage () {
	kdDebugFuncIn(trace);
	
	bool ret = false;
	int _val = 0;
	int _state = -1;

	// First make sure the battery object is still available
	TDEBatteryDevice* bdevice = dynamic_cast<TDEBatteryDevice*>(m_hwdevices->findByUniqueID(udi));
	if (!bdevice) {
		//grr... no luck
		kdError() << "Battery::checkRemainingPercentage couldn't find battery" << endl;
		kdDebugFuncOut(trace);
		return false;
	}

	if (!present) {
		kdWarning() << "No need to update property, battery not present." << endl;
		kdDebugFuncOut(trace);
		return false;
	}

	_val = bdevice->chargePercent();
	if (_val > 100) {
		_val = 100;
	} else if (_val < 0) {
		_val = 0;
	}
	ret = true;

	if (charge_level_percentage != _val) {
		if (initialized) {
			emit changedBatteryPercentage();
			emit changedBattery();
		}
		charge_level_percentage = _val;
	}

	//battery state
	if (charge_level_percentage <= crit_level) {
		//we are now in critical level
		_state = BAT_CRIT;
	} else if (charge_level_percentage <= low_level) {
		//we are now in a low level
		_state = BAT_LOW;
	} else if (charge_level_percentage <= warn_level) {
		//we are now in warning state
		_state = BAT_WARN;
	} else if (state != BAT_NONE) {
		_state = BAT_NORM;
	} else {
		_state = BAT_NONE;
	}
	
	if (state != _state) {
		if (initialized) {
			if (_state == (BAT_CRIT || BAT_LOW || BAT_WARN))
				emit changedBatteryWarnState(_state);
			else if (state == (BAT_CRIT || BAT_LOW || BAT_WARN))
				emit changedBatteryWarnState(_state);
			else 
				emit changedBatteryState();

			emit changedBattery();
		}
		state = _state;
	}

	kdDebugFuncOut(trace);
	return ret;
}

//! to check battery.remaining_time
/*!
 * function to update \ref remaining_minutes from property battery.remaining_time
 * \return boolean with the result of the operation
 * \retval true 	if the update was successfull
 * \retval false 	if the update couldn't be applied
 */
bool Battery::checkRemainingTime () {
	kdDebugFuncIn(trace);
	
	int _min = 0;
	bool _ret = false;	

	// First make sure the battery object is still available
	TDEBatteryDevice* bdevice = dynamic_cast<TDEBatteryDevice*>(m_hwdevices->findByUniqueID(udi));
	if (!bdevice) {
		//grr... no luck
		kdError() << "Battery::checkRemainingTime couldn't find battery" << endl;
		kdDebugFuncOut(trace);
		return false;
	}

	if (!present) {
		kdWarning() << "No need to update property, battery not present." << endl;
		kdDebugFuncOut(trace);
		return false;
	}

	_min = bdevice->timeRemaining();
	_min /= 60;
	_ret = true;

	if (remaining_minutes != _min) {
		if (initialized) {
			emit changedBatteryTime();
			emit changedBattery();
		}

		remaining_minutes = _min;
	}

	kdDebugFuncOut(trace);
	return _ret;
}

//! to check battery.rechargeable.is_*
/*!
 * function to update \ref charging_state from property battery.rechargeable.is_*
 * \return boolean with the result of the operation
 * \retval true 	if the update was successfull
 * \retval false 	if the update couldn't be applied
 */
bool Battery::checkChargingState () {
	kdDebugFuncIn(trace);
	
	bool tmp_bool = false;
	bool tmp_bool2 = false;
	bool _ret = false;
	int _c_state = -1;

	// First make sure the battery object is still available
	TDEBatteryDevice* bdevice = dynamic_cast<TDEBatteryDevice*>(m_hwdevices->findByUniqueID(udi));
	if (!bdevice) {
		//grr... no luck
		kdError() << "Battery::checkChargingState couldn't find battery" << endl;
		kdDebugFuncOut(trace);
		return false;
	}
	if (!present) {
		kdWarning() << "No need to update property, battery not present." << endl;
		kdDebugFuncOut(trace);
		return false;
	}

	tmp_bool = (bdevice->status() == TDEBatteryStatus::Charging);
	tmp_bool2 = (bdevice->status() == TDEBatteryStatus::Discharging);

	if (tmp_bool && !tmp_bool2) {
		_c_state = CHARGING;
	} else if (tmp_bool2 && !tmp_bool) {
		_c_state = DISCHARGING;
	} else {
		_c_state = UNKNOWN_STATE;
	}
	
	_ret = true;

	if (charging_state != _c_state) {
		if (initialized) {
			emit changedBatteryChargingState();
			emit changedBattery();
		}

		charging_state = _c_state;
	}

	kdDebugFuncOut(trace);
	return _ret;	
}

// ---> query for properties SECTION : END <----

//! to recheck a special value for an event
/*!
 * Check for the given property new values and set them to 
 * the battery variables.
 * \param device		TDEGenericDevice
 */
void Battery::updateProperty(TDEGenericDevice* device) {
	kdDebugFuncIn(trace);
	
	if (device->uniqueID() == udi) {
		recheck();
	}

	kdDebugFuncOut(trace);
}

// ---> write private members SECTION : START <----

//! sets the chargelevel in percent when battery should go into state warning
void Battery::setWarnLevel(int _warn_level) {
	kdDebugFuncIn(trace);

	if (_warn_level < low_level) {
		kdError() << "Refuse requested level: " << _warn_level 
			  << " as it is smaller than the LowLevel: " << low_level << endl;
	} else {
		warn_level = _warn_level;
	}

	kdDebugFuncOut(trace);
}

//! sets the chargelevel in percent when battery should go into state low
void Battery::setLowLevel(int _low_level) {
	kdDebugFuncIn(trace);

	if (_low_level < crit_level || _low_level > warn_level) {
		kdError() << "Refuse requested level: " << _low_level 
			  << " as it is not between WarnLevel: " << warn_level
			  << " and CritLevel: " << crit_level << endl; 
	} else {
		low_level = _low_level;
	}

	kdDebugFuncOut(trace);
}

//! sets the chargelevel in percent when battery should go into state critical
void Battery::setCritLevel(int _crit_level) {
	kdDebugFuncIn(trace);

	if (_crit_level > low_level) {
		kdError() << "Refuse requested level: " << _crit_level
			  << " as it is bigger than LowLevel: " << low_level << endl;
	} else {
		crit_level = _crit_level;
	}

	kdDebugFuncOut(trace);
}

// ---> write private members SECTION : END <----
// ---> get private members SECTION : START <----

//! reports the udi of this battery
TQString Battery::getUdi() const {
	return TQString(udi);
}

//! reports the battery type
int Battery::getType() const {
	return type;
}

//! gives the name of this battery technology
TQString Battery::getTechnology() const {
	return TQString(technology);
}

//! tells the current batterystate as enum BAT_STATE_
int Battery::getState() const {
	return state;
}

//! estimates the remaining minutes until fully charged/discharged
int Battery::getRemainingMinutes() const {
	return remaining_minutes;
}

//! current charging/discharging rate 
double Battery::getPresentRate() const {
	return present_rate;
}

//! get availability of this battery
bool Battery::isPresent() {
	return present;
}

//! maximum capacity of this battery by design
int Battery::getDesignCapacity() const {
	return design_capacity;
}

//! current charging state as enum BAT_CHARG_STATE
int Battery::getChargingState() const {
	return charging_state;
}

//! reports the physical unit of values like DesignCapacity, PresentRate and Lastfull
TQString Battery::getChargelevelUnit() const {
	return TQString(charge_level_unit);
}

//! reports current chargelevel in percentage
int Battery::getPercentage() const {
	return charge_level_percentage;
}

//! reports last full capacity of this battery when fully charged
int Battery::getLastfull() const {
	return charge_level_lastfull;
}

//! reports current chargelevel in units reported by getChargelevelUnit()
int Battery::getCurrentLevel() const {
	return charge_level_current;
}

//! reports capacity_state value
TQString Battery::getCapacityState() const {
	return TQString(capacity_state);
}

//! reports the chargelevel in percent when battery goes to state warning
int Battery::getWarnLevel() const {
	return warn_level;
}

//! reports the chargelevel in percent when battery goes to state low
int Battery::getLowLevel() const {
	return low_level;
}

//! reports the chargelevel in percent when battery goes to state critical
int Battery::getCritLevel() const {
	return crit_level;
}

//some convenience methods

//! check if the battery is currently charged
bool Battery::isCharging() {
	return (charging_state == CHARGING);
}

//! check if the battery gets currently discharged
bool Battery::isDischarging() {
	return (charging_state == DISCHARGING);
}

//! check it this is a primary battery
bool Battery::isPrimary() const {
	return (type == BAT_PRIMARY);
}

//! check if the battery state is ok/normal
bool Battery::isOk() {
	return (state == BAT_NORM);
}

//! check if the battery is in warning level/state
bool Battery::isWarning() {
	return (state == BAT_WARN);
}

//! check if the battery is in a low chargingstate
bool Battery::isLow() {
	return (state == BAT_LOW);
}

//! check if the battery level is critical
bool Battery::isCritical() {
	return (state == BAT_CRIT);
}
 
// ---> get private members SECTION : START <----

#include "hardware_battery.moc"
