/**
 * 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.PD within this package.
 */
#ifndef _MSPCOLL_H_
#define _MSPCOLL_H_

template <class T> class CTapiIfCollection : public IDispatchImpl<ITCollection,&IID_ITCollection,&LIBID_TAPI3Lib>,public CComObjectRootEx<CComMultiThreadModelNoCS>
{
public:
  typedef CTapiIfCollection<T> _CTapiCollectionBase;
  BEGIN_COM_MAP(_CTapiCollectionBase)
    COM_INTERFACE_ENTRY(IDispatch)
    COM_INTERFACE_ENTRY(ITCollection)
  END_COM_MAP()
private:
  int m_nSize;
  CComVariant *m_Var;

public:
  CTapiIfCollection(void) : m_nSize(0),m_Var(NULL) { }
  HRESULT WINAPI Initialize(DWORD dwSize,T *pBegin,T *pEnd) {
    int i;
    HRESULT hr;
    T *iter;
    LOG((MSP_TRACE,"CTapiCollection::Initialize - enter"));
    m_nSize = dwSize;
    m_Var = new CComVariant[m_nSize];
    if(!m_Var) return E_OUTOFMEMORY;
    i = 0;
    for(iter = pBegin;iter!=pEnd;iter++) {
      IDispatch *pDisp = NULL;
      hr = (*iter)->QueryInterface(IID_IDispatch,(void**)&pDisp);
      if(hr!=S_OK) return hr;
      CComVariant& var = m_Var[i];
      VariantInit(&var);
      var.vt = VT_DISPATCH;
      var.pdispVal = pDisp;
      i++;
    }
    LOG((MSP_TRACE,"CTapiCollection::Initialize - exit"));
    return S_OK;
  }
  void FinalRelease() {
    LOG((MSP_TRACE,"CTapiCollection::FinalRelease - enter"));
    delete [] m_Var;
    LOG((MSP_TRACE,"CTapiCollection::FinalRelease - exit"));
  }
  STDMETHOD(get_Count)(long *retval) {
    HRESULT hr = S_OK;
    LOG((MSP_TRACE,"CTapiCollection::get_Count - enter"));
    try {
      *retval = m_nSize;
    } catch(...) {
      hr = E_INVALIDARG;
    }
    LOG((MSP_TRACE,"CTapiCollection::get_Count - exit"));
    return hr;
  }
  STDMETHOD(get_Item)(long Index,VARIANT *retval) {
    HRESULT hr = S_OK;
    LOG((MSP_TRACE,"CTapiCollection::get_Item - enter"));
    if(!retval) return E_POINTER;
    try {
      VariantInit(retval);
    } catch(...) {
      hr = E_INVALIDARG;
    }
    if(hr!=S_OK) return hr;
    retval->vt = VT_UNKNOWN;
    retval->punkVal = NULL;
    if((Index < 1) || (Index > m_nSize)) return E_INVALIDARG;
    hr = VariantCopy(retval,&m_Var[Index-1]);
    if(FAILED(hr)) {
      LOG((MSP_ERROR,"CTapiCollection::get_Item - VariantCopy failed. hr = %lx",hr));
      return hr;
    }
    LOG((MSP_TRACE,"CTapiCollection::get_Item - exit"));
    return S_OK;
  }
  HRESULT WINAPI get__NewEnum(IUnknown **retval) {
    HRESULT hr;
    LOG((MSP_TRACE,"CTapiCollection::new__Enum - enter"));
    if(!retval) return E_POINTER;
    *retval = NULL;
    typedef CComObject<CSafeComEnum<IEnumVARIANT,&IID_IEnumVARIANT,VARIANT,_Copy<VARIANT> > > enumvar;
    enumvar *p;
    hr = enumvar::CreateInstance(&p);
    if(FAILED(hr)) return hr;
    hr = p->Init(&m_Var[0],&m_Var[m_nSize],NULL,AtlFlagCopy);
    if(SUCCEEDED(hr)) hr = p->QueryInterface(IID_IEnumVARIANT,(void**)retval);
    if(FAILED(hr)) delete p;
    LOG((MSP_TRACE,"CTapiCollection::new__Enum - exit"));
    return hr;
  }
};

class CTapiBstrCollection : public CComObjectRootEx<CComMultiThreadModelNoCS>,public IDispatchImpl<ITCollection,&IID_ITCollection,&LIBID_TAPI3Lib>,public CMSPObjectSafetyImpl
{
public:
  BEGIN_COM_MAP(CTapiBstrCollection)
    COM_INTERFACE_ENTRY(IDispatch)
    COM_INTERFACE_ENTRY(ITCollection)
    COM_INTERFACE_ENTRY(IObjectSafety)
  END_COM_MAP()
private:
  DWORD m_dwSize;
  CComVariant *m_Var;
public:
  CTapiBstrCollection(void) : m_dwSize(0),m_Var(NULL) { }
  HRESULT WINAPI Initialize(DWORD dwSize,BSTR *pBegin,BSTR *pEnd) {
    BSTR *i;
    DWORD dw = 0;
    LOG((MSP_TRACE,"CTapiBstrCollection::Initialize - enter"));
    m_dwSize = dwSize;
    m_Var = new CComVariant[m_dwSize];
    if(!m_Var) return E_OUTOFMEMORY;
    for(i = pBegin;i!=pEnd;i++) {
      CComVariant& var = m_Var[dw];
      var.vt = VT_BSTR;
      var.bstrVal = *i;
      dw++;
    }
    LOG((MSP_TRACE,"CTapiBstrCollection::Initialize - exit"));
    return S_OK;
  }
  STDMETHOD(get_Count)(long *retval) {
    HRESULT hr = S_OK;
    LOG((MSP_TRACE,"CTapiBstrCollection::get_Count - enter"));
    try {
      *retval = m_dwSize;
    } catch(...) {
      hr = E_INVALIDARG;
    }
    LOG((MSP_TRACE,"CTapiBstrCollection::get_Count - exit"));
    return hr;
  }
  STDMETHOD(get_Item)(long Index,VARIANT *retval) {
    HRESULT hr = S_OK;
    LOG((MSP_TRACE,"CTapiBstrCollection::get_Item - enter"));
    if(!retval) return E_POINTER;
    try {
      VariantInit(retval);
    } catch(...) {
      hr = E_INVALIDARG;
    }
    if(hr!=S_OK) return hr;
    retval->vt = VT_BSTR;
    retval->bstrVal = NULL;
    if((Index < 1) || ((DWORD) Index > m_dwSize)) return E_INVALIDARG;
    hr = VariantCopy(retval,&m_Var[Index-1]);
    if(FAILED(hr)) {
      LOG((MSP_ERROR,"CTapiBstrCollection::get_Item - VariantCopy failed. hr = %lx",hr));
      return hr;
    }
    LOG((MSP_TRACE,"CTapiBstrCollection::get_Item - exit"));
    return S_OK;
  }
  HRESULT WINAPI get__NewEnum(IUnknown **retval) {
    HRESULT hr;
    LOG((MSP_TRACE,"CTapiBstrCollection::get__NumEnum - enter"));
    if(!retval) return E_POINTER;
    *retval = NULL;
    typedef CComObject<CSafeComEnum<IEnumVARIANT,&IID_IEnumVARIANT,VARIANT,_Copy<VARIANT> > > enumvar;
    enumvar *p = new enumvar;
    if(!p) return E_OUTOFMEMORY;
    hr = p->Init(&m_Var[0],&m_Var[m_dwSize],NULL,AtlFlagCopy);
    if(SUCCEEDED(hr)) {
      hr = p->QueryInterface(IID_IEnumVARIANT,(void**)retval);
    }
    if(FAILED(hr)) delete p;
    LOG((MSP_TRACE,"CTapiBstrCollection::get__NewEnum - exit"));
    return hr;
  }
  void FinalRelease() {
    LOG((MSP_TRACE,"CTapiBstrCollection::FinalRelease() - enter"));
    delete [] m_Var;
    LOG((MSP_TRACE,"CTapiBstrCollection::FinalRelease() - exit"));
  }
};
#endif
