#ifndef _COMMON_VERSIONINFO_HPP_
#define _COMMON_VERSIONINFO_HPP_
#ifndef _COMMON_GLOBALDATA_HPP_
#include <common/gdata.hpp>
#endif
#ifndef _COMMON_STDIO_HPP_
#include <common/stdio.hpp>
#endif
#ifndef _COMMON_STRING_HPP_
#include <common/string.hpp>
#endif

// reads the VERSIONINFO from the application's resource file.

class VersionInfo
{
public:
  VersionInfo();
	VersionInfo(const String &strPathModuleName);
	virtual ~VersionInfo();
  String getProductNameString(void)const;
	String getProductVersionString(void)const;
	String getProductVersion(void)const;
	bool isOkay(void)const;
private:
  bool getVersionInfo(const String &strPathModuleName);
	bool getTranslation(void)const;
  String mStrPathModuleName;
	String mTranslation;
	GlobalData<BYTE> mVersionInfo;
	bool mHaveVersionInfo;

};

inline
VersionInfo::VersionInfo()
{
  String strPathModuleName;
	::GetModuleFileName(0,strPathModuleName.str(),String::MaxString);
	getVersionInfo(strPathModuleName);
}

inline
VersionInfo::VersionInfo(const String &strPathModuleName)
{
  getVersionInfo(strPathModuleName);
}

inline
VersionInfo::~VersionInfo()
{
}

inline
String VersionInfo::getProductVersionString(void)const
{
  if(!isOkay())return String();
	unsigned int sizeInfo=0;
	char *pProductVersion;
  ::VerQueryValue(&((GlobalData<BYTE>&)mVersionInfo)[0],String("\\StringFileInfo\\")+mTranslation+String("\\ProductVersion"),(void**)&pProductVersion,&sizeInfo); 
	return pProductVersion;
}

inline
String VersionInfo::getProductNameString(void)const
{
  if(!isOkay())return String();
	unsigned int sizeInfo=0;
	char *pProductName;
  ::VerQueryValue(&((GlobalData<BYTE>&)mVersionInfo)[0],String("\\StringFileInfo\\")+mTranslation+String("\\ProductName"),(void**)&pProductName,&sizeInfo); 
	return pProductName;
}

inline
String VersionInfo::getProductVersion(void)const
{
	String strProductVersion;
	String strProductVersionMaj;
	String strProductVersionMin;

  if(!isOkay())return String();
	strProductVersion=getProductVersionString();
	strProductVersionMaj=strProductVersion.betweenString(0,',');
	strProductVersionMin=strProductVersion.betweenString(',',0);
	strProductVersionMin.removeTokens(", ");
	strProductVersion=String("v")+strProductVersionMaj+String(".")+strProductVersionMin;
	return strProductVersion;
}

inline
bool VersionInfo::getVersionInfo(const String &strPathModuleName)
{
  DWORD sizeInfo;
  mHaveVersionInfo=false;
	if(!(sizeInfo=::GetFileVersionInfoSize((char*)strPathModuleName.str(),&sizeInfo)))return false;
	mVersionInfo.size(sizeInfo);
	if(!::GetFileVersionInfo(strPathModuleName,0,sizeInfo,&mVersionInfo[0]))return false;
	mHaveVersionInfo=true;
	getTranslation();
	return mHaveVersionInfo;
}

inline
bool VersionInfo::getTranslation(void)const
{
  if(!isOkay())return String();
	unsigned int sizeInfo=0;
	DWORD *pTranslation;
  ::VerQueryValue(&((GlobalData<BYTE>&)mVersionInfo)[0],TEXT("\\VarFileInfo\\Translation"),(void**)&pTranslation,&sizeInfo); 
	::sprintf(mTranslation,"%04x%04x",LOWORD(*pTranslation),HIWORD(*pTranslation));
	return true;
}

inline
bool VersionInfo::isOkay(void)const
{
  return mHaveVersionInfo;
}


#endif