//
//  Beta release only.
//
//  Copyright(c) Ivyware Pty Ltd 2013  (all rights reserved)
//               MELBOURNE, VICTORIA, AUSTRALIA, 3130
//
//  Provided no fee is charged (either by the distributer or user)
//  permission to use, copy, modify, and distribute this software and
//  its documentation for any purpose and without fee is hereby granted,
//  provided that the above copyright notice appear in all copies and
//  that both that copyright notice and this permission notice appear
//  in supporting documentation.
//
//  No waranty or suitablity for purpose is implied.
//
//
//  Extented IMAPIProp environment wrapper class
//  NOTES: Manages all subordinate IMAPIProp resources
//      
#pragma   once
#include "stdafx.h"
#include "MAPIEx.h"
#include "MAPI_Ext.h"

/////////////////////////////////////////////////////////////
// CMAPIProp

CMAPIProp::CMAPIProp()
{
	  m_pIMAPIProp        = nullptr;
	  m_oSBinEntryID.lpb  = nullptr;
    m_oSBinEntryID.cb   = 0;
}

CMAPIProp::~CMAPIProp()
{
    Close ( );
}

/////////////////////////////////////////////////
//  Operations

//
//  Maps to underlying IMAPIProp::GetProps() method
//
//  Parameters:  ULONG ulProperty
//
//               LPSPropValue& pProp
//
//  Returns:     HRESULT
//               Refer GetP2Pevent() for details
HRESULT
CMAPIProp::GetProperty ( ULONG ulProperty, LPSPropValue& pProp )
{
	  ULONG ulPropCount;
	  ULONG p[2] = { 1, ulProperty };
	  HRESULT hr = m_pIMAPIProp -> GetProps ( (LPSPropTagArray)p, T_MAPI_UNICODE, &ulPropCount, &pProp);
    if ( hr != S_OK )
      EVERR_MAPI ( hr, "IMAPIProp::GetProps() failed" );
    return hr;
}

const GUID
GUIDPublicStrings = { 0x00020329, 0x0000, 0x0000, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 };
HRESULT
CMAPIProp::GetPropTagArray ( LPCTSTR lpszFieldName, LPSPropTagArray& lppPropTags, int& nFieldType, BOOL bCreate)
{
    HRESULT     hr = S_OK;
    MAPINAMEID oMAPInameID;
    oMAPInameID.lpguid = (GUID*)&GUIDPublicStrings;
    oMAPInameID.ulKind = MNID_STRING;
#ifdef UNICODE
    nFieldType=PT_UNICODE;
    nameID.Kind.lpwstrName=(LPWSTR)szFieldName;
#else
    nFieldType = PT_STRING8;
    WCHAR wszFieldName[256];
    MultiByteToWideChar  ( CP_ACP, 0, lpszFieldName, -1, wszFieldName, 255 );
    oMAPInameID.Kind.lpwstrName=wszFieldName;
#endif

    LPMAPINAMEID lpNameID[1] = { &oMAPInameID };
    if ( bCreate )
      hr = m_pIMAPIProp -> GetIDsFromNames ( 1, lpNameID, MAPI_CREATE, &lppPropTags );
    else
      hr = m_pIMAPIProp -> GetIDsFromNames ( 1, lpNameID, 0, &lppPropTags );
    if ( hr != S_OK )
      EVERR_MAPI ( hr, "IMAPIProp::GetIDsFromNames() failed");
    return hr;
}

void
CMAPIProp::SetSBinEntryID ( SBinary* pSBinEntryID )
{
   if ( m_oSBinEntryID.lpb )
     delete [] m_oSBinEntryID.lpb;
   m_oSBinEntryID.lpb = NULL;
   m_oSBinEntryID.cb  = 0;

   if ( pSBinEntryID ) 
   {
     m_oSBinEntryID.cb = pSBinEntryID -> cb;
     if ( m_oSBinEntryID.cb ) 
     {
       m_oSBinEntryID.lpb = new BYTE[m_oSBinEntryID.cb];
       memcpy ( m_oSBinEntryID.lpb, pSBinEntryID->lpb, m_oSBinEntryID.cb );
     }
   } 
}

SBinary*
CMAPIProp::GetSBinEntryID ( )
{
    return &m_oSBinEntryID;
}

void
CMAPIProp::Close ( )
{
    SetSBinEntryID ( NULL );
	  RELEASE(m_pIMAPIProp);
}

HRESULT
CMAPIProp::GetPropertyString ( ULONG ulProperty, CString& strProperty )
{
    strProperty.Empty();
    LPSPropValue pProp;
    if ( GetProperty(ulProperty, pProp) == S_OK ) 
      ThrowP2Pevent ( );
    strProperty=MAPI_GetValidString(*pProp);
    MAPIFreeBuffer(pProp);
    return S_OK;
}

HRESULT
CMAPIProp::GetPropertyViaStream ( ULONG ulProperty, CString& strProperty )
{
    HRESULT hr;
    strProperty.Empty();
    CComPtr<IStream> pIStream;
    hr = m_pIMAPIProp -> OpenProperty ( ulProperty, &IID_IStream, STGM_READ, NULL, (LPUNKNOWN*)&pIStream );
    if ( hr != S_OK )
      return MAPI_HRESULT ( hr, "IMAPIProp::OpenProperty() failed" );

    const int BUF_SIZE = 16383;
    TCHAR szBuf[BUF_SIZE+1];
    ULONG ulNumChars;

    do 
    {
      pIStream -> Read ( szBuf, BUF_SIZE*sizeof(TCHAR), &ulNumChars );
      ulNumChars /= sizeof(TCHAR);
      szBuf[min(BUF_SIZE,ulNumChars)]=0;
      strProperty += szBuf;
    } while ( ulNumChars>=BUF_SIZE );
    return hr;
}

int
CMAPIProp::GetPropertyValue ( ULONG ulProperty, int nDefaultValue )
{
    LPSPropValue pProp;
	  if ( GetProperty(ulProperty, pProp) == S_OK ) 
    {
		  nDefaultValue = pProp->Value.l;
		  MAPIFreeBuffer(pProp);
	  }
	  return nDefaultValue;
}

BOOL
CMAPIProp::SetPropertyString ( ULONG ulProperty, LPCTSTR szProperty, BOOL bStream )
{
	  if ( m_pIMAPIProp && szProperty ) 
	  {
		  if ( bStream )
		  {
			  LPSTREAM pStream=NULL;
			  if(m_pIMAPIProp->OpenProperty(ulProperty, &IID_IStream, 0, MAPI_MODIFY | MAPI_CREATE, (LPUNKNOWN*)&pStream)==S_OK) 
			  {
				  pStream->Write(szProperty, (ULONG)(_tcslen(szProperty)+1)*sizeof(TCHAR), NULL);
				  RELEASE(pStream);
				  return TRUE;
			  }
		  }
		  else
		  {
			  SPropValue prop;
			  prop.ulPropTag=ulProperty;
			  prop.Value.LPSZ=(LPTSTR)szProperty;
			  return (m_pIMAPIProp->SetProps(1, &prop, NULL)==S_OK);
		  }
	  }
	  return FALSE;
}

