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

class Library
{
public:
  Library(void);
	Library(const String &strPathLibrary);
	virtual ~Library();
	Library &operator=(const String &strPathLibrary);
	FARPROC procAddress(const String &strMethod)const;
	BOOL procIn(const String &strMethod)const;
	String strPathLibrary(void)const;
	HINSTANCE getInstance(void)const;
	BOOL isOkay(void)const;
private:
  enum {MaxString=256};
  void load(const String &strPathLibrary);
	void free(void);
	HINSTANCE mhInstance;
	String mStrPathLibrary;
};

inline
Library::Library(void)
: mhInstance(0)
{
  mStrPathLibrary.reserve(MaxString);
}

inline
Library::Library(const String &strPathLibrary)
: mhInstance(0)
{
  load(strPathLibrary);
}

inline
Library::~Library()
{
  free();
}

inline
Library &Library::operator=(const String &strPathLibrary)
{
  load(strPathLibrary);
	return *this;
}

inline
FARPROC Library::procAddress(const String &strMethod)const
{
  if(!isOkay())return FALSE;
	return ::GetProcAddress(mhInstance,strMethod);
}

inline
BOOL Library::procIn(const String &strMethod)const
{
  return procAddress(strMethod)?TRUE:FALSE;;
}

inline
void Library::load(const String &strPathLibrary)
{
  free();
	mhInstance=::LoadLibrary(strPathLibrary);
	if(isOkay())::GetModuleFileName(mhInstance,mStrPathLibrary,MaxString);
}

inline
void Library::free(void)
{
  if(!isOkay())return;
	::FreeLibrary(mhInstance);
	mhInstance=0;
}

inline
String Library::strPathLibrary(void)const
{
  if(!isOkay())return String();
	return mStrPathLibrary;
}

inline
HINSTANCE Library::getInstance(void)const
{
  return mhInstance;
}

inline
BOOL Library::isOkay(void)const
{
  return (mhInstance<HINSTANCE(HINSTANCE_ERROR)?FALSE:TRUE);
}
#endif