/**
 * This file has no copyright assigned and is placed in the Public Domain.
 * This file is part of the mingw-w64 runtime package.
 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
 */
#ifndef _INC_COMIP
#define _INC_COMIP

#include <_mingw.h>

#include <ole2.h>
#include <malloc.h>

#include <comutil.h>

#ifdef __cplusplus

#pragma push_macro("new")
#undef new

#include <new.h>

class _com_error;

#ifndef WINAPI
#define WINAPI __stdcall
#endif

void WINAPI _com_issue_error(HRESULT);
struct IUnknown;

template<typename _Interface,const IID *_IID >
class _com_IIID {
public:
  typedef _Interface Interface;
  static _Interface *GetInterfacePtr() throw() { return NULL; }
  static _Interface& GetInterface() throw() { return *GetInterfacePtr(); }
  static const IID& GetIID() throw() { return *_IID; }
};

template<typename _IIID> class _com_ptr_t {
public:
  typedef _IIID ThisIIID;
  typedef typename _IIID::Interface Interface;
  static const IID& GetIID() throw() { return ThisIIID::GetIID(); }
  template<typename _OtherIID> _com_ptr_t(const _com_ptr_t<_OtherIID> &p) : m_pInterface(NULL) {
    HRESULT hr = _QueryInterface(p);
    if(FAILED(hr) && (hr!=E_NOINTERFACE)) { _com_issue_error(hr); }
  }
  template<typename _InterfaceType> _com_ptr_t(_InterfaceType *p) : m_pInterface(NULL) {
    HRESULT hr = _QueryInterface(p);
    if(FAILED(hr) && (hr!=E_NOINTERFACE)) { _com_issue_error(hr); }
  }
  template<typename _X> _com_ptr_t(LPSTR str) { new(this) _com_ptr_t(static_cast<LPCSTR> (str),NULL); }
  template<typename _X> _com_ptr_t(LPWSTR str) { new(this) _com_ptr_t(static_cast<LPCWSTR> (str),NULL); }
  template<typename _X> explicit _com_ptr_t(_com_ptr_t *p) : m_pInterface(NULL) {
    if(!p) { _com_issue_error(E_POINTER); }
    else {
      m_pInterface = p->m_pInterface;
      AddRef();
    }
  }
  _com_ptr_t() throw() : m_pInterface(NULL) { }
  _com_ptr_t(int null) : m_pInterface(NULL) {
    if(null!=0) { _com_issue_error(E_POINTER); }
  }

#ifdef _NATIVE_NULLPTR_SUPPORTED
  _com_ptr_t(decltype(nullptr)) : m_pInterface(NULL) {}
#endif

  _com_ptr_t(const _com_ptr_t &cp) throw() : m_pInterface(cp.m_pInterface) { _AddRef(); }
  template<typename _X> _com_ptr_t(Interface *pInterface) throw() : m_pInterface(pInterface) { _AddRef(); }
  _com_ptr_t(Interface *pInterface,bool fAddRef) throw() : m_pInterface(pInterface) {
    if(fAddRef) _AddRef();
  }
  _com_ptr_t(const _variant_t& varSrc) : m_pInterface(NULL) {
    HRESULT hr = QueryStdInterfaces(varSrc);
    if(FAILED(hr) && (hr!=E_NOINTERFACE)) { _com_issue_error(hr); }
  }
  explicit _com_ptr_t(const CLSID &clsid,IUnknown *pOuter = NULL,DWORD dwClsContext = CLSCTX_ALL) : m_pInterface(NULL) {
    HRESULT hr = CreateInstance(clsid,pOuter,dwClsContext);
    if(FAILED(hr) && (hr!=E_NOINTERFACE)) { _com_issue_error(hr); }
  }
  explicit _com_ptr_t(LPCWSTR str,IUnknown *pOuter = NULL,DWORD dwClsContext = CLSCTX_ALL) : m_pInterface(NULL) {
    HRESULT hr = CreateInstance(str,pOuter,dwClsContext);
    if(FAILED(hr) && (hr!=E_NOINTERFACE)) { _com_issue_error(hr); }
  }
  explicit _com_ptr_t(LPCSTR str,IUnknown *pOuter = NULL,DWORD dwClsContext = CLSCTX_ALL) : m_pInterface(NULL) {
    HRESULT hr = CreateInstance(str,pOuter,dwClsContext);
    if(FAILED(hr) && (hr!=E_NOINTERFACE)) { _com_issue_error(hr); }
  }
  template<typename _OtherIID> _com_ptr_t &operator=(const _com_ptr_t<_OtherIID> &p) {
    HRESULT hr = _QueryInterface(p);
    if(FAILED(hr) && (hr!=E_NOINTERFACE)) { _com_issue_error(hr); }
    return *this;
  }
  template<typename _InterfaceType> _com_ptr_t &operator=(_InterfaceType *p) {
    HRESULT hr = _QueryInterface(p);
    if(FAILED(hr) && (hr!=E_NOINTERFACE)) { _com_issue_error(hr); }
    return *this;
  }
  template<typename _X> _com_ptr_t &operator=(Interface *pInterface) throw() {
    if(m_pInterface!=pInterface) {
      Interface *pOldInterface = m_pInterface;
      m_pInterface = pInterface;
      _AddRef();
      if(pOldInterface!=NULL) pOldInterface->Release();
    }
    return *this;
  }
  _com_ptr_t &operator=(const _com_ptr_t &cp) throw() { return operator=(cp.m_pInterface); }
  _com_ptr_t &operator=(int null) {
    if(null!=0) { _com_issue_error(E_POINTER); }
    return operator=(reinterpret_cast<Interface*>(NULL));
  }
  _com_ptr_t &operator=(const _variant_t& varSrc) {
    HRESULT hr = QueryStdInterfaces(varSrc);
    if(FAILED(hr) && (hr!=E_NOINTERFACE)) { _com_issue_error(hr); }
    return *this;
  }
  ~_com_ptr_t() throw() { _Release(); }
  void Attach(Interface *pInterface) throw() {
    _Release();
    m_pInterface = pInterface;
  }
  void Attach(Interface *pInterface,bool fAddRef) throw() {
    _Release();
    m_pInterface = pInterface;
    if(fAddRef) {
      if(!pInterface) { _com_issue_error(E_POINTER); }
      else pInterface->AddRef();
    }
  }
  Interface *Detach() throw() {
    Interface *const old = m_pInterface;
    m_pInterface = NULL;
    return old;
  }
  operator Interface*() const throw() { return m_pInterface; }
  operator Interface&() const {
    if(!m_pInterface) { _com_issue_error(E_POINTER); }
    return *m_pInterface;
  }
  Interface& operator*() const {
    if(!m_pInterface) { _com_issue_error(E_POINTER); }
    return *m_pInterface;
  }
  Interface **operator&() throw() {
    _Release();
    m_pInterface = NULL;
    return &m_pInterface;
  }
  Interface *operator->() const {
    if(!m_pInterface) { _com_issue_error(E_POINTER); }
    return m_pInterface;
  }
  operator bool() const throw() { return m_pInterface!=NULL; }
  template<typename _OtherIID> bool operator==(const _com_ptr_t<_OtherIID> &p) { return _CompareUnknown(p)==0; }
  template<typename _OtherIID> bool operator==(_com_ptr_t<_OtherIID> &p) { return _CompareUnknown(p)==0; }
  template<typename _InterfaceType> bool operator==(_InterfaceType *p) { return _CompareUnknown(p)==0; }
  template<typename _X> bool operator==(Interface *p) { return (m_pInterface==p) ? true : _CompareUnknown(p)==0; }
  template<typename _X> bool operator==(const _com_ptr_t &p) throw() { return operator==(p.m_pInterface); }
  template<typename _X> bool operator==(_com_ptr_t &p) throw() { return operator==(p.m_pInterface); }
  bool operator==(int null) {
    if(null!=0) { _com_issue_error(E_POINTER); }
    return !m_pInterface;
  }
  template<typename _OtherIID> bool operator!=(const _com_ptr_t<_OtherIID> &p) { return !(operator==(p)); }
  template<typename _OtherIID> bool operator!=(_com_ptr_t<_OtherIID> &p) { return !(operator==(p)); }
  template<typename _InterfaceType> bool operator!=(_InterfaceType *p) { return !(operator==(p)); }
  bool operator!=(int null) { return !(operator==(null)); }
  template<typename _OtherIID> bool operator<(const _com_ptr_t<_OtherIID> &p) { return _CompareUnknown(p)<0; }
  template<typename _OtherIID> bool operator<(_com_ptr_t<_OtherIID> &p) { return _CompareUnknown(p)<0; }
  template<typename _InterfaceType> bool operator<(_InterfaceType *p) { return _CompareUnknown(p)<0; }
  template<typename _OtherIID> bool operator>(const _com_ptr_t<_OtherIID> &p) { return _CompareUnknown(p)>0; }
  template<typename _OtherIID> bool operator>(_com_ptr_t<_OtherIID> &p) { return _CompareUnknown(p)>0; }
  template<typename _InterfaceType> bool operator>(_InterfaceType *p) { return _CompareUnknown(p)>0; }
  template<typename _OtherIID> bool operator<=(const _com_ptr_t<_OtherIID> &p) { return _CompareUnknown(p)<=0; }
  template<typename _OtherIID> bool operator<=(_com_ptr_t<_OtherIID> &p) { return _CompareUnknown(p)<=0; }
  template<typename _InterfaceType> bool operator<=(_InterfaceType *p) { return _CompareUnknown(p)<=0; }
  template<typename _OtherIID> bool operator>=(const _com_ptr_t<_OtherIID> &p) { return _CompareUnknown(p)>=0; }
  template<typename _OtherIID> bool operator>=(_com_ptr_t<_OtherIID> &p) { return _CompareUnknown(p)>=0; }
  template<typename _InterfaceType> bool operator>=(_InterfaceType *p) { return _CompareUnknown(p)>=0; }
  void Release() {
    if(!m_pInterface) { _com_issue_error(E_POINTER); }
    else {
      m_pInterface->Release();
      m_pInterface = NULL;
    }
  }
  void AddRef() {
    if(!m_pInterface) { _com_issue_error(E_POINTER); }
    else m_pInterface->AddRef();
  }
  Interface *GetInterfacePtr() const throw() { return m_pInterface; }
  Interface*& GetInterfacePtr() throw() { return m_pInterface; }
  HRESULT CreateInstance(const CLSID &rclsid,IUnknown *pOuter = NULL,DWORD dwClsContext = CLSCTX_ALL) throw() {
    HRESULT hr;
    _Release();
    if(dwClsContext & (CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER)) {
      IUnknown *pIUnknown;
      hr = CoCreateInstance(rclsid,pOuter,dwClsContext,__uuidof(IUnknown),reinterpret_cast<void**>(&pIUnknown));
      if(SUCCEEDED(hr)) {
	hr = OleRun(pIUnknown);
	if(SUCCEEDED(hr)) hr = pIUnknown->QueryInterface(GetIID(),reinterpret_cast<void**>(&m_pInterface));
	pIUnknown->Release();
      }
    } else hr = CoCreateInstance(rclsid,pOuter,dwClsContext,GetIID(),reinterpret_cast<void**>(&m_pInterface));
    if(FAILED(hr)) m_pInterface = NULL;
    return hr;
  }
  HRESULT CreateInstance(LPCWSTR clsidString,IUnknown *pOuter = NULL,DWORD dwClsContext = CLSCTX_ALL) throw() {
    if(!clsidString) return E_INVALIDARG;
    CLSID clsid;
    HRESULT hr;
    if(clsidString[0]==L'{') hr = CLSIDFromString(const_cast<LPWSTR> (clsidString),&clsid);
    else hr = CLSIDFromProgID(const_cast<LPWSTR> (clsidString),&clsid);
    if(FAILED(hr)) return hr;
    return CreateInstance(clsid,pOuter,dwClsContext);
  }
  HRESULT CreateInstance(LPCSTR clsidStringA,IUnknown *pOuter = NULL,DWORD dwClsContext = CLSCTX_ALL) throw() {
    if(!clsidStringA) return E_INVALIDARG;
    int size = lstrlenA(clsidStringA) + 1;
    int destSize = MultiByteToWideChar(CP_ACP,0,clsidStringA,size,NULL,0);
    if(destSize==0) return HRESULT_FROM_WIN32(GetLastError());
    LPWSTR clsidStringW;
    clsidStringW = static_cast<LPWSTR>(_malloca(destSize*sizeof(WCHAR)));
    if(!clsidStringW) return E_OUTOFMEMORY;
    if(MultiByteToWideChar(CP_ACP,0,clsidStringA,size,clsidStringW,destSize)==0) {
      _freea(clsidStringW);
      return HRESULT_FROM_WIN32(GetLastError());
    }
    HRESULT hr=CreateInstance(clsidStringW,pOuter,dwClsContext);
    _freea(clsidStringW);
    return hr;
  }
  HRESULT GetActiveObject(const CLSID &rclsid) throw() {
    _Release();
    IUnknown *pIUnknown;
    HRESULT hr = ::GetActiveObject(rclsid,NULL,&pIUnknown);
    if(SUCCEEDED(hr)) {
      hr = pIUnknown->QueryInterface(GetIID(),reinterpret_cast<void**>(&m_pInterface));
      pIUnknown->Release();
    }
    if(FAILED(hr)) m_pInterface = NULL;
    return hr;
  }
  HRESULT GetActiveObject(LPCWSTR clsidString) throw() {
    if(!clsidString) return E_INVALIDARG;
    CLSID clsid;
    HRESULT hr;
    if(clsidString[0]=='{') hr = CLSIDFromString(const_cast<LPWSTR> (clsidString),&clsid);
    else hr = CLSIDFromProgID(const_cast<LPWSTR> (clsidString),&clsid);
    if(FAILED(hr)) return hr;
    return GetActiveObject(clsid);
  }
  HRESULT GetActiveObject(LPCSTR clsidStringA) throw() {
    if(!clsidStringA) return E_INVALIDARG;
    int size = lstrlenA(clsidStringA) + 1;
    int destSize = MultiByteToWideChar(CP_ACP,0,clsidStringA,size,NULL,0);
    LPWSTR clsidStringW;
    try {
      clsidStringW = static_cast<LPWSTR>(_alloca(destSize*sizeof(WCHAR)));
    } catch (...) {
      clsidStringW = NULL;
    }
    if(!clsidStringW) return E_OUTOFMEMORY;
    if(MultiByteToWideChar(CP_ACP,0,clsidStringA,size,clsidStringW,destSize)==0) return HRESULT_FROM_WIN32(GetLastError());
    return GetActiveObject(clsidStringW);
  }
  template<typename _InterfaceType> HRESULT QueryInterface(const IID& iid,_InterfaceType*& p) throw () {
    if(m_pInterface!=NULL) return m_pInterface->QueryInterface(iid,reinterpret_cast<void**>(&p));
    return E_POINTER;
  }
  template<typename _InterfaceType> HRESULT QueryInterface(const IID& iid,_InterfaceType **p) throw() { return QueryInterface(iid,*p); }
private:
  Interface *m_pInterface;
  void _Release() throw() {
    if(m_pInterface!=NULL) m_pInterface->Release();
  }
  void _AddRef() throw() {
    if(m_pInterface!=NULL) m_pInterface->AddRef();
  }
  template<typename _InterfacePtr> HRESULT _QueryInterface(_InterfacePtr p) throw() {
    HRESULT hr;
    if(p!=NULL) {
      Interface *pInterface;
      hr = p->QueryInterface(GetIID(),reinterpret_cast<void**>(&pInterface));
      Attach(SUCCEEDED(hr)? pInterface: NULL);
    } else {
      operator=(static_cast<Interface*>(NULL));
      hr = E_NOINTERFACE;
    }
    return hr;
  }
  template<typename _InterfacePtr> int _CompareUnknown(_InterfacePtr p) {
    IUnknown *pu1,*pu2;
    if(m_pInterface!=NULL) {
      HRESULT hr = m_pInterface->QueryInterface(__uuidof(IUnknown),reinterpret_cast<void**>(&pu1));
      if(FAILED(hr)) {
	_com_issue_error(hr);
	pu1 = NULL;
      } else pu1->Release();
    } else pu1 = NULL;
    if(p!=NULL) {
      HRESULT hr = p->QueryInterface(__uuidof(IUnknown),reinterpret_cast<void**>(&pu2));
      if(FAILED(hr)) {
	_com_issue_error(hr);
	pu2 = NULL;
      } else pu2->Release();
    } else pu2 = NULL;
    return pu1 - pu2;
  }
  HRESULT QueryStdInterfaces(const _variant_t& varSrc) throw() {
    if(V_VT(&varSrc)==VT_DISPATCH) return _QueryInterface(V_DISPATCH(&varSrc));
    if(V_VT(&varSrc)==VT_UNKNOWN) return _QueryInterface(V_UNKNOWN(&varSrc));
    VARIANT varDest;
    VariantInit(&varDest);
    HRESULT hr = VariantChangeType(&varDest,const_cast<VARIANT*>(static_cast<const VARIANT*>(&varSrc)),0,VT_DISPATCH);
    if(SUCCEEDED(hr)) hr = _QueryInterface(V_DISPATCH(&varSrc));
    if(hr==E_NOINTERFACE) {
      VariantInit(&varDest);
      hr = VariantChangeType(&varDest,const_cast<VARIANT*>(static_cast<const VARIANT*>(&varSrc)),0,VT_UNKNOWN);
      if(SUCCEEDED(hr)) hr = _QueryInterface(V_UNKNOWN(&varSrc));
    }
    VariantClear(&varDest);
    return hr;
  }
};

template<typename _InterfaceType> bool operator==(int null,_com_ptr_t<_InterfaceType> &p) {
  if(null!=0) { _com_issue_error(E_POINTER); }
  return !p;
}

template<typename _Interface,typename _InterfacePtr> bool operator==(_Interface *i,_com_ptr_t<_InterfacePtr> &p) { return p==i; }

template<typename _Interface> bool operator!=(int null,_com_ptr_t<_Interface> &p) {
  if(null!=0) { _com_issue_error(E_POINTER); }
  return p!=NULL;
}

template<typename _Interface,typename _InterfacePtr> bool operator!=(_Interface *i,_com_ptr_t<_InterfacePtr> &p) { return p!=i; }

template<typename _Interface> bool operator<(int null,_com_ptr_t<_Interface> &p) {
  if(null!=0) { _com_issue_error(E_POINTER); }
  return p>NULL;
}

template<typename _Interface,typename _InterfacePtr> bool operator<(_Interface *i,_com_ptr_t<_InterfacePtr> &p) { return p>i; }

template<typename _Interface> bool operator>(int null,_com_ptr_t<_Interface> &p) {
  if(null!=0) { _com_issue_error(E_POINTER); }
  return p<NULL;
}

template<typename _Interface,typename _InterfacePtr> bool operator>(_Interface *i,_com_ptr_t<_InterfacePtr> &p) { return p<i; }

template<typename _Interface> bool operator<=(int null,_com_ptr_t<_Interface> &p) {
  if(null!=0) { _com_issue_error(E_POINTER); }
  return p>=NULL;
}

template<typename _Interface,typename _InterfacePtr> bool operator<=(_Interface *i,_com_ptr_t<_InterfacePtr> &p) { return p>=i; }

template<typename _Interface> bool operator>=(int null,_com_ptr_t<_Interface> &p) {
  if(null!=0) { _com_issue_error(E_POINTER); }
  return p<=NULL;
}

template<typename _Interface,typename _InterfacePtr> bool operator>=(_Interface *i,_com_ptr_t<_InterfacePtr> &p) { return p<=i; }

#pragma pop_macro("new")

#endif /* __cplusplus */

#endif /* _INC_COMIP */
