//
//  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.
//
//
//  IMsgStore interface wrapper class implementation
//  NOTES: Manages all subordinate IMsgStore resources
//      

#include "stdafx.h"
#include "P2Pevent.h"
#include "MAPIEx.h"
#include "MsgStore.h"
#include "MAPI_Ext.h"

#pragma comment (lib,"mapi32.lib")
#pragma comment(lib,"Ole32.lib")

/////////////////////////////////////////////////////////////
// CMsgStore constructors and destructor

CMsgStore::CMsgStore ( CMAPISession *pMAPISession, IMsgStore *pIMsgStore, ULONG ulMDBFlags )
{
    m_pMAPISession  = pMAPISession;
    m_ulMDBFlags    = ulMDBFlags;
	  m_pIMsgStore    = pIMsgStore;
    m_pIMsgStore->AddRef ();
}

CMsgStore::~CMsgStore()
{
    RELEASE(m_pIMsgStore);
}

///////////////////////////////////////////////////////////////////////////////
//  Folder query factories
//  NOTES: Externally client managed life cycle

CMAPIFolder*
CMsgStore::Query4RootFolder ( )
{
    return Query4Folder ( PR_IPM_SUBTREE_ENTRYID );
}

CMAPIFolder*
CMsgStore::Query4Folder ( unsigned long ulFolderID )
{
    HRESULT      hr = S_OK;
    LPSPropValue props=nullptr;
    ULONG        cValues=0;
    DWORD        dwObjType;
    ULONG        rgTags[]={ 1, ulFolderID };
    CComPtr<IMAPIFolder> pIMAPIFolder;

    hr =  m_pIMsgStore -> GetProps ( (LPSPropTagArray)rgTags, T_MAPI_UNICODE, &cValues, &props );
    if ( hr != S_OK )
    {
      MAPI_HRESULT(hr,"IMsgStore::GetProps() failed");
      return nullptr;
    }
    P2PsafeMAPIbuffer sbPropValue = props;
    hr = m_pIMsgStore -> OpenEntry ( props[0].Value.bin.cb, (LPENTRYID)props[0].Value.bin.lpb, NULL, m_ulMDBFlags
                                   , &dwObjType, (LPUNKNOWN*)&pIMAPIFolder );
    if ( hr != S_OK )
    {
      MAPI_HRESULT ( hr, "IMsgStore::OpenEntry() failed" );
      return nullptr;
    }

    // Package, and
    return new CMAPIFolder ( m_pMAPISession, pIMAPIFolder );
}

CMAPIFolder*
CMsgStore::Query4Folder ( LPCTSTR lpszFolderName )
{
    CMAPIFolderSP spFolderRoot = Query4RootFolder ( );
    if ( spFolderRoot.IsEmpty() )
      ThrowP2Pevent();
    return spFolderRoot -> Query4SubFolder ( lpszFolderName );
}

CMAPIFolder*
CMsgStore::Query4SpecialFolder ( unsigned long ulFolderID )
{
    HRESULT       hr = S_OK;
    LPSPropValue  props=NULL;
    ULONG         cValues=0;
    DWORD         dwObjType;
    ULONG         rgTags[] = { 1, ulFolderID };
    CComPtr<IMAPIFolder> pIMAPIFolder;

	  CMAPIFolderSP spInboxFolder = Query4Inbox ( );
    if ( spInboxFolder.IsEmpty() )
      return nullptr;

    hr = spInboxFolder -> GetIMAPIFolder() -> GetProps ( (LPSPropTagArray) rgTags, T_MAPI_UNICODE, &cValues, &props);
    if ( hr !=S_OK )
      THROW_MAPI(hr,"IMAPIFolder::GetProps() failed" );
    P2PsafeMAPIbuffer sbPropValue = props;
    hr = m_pIMsgStore -> OpenEntry ( props[0].Value.bin.cb, (LPENTRYID)props[0].Value.bin.lpb, NULL, m_ulMDBFlags
                                   , &dwObjType, (LPUNKNOWN*)&pIMAPIFolder);
    if ( hr !=S_OK )
      THROW_MAPI(hr,"IMAPIFolder::GetProps() failed" );

    // Package, and
    return new CMAPIFolder ( m_pMAPISession, pIMAPIFolder );
}

CMAPIFolder*
CMsgStore::Query4Inbox ( )
{
    HRESULT        hr = S_OK;
    ULONG        cbEntryID;
    LPENTRYID     pEntryID;
    DWORD        dwObjType;
    CComPtr<IMAPIFolder> pIMAPIFolder;

    hr = GetIMsgStore() -> GetReceiveFolder ( NULL, 0, &cbEntryID, &pEntryID, NULL );
    if ( hr != S_OK )
    {
      MAPI_HRESULT(hr,"IMsgStore::GetReceiveFolder() failed");
      return nullptr;
    }
    P2PsafeMAPIbuffer sbEntryID = pEntryID;
    hr = GetIMsgStore() -> OpenEntry ( cbEntryID, pEntryID, NULL, m_ulMDBFlags, &dwObjType, (LPUNKNOWN*)&pIMAPIFolder);
    if ( hr != S_OK )
    {
      MAPI_HRESULT ( hr, "IMsgStore::OpenEntry() failed" );
      return nullptr;
    }

    // Package, and
    return new CMAPIFolder ( m_pMAPISession, pIMAPIFolder );
}

CMAPIFolder*
CMsgStore::Query4Outbox ( )
{
    return Query4Folder ( PR_IPM_OUTBOX_ENTRYID );
}

CMAPIFolder*
CMsgStore::Query4SentItems ( )
{
    return Query4Folder ( PR_IPM_SENTMAIL_ENTRYID );
}

CMAPIFolder*
CMsgStore::Query4DeletedItems ( )
{
    return Query4Folder ( PR_IPM_WASTEBASKET_ENTRYID );
}

CMAPIFolder*
CMsgStore::Query4Contacts ( )
{
    return Query4SpecialFolder ( PR_IPM_CONTACT_ENTRYID );
}

CMAPIFolder*
CMsgStore::Query4Drafts ( )
{
    return Query4SpecialFolder ( PR_IPM_DRAFTS_ENTRYID );
}

CMAPIFolder*
CMsgStore::Query4Calendar ( )
{
    return Query4SpecialFolder ( PR_IPM_APPOINTMENT_ENTRYID );
}

CMAPIFolder*
CMsgStore::Query4JunkFolder ( )
{
    return Query4Folder ( _T("Junk E-mail") );
}

///////////////////////////////////////
//  Property exposure

ULONG
CMsgStore::GetSupportMask ( )
{
    LPSPropValue   props  = nullptr;
    ULONG         cValues = 0;
    ULONG        rgTags[] = { 1, PR_STORE_SUPPORT_MASK };
    ULONG        ulSupport= 0;

    HRESULT hr = m_pIMsgStore -> GetProps ( (LPSPropTagArray)rgTags,T_MAPI_UNICODE
                                          , &cValues, &props );
    if ( hr != S_OK )
      THROW_MAPI ( hr,"IMsgStore::GetProps() failed");
    ulSupport = props -> Value.ul;
    MAPIFreeBuffer(props);
    return ulSupport;
}

IMsgStore*
CMsgStore::GetIMsgStore ( )
{
    return m_pIMsgStore;
}
