 /**************************************************************************
 *   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.h
*  \brief 	Headerfile for hardwareinfo.cpp. This file collect/hold all
*		Hardware information as e.g. battery and ac state.
*/

/*!
*  \class 	HardwareInfo
*  \brief 	class for hardware information related funtionality
*  \author 	Danny Kukawka, <dkukawka@suse.de>, <danny.kukawka@web.de>
*  \date    	2006-2007
*/

#ifndef _HARDWARE_H_
#define _HARDWARE_H_

// TQt - Header
#include <tqstring.h>
#include <tqobject.h>
#include <tqvaluelist.h>
#include <tqptrlist.h>
#include <tqdict.h>

// TDE hardware library
#include <tdehardwaredevices.h>

#include "dbusInterface.h"
#include "hardware_battery.h"
#include "hardware_batteryCollection.h"

enum suspend_type {
	SUSPEND2DISK,
	SUSPEND2RAM,
	FREEZE,
	STANDBY,
	SUSPEND_HYBRID,
};

enum cpufreq_type {
	UNKNOWN_CPUFREQ = -1,
	PERFORMANCE,
	DYNAMIC,
	POWERSAVE
};

enum device_type {
	BATTERY,
	AC_ADAPTER,
	BUTTON_SLEEP,
	BUTTON_POWER,
	LID,
	LAPTOP_PANEL,
	UNKNOWN_DEVICE
};

//! hold information if suspend/standby/pm actions are supported and allowed
/*!
* This dictionary contains information about the available pm capabilities and
* the related interfaces in TDE hardware library.
*/
typedef struct SuspendStates {
	//! true if the machine support suspend2ram and the interface is available
	bool suspend2ram;
	//! true if the machine support suspend2ram, but no interface available
	bool suspend2ram_can;
	//! true if the machine support suspend2ram and PolicyKit allow to call the interface
	int suspend2ram_allowed;
	//! true if the machine support suspend2disk and the interface is available
	bool suspend2disk;
	//! true if the machine support suspend2disk, but no interface available
	bool suspend2disk_can;
	//! true if the machine support suspend2disk and PolicyKit allow to call the interface
	int suspend2disk_allowed;
	//! true if the machine support freeze and the interface is available
	bool freeze;
	//! true if the machine support freeze, but no interface available
	bool freeze_can;
	//! true if the machine support freeze and PolicyKit allow to call the interface
	int freeze_allowed;
	//! true if the machine support standby and the interface is available
	bool standby;
	//! true if the machine support standby, but no interface available
	bool standby_can;
	//! true if the machine support standby and PolicyKit allow to call the interface
	int standby_allowed;
	//! true if the machine support hybrid suspend and the interface is available
	bool suspend_hybrid;
	//! true if the machine support hybrid suspend, but no interface available
	bool suspend_hybrid_can;
	//! true if the machine support hybrid suspend and PolicyKit allow to call the interface
	int suspend_hybrid_allowed;

	SuspendStates () {
		suspend2ram = false;
		suspend2ram_can = false;
		suspend2ram_allowed = -1;
		suspend2disk = false;
		suspend2disk_can = false;
		suspend2disk_allowed = -1;
		freeze = false;
		freeze_can = false;
		freeze_allowed = -1;
		standby = false;
		standby_can = false;
		standby_allowed = -1;
		suspend_hybrid = false;
		suspend_hybrid_can = false;
		suspend_hybrid_allowed = -1;
	}
} SuspendStates;

class HardwareInfo : public TQObject{

	TQ_OBJECT


private:
	TDEHardwareDevices *m_hwdevices;

	//! pointer to the dbusInterface connection class
	dbusInterface *dbus_iface;

	//! hold udis of special hardware except batteries represented by a TQString pairs (name,udi)
	/*!
	* This directory handle udis for known fixed devices as e.g ac adapter. This devices are
	* currently available:
	* \li acadapter
	* \li lidclose
	* \li laptop_panel
	*/
	TQDict<TQString> udis;

	//! hold the UDIs of all hardware we handle atm
	/*!
	 * This TQStringList contains the list of UDIs we handle at the moment in this
         * class. This should be used to handle device events from TDE hardware library
         * for devices we want to monitor
	 */
	TQStringList allUDIs;

	/*!
	 * This TQStringList contains the unmonitored UDIs we alread know
	 */
	TQStringList unknownUDIs;

	//! hold information if suspend/standby/pm actions are supported and allowed
	/*!
	* This dictionary contains information about the available pm capabilities and
	* the related interfaces in TDE hardware library.
	*/
	SuspendStates suspend_states;

	TQTime calledSuspend;

	//! hold the list of pointers to all relevant batteries
	TQPtrList<Battery> BatteryList;
	//! hold the information about all primary batteries
	BatteryCollection *primaryBatteries;

	//! hold the name of the CPU Freq governor from the last check
	TQString cpuFreqGovernor;

	//! hold the ConsoleKit name/path of the actual session
	TQString consoleKitSession;

	//! enum with the currently active CPU Freq policy
	/*! This enum contains the enum with the currently set CPU Freq Policy. */
	cpufreq_type currentCPUFreqPolicy;

	//! the state of the ac adapter
	/*!
	* This boolean represent information about the AC adapter state.
	* \li true: 	if AC adapter is present
	* \li false: 	it AC adapter is not present
	*/
	bool acadapter;
	//! the state of the lidclose button
	/*!
	* This boolean represent information about the Lid button state.
	* \li true: 	if lid is closed
	* \li false: 	else
	*/
	bool lidclose;
	//! if the machine support APM
	/*!
	* This boolean represent information if the machine support APM or not.
	* \li true: 	if APM supported
	* \li false: 	else
	*/
	bool has_APM;
	//! if the machine support ACPI
	/*!
	* This boolean represent information if the machine support ACPI or not.
	* \li true: 	if ACPI supported
	* \li false: 	else
	*/
	bool has_ACPI;
	//! if the machine support PMU (ppc power management)
	/*!
	* This boolean represent information if the machine support PMU or not.
	* \li true: 	if PMU supported
	* \li false: 	else
	*/
	bool has_PMU;
	//! if the machine support change CPU Freq via TDE hardware library
	/*!
	* This boolean represent information if the machine support change the
	* CPU freqency via TDE hardware library.
	* \li true: 	if supported
	* \li false: 	else
	*/
	bool cpuFreq;
	//! if the machine support change brightness
	/*!
	* This boolean represent information if the machine support brightness changes.
	* \li true: 	if supported
	* \li false: 	else
	*/
	bool brightness;
	//! if brightness get controled via keyevents in hardware
	/*!
	* This boolean represent information if the machine handle brightness button
	* and keyevents in hardware. If so TDEPowersave should ignore key events.
	* \li true: 	if handled in hardware
	* \li false: 	else
	*/
	bool brightness_in_hardware;
	//! if the machine is a laptop
	/*!
	* This boolean represent information if the machine is a laptop.
	* \li true: 	if the machine is a laptop
	* \li false: 	else
	*/
	bool laptop;

	//! if the current desktop session is active
	/*!
	* This boolean represent information if the current desktop session in
        * Which TDEPowersave runs is marked in ConsoleKit as active or not.
	* \li true: 	if active
	* \li false: 	else
	*/
	bool sessionIsActive;

	//! if the current user can use the CPU Freq interface
	/*!
	* This integer tell if the current user is allowed to change the
	* CPU Frequency policy via the TDE hardware library
	* \li 1:	if allowed
	* \li 0:	if not allowed
	* \li -1:	if unknown (e.g. there is no policy/PolicyKit)
	*/
	int cpuFreqAllowed;
	//! if the current user can use the brightness interface
	/*!
	* This integer tell if the current user is allowed to change the
	* brightness via the TDE hardware library
	* \li 1:	if allowed
	* \li 0:	if not allowed
	* \li -1:	if unknown (e.g. there is no policy/PolicyKit)
	*/
	int brightnessAllowed;


	//! Integer with the number of current brightness
	/*! This contains the current brighness level. */
	int currentBrightnessLevel;
	//! Integer with the number of availabl brightness level
	/*! This contains the number of available brightness levels for internal usage. */
	int availableBrightnessLevels;

	//! interger with the current warning level
	int primaryBatteriesWarnLevel;
	//! interger with the current low level
	int primaryBatteriesLowLevel;
	//! interger with the current critical level
	int primaryBatteriesCriticalLevel;

	// --> functions
	//! check if the machine support ACPI/APM/PMU or not
	void checkPowermanagement();
	//! check the possible suspend/standby states
	void checkSuspend();
	//! check if the machine support change CPU Freq via TDE hardware library
	void checkCPUFreq();
	//! check the current brightness level
	void checkCurrentBrightness();
	//! check if the machine is a laptop
	void checkIsLaptop();

	//! initalise all hardware information
	bool intialiseHWInfo();
	//! reinit all hardware information
	bool reinitHardwareInfos();
	//! to check if we should handle a device
	bool checkIfHandleDevice ( TQString _udi, int *type );
	//! to set the CPUFreq governor
	bool setCPUFreqGovernor( const char *governor );

	//! find and update a battery information
	void updateBatteryValues (TDEGenericDevice* device);

private slots:

	//! handle changes of the session state
	void handleSessionState (bool state);
	//! to fetch events from the TDE hardware library and handle them
	void processHardwareChangedEvent (TDEGenericDevice*);
	//! to fetch keypresses from the TDE hardware library and handle them
	void processKeyPressEvent (unsigned int, TDEEventDevice*);
	//! to update \ref primaryBatteries
	void updatePrimaryBatteries ();
	//! to set \ref update_info_primBattery_changed
	void setPrimaryBatteriesChanges ();
	//! check the state of the lidclose button
	void checkLidcloseState();
	//! check the state of the AC adapter
	void checkACAdapterState();
	//! check if brightness change is possible
	void checkBrightness();

	//! TQ_SLOT to forward signal about changed battery warning state
	void emitBatteryWARNState (int type, int state);

	//! TQ_SLOT to handle resume and forward a signal for resume
	void handleResumeSignal (int result);

	//! to emit signal for power button
	void emitPowerButtonPressed();
	//! to emit signal for sleep button
	void emitSuspendButtonPressed();
	//! to emit signal for s2disk button
	void emitS2diskButtonPressed();
	//! to emit signal for session state
	void emitSessionActiveState();

signals:
	//! signal for larger data changes
	void generalDataChanged();
	//! emited if the CPU Freq Policy changed
	void currentCPUFreqPolicyChanged();

	//! signal the AC adapter
	void ACStatus( bool );
	//! signal for the lidclose button
	void lidclosetStatus ( bool );
	//! signal for pressed the power button
	void powerButtonPressed ();
	//! signal for pressed sleep (suspend2ram) button
	void sleepButtonPressed ();
	//! signal for pressed the suspend2disk (hibernate) button
	void s2diskButtonPressed ();

	//  battery related signals
	//! signal if the primary battery collection changed
	void primaryBatteryChanged();
	//! signal to inform about reaching a warning state
	void batteryWARNState(int type, int state);

	// Error signals

	//! signal if the IsActive state of
	void desktopSessionIsActive (bool);

	//! signal if we are back from resume
	void resumed ( int success );

public:

	// update related info --> need to be reset if the data was read
	//! tells if the  CPUFreq Policy changed
	/*!
	* This boolean represent information about CPUFreq Policy changes.
	* \li true: if something changed
	* \li false: if nothing changed (or this is reset to false if the message was consumed)
	*/
	bool update_info_cpufreq_policy_changed;
	//! tells if the AC status changed
	/*!
	* This boolean represent information about AC status changes.
	* \li true: if something changed
	* \li false: if nothing changed (or this is reset to false if the message was consumed)
	*/
	bool update_info_ac_changed;
	//! tells if the primary battery collection changed some values
	/*!
	* This boolean represent information about primary battery changes.
	* \li true: if something changed
	* \li false: if nothing changed (or this is reset to false if the message was consumed)
	*/
	bool update_info_primBattery_changed;

	// --> functions
	//! default constructor
	HardwareInfo();
	//! default destructor
	~HardwareInfo();

	// to get private members
	//! get info about support of suspend/standby
	SuspendStates getSuspendSupport() const;
	//! get a pointer to the primary batteries
	BatteryCollection* getPrimaryBatteries() const;
	//! get all batteries
	TQPtrList<Battery> getAllBatteries() const;

	//! check the currently set CPU Frequency Policy
	cpufreq_type checkCurrentCPUFreqPolicy();

	//! get max brightness level
	int getMaxBrightnessLevel() const;
	//! get current brightness level
	int getCurrentBrightnessLevel() const;
	//! get currently CPU Frequency Policy
	int getCurrentCPUFreqPolicy() const;
	//! if the user is allowed to change CPU Freq PolicyKit
	int isCpuFreqAllowed ();

	//! get state of the AC adapter
	bool getAcAdapter() const;
	//! get the state of the lid button
	bool getLidclose() const;
	//! check if the machine is a latop
	bool isLaptop() const;
	//! check if there is a connection to TDE hardware library
	bool isOnline() const;
	//! check if the machine support ACPI
	bool hasACPI() const;
	//! check if the machine support APM
	bool hasAPM() const;
	//! check if the machine support PMU
	bool hasPMU() const;
	//! check if the machine support change the CPU frequency
	bool supportCPUFreq() const;
	//! check if the machine support brightness changes
	bool supportBrightness() const;
	//! check if the current session is active
	bool currentSessionIsActive() const;

	// --> functions to call a TDE hardware library and trigger an action
	//! execute/trigger a suspend via the TDE hardware library
	bool suspend ( suspend_type suspend );
	//! set the brightness level via TDE hardware library
	bool setBrightnessLevel(int level);
	//! set the brightness percentage via TDE hardware library
	bool setBrightnessPercentage(int percent);
	//! to set the brightness down
	bool setBrightnessDown(int percentageStep = -1);
	//! to set the brightness up
	bool setBrightnessUp(int percentageStep = -1);
	//! set the CPU frequency policy/speed
	bool setCPUFreq ( cpufreq_type cpufreq, int limit = 51 );

	//! function to set warning states for the primary battery collection
	void setPrimaryBatteriesWarningLevel (int _warn = -1, int _low = -1, int _crit = -1 );
};

#endif
