/**
 * This file has no copyright assigned and is placed in the Public Domain.
 * This file is part of the w64 mingw-runtime package.
 * No warranty is given; refer to the file DISCLAIMER within this package.
 */
#if !defined(_INC_COMDEF)
#define _INC_COMDEF

#ifndef RC_INVOKED

#ifndef __cplusplus
#error Native Compiler support only available in C++ compiler
#endif

#include <ole2.h>
#include <olectl.h>
#include <comutil.h>

#ifndef WINAPI
#define WINAPI __stdcall
#endif

class _com_error;
void WINAPI _com_raise_error(HRESULT hr,IErrorInfo *perrinfo = 0);
void WINAPI _set_com_error_handler(void (WINAPI *pHandler)(HRESULT hr,IErrorInfo *perrinfo));
void WINAPI _com_issue_error(HRESULT);
void WINAPI _com_issue_errorex(HRESULT,IUnknown*,REFIID);
HRESULT WINAPI _com_dispatch_propget(IDispatch*,DISPID,VARTYPE,void*);
HRESULT __cdecl _com_dispatch_propput(IDispatch*,DISPID,VARTYPE,...);
HRESULT __cdecl _com_dispatch_method(IDispatch*,DISPID,WORD,VARTYPE,void*,const wchar_t*,...);
HRESULT WINAPI _com_dispatch_raw_propget(IDispatch*,DISPID,VARTYPE,void*) throw();
HRESULT __cdecl _com_dispatch_raw_propput(IDispatch*,DISPID,VARTYPE,...) throw();
HRESULT __cdecl _com_dispatch_raw_method(IDispatch*,DISPID,WORD,VARTYPE,void*,const wchar_t*,...) throw();

class _com_error {
public:
  _com_error(HRESULT hr,IErrorInfo *perrinfo = NULL,bool fAddRef = false) throw();
  _com_error(const _com_error &that) throw();
  virtual ~_com_error() throw();
  _com_error &operator=(const _com_error &that) throw();
  HRESULT Error() const throw();
  WORD WCode() const throw();
  IErrorInfo *ErrorInfo() const throw();
  _bstr_t Description() const;
  DWORD HelpContext() const throw();
  _bstr_t HelpFile() const;
  _bstr_t Source() const;
  GUID GUID() const throw();
  const TCHAR *ErrorMessage() const throw();
  static HRESULT WCodeToHRESULT(WORD wCode) throw();
  static WORD HRESULTToWCode(HRESULT hr) throw();
private:
  enum {
    WCODE_HRESULT_FIRST = MAKE_HRESULT(SEVERITY_ERROR,FACILITY_ITF,0x200),WCODE_HRESULT_LAST = MAKE_HRESULT(SEVERITY_ERROR,FACILITY_ITF+1,0) - 1
  };
  const HRESULT m_hresult;
  IErrorInfo *m_perrinfo;
  mutable TCHAR *m_pszMsg;
};

inline _com_error::_com_error(HRESULT hr,IErrorInfo *perrinfo,bool fAddRef) throw() : m_hresult(hr),m_perrinfo(perrinfo),m_pszMsg(NULL) {
  if(m_perrinfo!=NULL && fAddRef) m_perrinfo->AddRef();
}

inline _com_error::_com_error(const _com_error &that) throw() : m_hresult(that.m_hresult),m_perrinfo(that.m_perrinfo),m_pszMsg(NULL) {
  if(m_perrinfo!=NULL) m_perrinfo->AddRef();
}

inline _com_error::~_com_error() throw() {
  if(m_perrinfo!=NULL) m_perrinfo->Release();
  if(m_pszMsg!=NULL) LocalFree((HLOCAL)m_pszMsg);
}

inline _com_error &_com_error::operator=(const _com_error &that) throw() {
  if(this!=&that) {
    this->_com_error::~_com_error();
    this->_com_error::_com_error(that);
  }
  return *this;
}

inline HRESULT _com_error::Error() const throw() { return m_hresult; }
inline WORD _com_error::WCode() const throw() { return HRESULTToWCode(m_hresult); }

inline IErrorInfo *_com_error::ErrorInfo() const throw() {
  if(m_perrinfo!=NULL) m_perrinfo->AddRef();
  return m_perrinfo;
}

inline _bstr_t _com_error::Description() const {
  BSTR bstr = NULL;
  if(m_perrinfo!=NULL) m_perrinfo->GetDescription(&bstr);
  return _bstr_t(bstr,false);
}

inline DWORD _com_error::HelpContext() const throw() {
  DWORD dwHelpContext = 0;
  if(m_perrinfo!=NULL) m_perrinfo->GetHelpContext(&dwHelpContext);
  return dwHelpContext;
}

inline _bstr_t _com_error::HelpFile() const {
  BSTR bstr = NULL;
  if(m_perrinfo!=NULL)  m_perrinfo->GetHelpFile(&bstr);
  return _bstr_t(bstr,false);
}

inline _bstr_t _com_error::Source() const {
  BSTR bstr = NULL;
  if(m_perrinfo!=NULL) m_perrinfo->GetSource(&bstr);
  return _bstr_t(bstr,false);
}

inline _GUID _com_error::GUID() const throw() {
  _GUID guid;
  _COM_MEMCPY_S(&guid,sizeof(_GUID),&__uuidof(NULL),sizeof(_GUID));
  if(m_perrinfo!=NULL) m_perrinfo->GetGUID(&guid);
  return guid;
}

inline const TCHAR *_com_error::ErrorMessage() const throw() {
  if(!m_pszMsg) {
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,NULL,m_hresult,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPTSTR)&m_pszMsg,0,NULL);
    if(m_pszMsg!=NULL) {
      int nLen = lstrlen(m_pszMsg);
      if(nLen > 1 && m_pszMsg[nLen - 1]=='\n') {
	m_pszMsg[nLen-1] = 0;
	if(m_pszMsg[nLen - 2]=='\r') m_pszMsg[nLen-2] = 0;
      }
    } else {
      m_pszMsg = (LPTSTR)LocalAlloc(0,32 *sizeof(TCHAR));
      if(m_pszMsg!=NULL) {
	WORD wCode = WCode();
	if(wCode!=0) {
	  _COM_PRINTF_S_1(m_pszMsg,32,TEXT("IDispatch error #%d"),wCode);
	} else {
	  _COM_PRINTF_S_1(m_pszMsg,32,TEXT("Unknown error 0x%0lX"),m_hresult);
	}
      }
    }
  }
  return m_pszMsg;
}

inline HRESULT _com_error::WCodeToHRESULT(WORD wCode) throw() { return wCode >= 0xFE00 ? WCODE_HRESULT_LAST : WCODE_HRESULT_FIRST + wCode; }
inline WORD _com_error::HRESULTToWCode(HRESULT hr) throw() { return (hr >= WCODE_HRESULT_FIRST && hr <= WCODE_HRESULT_LAST) ? WORD(hr - WCODE_HRESULT_FIRST) : 0; }

typedef int __missing_type__;

#if !defined(_COM_SMARTPTR)
#if !defined(_INC_COMIP)
#include <comip.h>
#endif
#define _COM_SMARTPTR _com_ptr_t
#define _COM_SMARTPTR_LEVEL2 _com_IIID
#endif
#if defined(_COM_SMARTPTR)
#if !defined(_COM_SMARTPTR_TYPEDEF)
#if defined(_COM_SMARTPTR_LEVEL2)
#define _COM_SMARTPTR_TYPEDEF(Interface,IID) typedef _COM_SMARTPTR<_COM_SMARTPTR_LEVEL2<Interface,&IID> > Interface ## Ptr
#else
#define _COM_SMARTPTR_TYPEDEF(Interface,IID) typedef _COM_SMARTPTR<Interface,&IID> Interface ## Ptr
#endif
#endif
#endif

#if !defined(_COM_NO_STANDARD_GUIDS_)
#if defined(__IFontDisp_INTERFACE_DEFINED__)
__if_not_exists(Font)
{
  struct Font : IFontDisp {};
}
_COM_SMARTPTR_TYPEDEF(Font,__uuidof(IDispatch));
#endif
#if defined(__IFontEventsDisp_INTERFACE_DEFINED__)
__if_not_exists(FontEvents)
{
  struct FontEvents : IFontEventsDisp {};
}
_COM_SMARTPTR_TYPEDEF(FontEvents,__uuidof(IDispatch));
#endif
#if defined(__IPictureDisp_INTERFACE_DEFINED__)
__if_not_exists(Picture)
{
  struct Picture : IPictureDisp {};
}
_COM_SMARTPTR_TYPEDEF(Picture,__uuidof(IDispatch));
#endif

#include "comdefsp.h"
#endif
#endif
#endif
