/*
Copyright (c) 2006, Intel Corporation.

This Intel Laptop Gaming TDK ("Software") is furnished under license and may 
only be used or copied in accordance with the terms of that license. No license, 
express or implied, by estoppel or otherwise, to any intellectual property rights 
is granted by this document. The Software is subject to change without notice, 
and should not be construed as a commitment by Intel Corporation to market, 
license, sell or support any product or technology. Unless otherwise provided 
for in the license under which this Software is provided, the Software is 
provided AS IS, with no warranties of any kind, express or implied. 
Except as expressly permitted by the Software license, neither Intel Corporation 
nor its suppliers assumes any responsibility or liability for any errors or 
inaccuracies that may appear herein. Except as expressly permitted by the 
Software license, no part of the Software may be reproduced, stored in a 
retrieval system, transmitted in any form, or distributed by any means 
without the express written consent of Intel Corporation.
*/


/**
* This class defines PowerInfo methods which provide access to system current
* power status. Methods provide access to current power source, % battery life left, 
* battery time in seconds, setting/getting power scheme.
* Also provides events for change in power source and low battery life left
*/

#ifndef IGLPOWERINFO_H
#define IGLPOWERINFO_H

#include "stdafx.h"

extern "C"
{
#include <Powrprof.h>
}
#include "ILGAbstractEventInfo.h"
#include "ILGdefines.h"

// Warning here complains about using non-dll base class for creating PowerInfo
#pragma warning( disable : 4275 )

typedef unsigned (WINAPI *PBEGINTHREADEX_THREADFUNC)(LPVOID lParam);
typedef unsigned *PBEGINTHREADEX_THAREDID;

class PowerInfo: public AbstractEventInfo
{

public:
	PowerInfo();
	~PowerInfo();
	
	/**
	* Checks if the current system is laptop based on battery flag
	* if system battery is not available, then battery flag is set to 128
	*/
	bool IsLaptop();

	/**
	* Get current power source. u.e. whether system running on battery or AC power
	*/
	PowerSource GetPowerSrc();

	/**
	* Get percent battery life left in percent
	*/
	int GetPercentBatteryLife();

	/**
	* Get battery life time remaining in seconds
	*/
	unsigned long GetSecBatteryLifeTimeRemaining();

	/**
	* Get number of batteries powering the system
	*/
	//int GetNumberOfBatteries();

	/**
	* Get current power scheme of the system - throttle_adaptive
	* throttle_degrade, throttle_constant, throttle_none
	* CPU frequency will be dependent on power scheme
	*/
	PowerScheme GetCurrentPowerScheme();

	/**
	* Set power scheme for the system. This is used to change current power scheme
	* to a new one
	*/
	bool SetCurrentPowerScheme(PowerScheme new_scheme);

	/**
	* This function starts a monitoring thread of a desired event. This function is
	* defined in base class and the 3rd parameter is by default turned off. This
	* is used in cases where there an event needs to watch for a certain threshold 
	* value
	*/
	void Start(int event, Notifiable* m_pNot, int lpThreshold = 0, int UpdateFreq = 2000);

	/**
	* This function stops a monitoring thread of a desired event
	*/
	void Stop(int event);

private:
	
	// private variable to store power status information
	SYSTEM_POWER_STATUS pwrStat;

	// For reading power policy
	MACHINE_PROCESSOR_POWER_POLICY pwrPolicy;

	// Thread function for monitoring change in power source
	static DWORD WINAPI ThreadFuncPowerSource(LPVOID ThreadParam);

	// non-static function that the thread function calls to detect change in power source
	void ThreadMonitorPowerSource(Notifiable* pNotif, int frequency);

	// Thread function for watching low threshold battery life
	static DWORD WINAPI ThreadFuncPower(LPVOID ThreadParam);

	// non-static function that the thread function calls to detect if low threshold has reached
	void ThreadMonitorPower(Notifiable* pNotif, int lPower, int frequency);

	// Thread function for event driven model to watch change in battery charge
	static DWORD WINAPI ThreadFuncBatCharge(LPVOID ThreadParam);

	// non-static function that the thread thread function calls to detect change in battery charge
	void ThreadMonitorBatteryCharge(Notifiable* pNotif, int frequency);

	// parameters for two threads. Defined in base file
	// structure to pass to thread functions including this pointer for the class 
	// pointer to call back observer and threshold paramater.
	//ThreadParamStruct *pStructT1, *pStructT2;
	ThreadParamStruct pStruct[3];

	// critical section for protecting variable shared between separate threads
	CRITICAL_SECTION m_cs;

	// Bool variable to control monitoring of power state
	bool MonitorPowerState;

	// Bool variable to control monitoring of change in power source
	bool MonitorPowerSrc;

	// Bool variable to control event notification model to get current battery %
	bool MonitorBatteryCharge;

	// Thread handle
	HANDLE h[3];

	// Bool variables to check if the threads are already running
	bool Thread0Running, Thread1Running, Thread2Running;

	// Bool variables to make sure threads have exited before calling
	// destructor
	bool EndThread0, EndThread1, EndThread2;

};

#endif IGLPOWERINFO_H