#ifndef _COMMON_DESKTOP_HPP_
#define _COMMON_DESKTOP_HPP_
#ifndef _COMMON_WINDOWS_HPP_
#include <common/windows.hpp>
#endif
#ifndef _COMMON_STRING_HPP_
#include <common/string.hpp>
#endif

class Desktop
{
public:
  enum Access{AccessCreateMenu=DESKTOP_CREATEMENU,AccessCreateWindow=DESKTOP_CREATEWINDOW,AccessEnumerate=DESKTOP_ENUMERATE,
	            AccessHookControl=DESKTOP_HOOKCONTROL,AccessJournalPlayback=DESKTOP_JOURNALPLAYBACK,AccessJournalRecord=DESKTOP_JOURNALRECORD,
							AccessReadObjects=DESKTOP_READOBJECTS,AccessSwitchDesktop=DESKTOP_SWITCHDESKTOP,AccessWriteObjects=DESKTOP_WRITEOBJECTS};
	enum Flags{None=0,AllowOtherAccountHook=DF_ALLOWOTHERACCOUNTHOOK};
  Desktop(void);
	Desktop(const String &strDesktop,bool inheritHandle=false,DWORD desiredAccess=AccessEnumerate,DWORD dwFlags=AllowOtherAccountHook);
	virtual ~Desktop();
	bool open(const String &strDesktop,bool inheritHandle=false,DWORD desiredAccess=AccessEnumerate,DWORD dwFlags=AllowOtherAccountHook);
	void close(void);
	const String &desktopName(void)const;
  bool activate(void)const;
	HDESK getHandle(void)const;
	bool isOkay(void)const;
private:
  Desktop(const Desktop &someDesktop);
	Desktop &operator=(const Desktop &someDesktop);

  String mStrDesktopName;
  HDESK mhDesktop;
};

inline
Desktop::Desktop(void)
: mhDesktop(0)
{
}

inline
Desktop::Desktop(const String &strDesktop,bool inheritHandle,DWORD desiredAccess,DWORD dwFlags)
: mhDesktop(0)
{
  open(strDesktop,inheritHandle,desiredAccess,dwFlags);
}

inline
Desktop::Desktop(const Desktop &/*someDesktop*/)
{ // private implementation
}

inline
Desktop::~Desktop()
{
}

inline
Desktop &Desktop::operator=(const Desktop &/*someDesktop*/)
{ // private implementation
  return *this;
}

inline
bool Desktop::open(const String &strDesktop,bool inheritHandle,DWORD desiredAccess,DWORD dwFlags)
{
  close();
	if(strDesktop.isNull())return false;
	mStrDesktopName=strDesktop;
	mhDesktop=::OpenDesktop(strDesktop,dwFlags,inheritHandle,desiredAccess);
	return isOkay();
}

inline
void Desktop::close(void)
{
  if(!isOkay())return;
	::CloseDesktop(mhDesktop);
	mhDesktop=0;
}

inline
bool Desktop::activate(void)const
{
  if(!isOkay())return false;
  return ::SwitchDesktop(mhDesktop);
}

inline
const String &Desktop::desktopName(void)const
{
  return mStrDesktopName;
}

inline
bool Desktop::isOkay(void)const
{
  return mhDesktop?true:false;
}

inline
HDESK Desktop::getHandle(void)const
{
  return mhDesktop;
}
#endif
