#ifndef _MAPIFORM_H
#define _MAPIFORM_H

/* MAPI definitions (MS crap) */

#ifndef _MAPIDEFS_H
#include <mapidefs.h>
#include <mapicode.h>
#include <mapiguid.h>
#include <mapitags.h>
#endif

#ifndef BEGIN_INTERFACE
#define BEGIN_INTERFACE
#endif

typedef const RECT *LPCRECT;
typedef ULONG HFRMREG;

#define HFRMREG_DEFAULT  0
#define HFRMREG_LOCAL  1
#define HFRMREG_PERSONAL 2
#define HFRMREG_FOLDER  3

DECLARE_MAPI_INTERFACE_PTR(IPersistMessage, LPPERSISTMESSAGE);
DECLARE_MAPI_INTERFACE_PTR(IMAPIMessageSite, LPMAPIMESSAGESITE);
DECLARE_MAPI_INTERFACE_PTR(IMAPISession, LPMAPISESSION);
DECLARE_MAPI_INTERFACE_PTR(IMAPIViewContext, LPMAPIVIEWCONTEXT);
DECLARE_MAPI_INTERFACE_PTR(IMAPIViewAdviseSink, LPMAPIVIEWADVISESINK);
DECLARE_MAPI_INTERFACE_PTR(IMAPIFormAdviseSink, LPMAPIFORMADVISESINK);
DECLARE_MAPI_INTERFACE_PTR(IMAPIFormInfo, LPMAPIFORMINFO);
DECLARE_MAPI_INTERFACE_PTR(IMAPIFormMgr, LPMAPIFORMMGR);
DECLARE_MAPI_INTERFACE_PTR(IMAPIFormContainer, LPMAPIFORMCONTAINER);
DECLARE_MAPI_INTERFACE_PTR(IMAPIForm, LPMAPIFORM);
DECLARE_MAPI_INTERFACE_PTR(IMAPIFormFactory, LPMAPIFORMFACTORY);

typedef const char **LPPCSTR;
typedef LPMAPIFORMINFO *LPPMAPIFORMINFO;

STDAPI MAPIOpenFormMgr(LPMAPISESSION,LPMAPIFORMMGR*);
STDAPI MAPIOpenLocalFormContainer(LPMAPIFORMCONTAINER*);

#define MAPI_GETLASTERROR_METHOD(IPURE)  \
    MAPIMETHOD(GetLastError)(THIS_ HRESULT,ULONG,LPMAPIERROR*) IPURE;

#define MAPI_IPERSISTMESSAGE_METHODS(IPURE)  \
    MAPIMETHOD(GetClassID)(THIS_ LPCLSID) IPURE;  \
    MAPIMETHOD(IsDirty)(THIS) IPURE;  \
    MAPIMETHOD(InitNew)(THIS_ LPMAPIMESSAGESITE,LPMESSAGE) IPURE;  \
    MAPIMETHOD(Load)(THIS_ LPMAPIMESSAGESITE,LPMESSAGE,ULONG,ULONG) IPURE;  \
    MAPIMETHOD(Save)(THIS_ LPMESSAGE,ULONG) IPURE;  \
    MAPIMETHOD(SaveCompleted)(THIS_ LPMESSAGE) IPURE;  \
    MAPIMETHOD(HandsOffMessage)(THIS) IPURE;

#undef INTERFACE
#define INTERFACE IPersistMessage
DECLARE_MAPI_INTERFACE_(IPersistMessage, IUnknown)
{
    BEGIN_INTERFACE
    MAPI_IUNKNOWN_METHODS(PURE)
    MAPI_GETLASTERROR_METHOD(PURE)
    MAPI_IPERSISTMESSAGE_METHODS(PURE)
};

#define MAPI_IMAPIMESSAGESITE_METHODS(IPURE)  \
    MAPIMETHOD(GetSession)(THIS_ LPMAPISESSION*) IPURE;  \
    MAPIMETHOD(GetStore)(THIS_ LPMDB*) IPURE; \
    MAPIMETHOD(GetFolder)(THIS_ LPMAPIFOLDER*) IPURE;  \
    MAPIMETHOD(GetMessage)(THIS_ LPMESSAGE*) IPURE;  \
    MAPIMETHOD(GetFormManager)(THIS_ LPMAPIFORMMGR*) IPURE;  \
    MAPIMETHOD(NewMessage)(THIS_ ULONG,LPMAPIFOLDER,LPPERSISTMESSAGE,LPMESSAGE*,LPMAPIMESSAGESITE*,LPMAPIVIEWCONTEXT*) IPURE;  \
    MAPIMETHOD(CopyMessage)(THIS_ LPMAPIFOLDER) IPURE;  \
    MAPIMETHOD(MoveMessage)(THIS_ LPMAPIFOLDER,LPMAPIVIEWCONTEXT,LPCRECT) IPURE;  \
    MAPIMETHOD(DeleteMessage)(THIS_ LPMAPIVIEWCONTEXT,LPCRECT) IPURE;  \
    MAPIMETHOD(SaveMessage)(THIS) IPURE;  \
    MAPIMETHOD(SubmitMessage)(THIS_ ULONG) IPURE;  \
    MAPIMETHOD(GetSiteStatus)(THIS_ LPULONG) IPURE;

#undef INTERFACE
#define INTERFACE IMAPIMessageSite
DECLARE_MAPI_INTERFACE_(IMAPIMessageSite, IUnknown)
{
    BEGIN_INTERFACE
    MAPI_IUNKNOWN_METHODS(PURE)
    MAPI_GETLASTERROR_METHOD(PURE)
    MAPI_IMAPIMESSAGESITE_METHODS(PURE)
};

#define MAPI_IMAPIFORM_METHODS(IPURE)  \
    MAPIMETHOD(SetViewContext)(THIS_ LPMAPIVIEWCONTEXT) IPURE;  \
    MAPIMETHOD(GetViewContext)(THIS_ LPMAPIVIEWCONTEXT*) IPURE;  \
    MAPIMETHOD(ShutdownForm)(THIS_ ULONG) IPURE; \
    MAPIMETHOD(DoVerb)(THIS_ LONG,LPMAPIVIEWCONTEXT,ULONG,LPCRECT) IPURE;  \
    MAPIMETHOD(Advise)(THIS_ LPMAPIVIEWADVISESINK,ULONG*) IPURE;  \
    MAPIMETHOD(Unadvise)(THIS_ ULONG) IPURE;

#undef INTERFACE
#define INTERFACE IMAPIForm
DECLARE_MAPI_INTERFACE_(IMAPIForm, IUnknown)
{
    BEGIN_INTERFACE
    MAPI_IUNKNOWN_METHODS(PURE)
    MAPI_GETLASTERROR_METHOD(PURE)
    MAPI_IMAPIFORM_METHODS(PURE)
};

typedef enum tagSAVEOPTS {
    SAVEOPTS_SAVEIFDIRTY = 0,
    SAVEOPTS_NOSAVE = 1,
    SAVEOPTS_PROMPTSAVE = 2
} SAVEOPTS;

typedef struct {
    ULONG ulFlags;
    HGLOBAL hDevMode;
    HGLOBAL hDevNames;
    ULONG ulFirstPageNumber;
    ULONG fPrintAttachments;
} FORMPRINTSETUP, *LPFORMPRINTSETUP;

#define SAVE_FORMAT_TEXT  1
#define SAVE_FORMAT_RICHTEXT  2

#define MAPI_IMAPIVIEWCONTEXT_METHODS(IPURE)  \
    MAPIMETHOD(SetAdviseSink)(THIS_ LPMAPIFORMADVISESINK) IPURE;  \
    MAPIMETHOD(ActivateNext)(THIS_ ULONG,LPCRECT) IPURE; \
    MAPIMETHOD(GetPrintSetup)(THIS_ ULONG,LPFORMPRINTSETUP*) IPURE;  \
    MAPIMETHOD(GetSaveStream)(THIS_ ULONG*,ULONG*,LPSTREAM*) IPURE;  \
    MAPIMETHOD(GetViewStatus)(THIS_ LPULONG) IPURE;

#undef INTERFACE
#define INTERFACE IMAPIViewContext
DECLARE_MAPI_INTERFACE_(IMAPIViewContext, IUnknown)
{
    BEGIN_INTERFACE
    MAPI_IUNKNOWN_METHODS(PURE)
    MAPI_GETLASTERROR_METHOD(PURE)
    MAPI_IMAPIVIEWCONTEXT_METHODS(PURE)
};

#define VCSTATUS_NEXT  0x00000001
#define VCSTATUS_PREV  0x00000002
#define VCSTATUS_MODAL  0x00000004
#define VCSTATUS_INTERACTIVE  0x00000008
#define VCSTATUS_READONLY  0x00000010
#define VCSTATUS_DELETE  0x00010000
#define VCSTATUS_COPY  0x00020000
#define VCSTATUS_MOVE  0x00040000
#define VCSTATUS_SUBMIT  0x00080000
#define VCSTATUS_DELETE_IS_MOVE  0x00100000
#define VCSTATUS_SAVE  0x00200000
#define VCSTATUS_NEW_MESSAGE  0x00400000

#define VCDIR_NEXT  VCSTATUS_NEXT
#define VCDIR_PREV  VCSTATUS_PREV
#define VCDIR_DELETE  VCSTATUS_DELETE
#define VCDIR_MOVE  VCSTATUS_MOVE

#define MAPI_IMAPIFORMADVISESINK_METHODS(IPURE)  \
    STDMETHOD(OnChange)(THIS_ ULONG) IPURE;  \
    STDMETHOD(OnActivateNext)(THIS_ LPCSTR,ULONG,ULONG,LPPERSISTMESSAGE*) IPURE;

#undef INTERFACE
#define INTERFACE IMAPIFormAdviseSink
DECLARE_MAPI_INTERFACE_(IMAPIFormAdviseSink, IUnknown)
{
    BEGIN_INTERFACE
    MAPI_IUNKNOWN_METHODS(PURE)
    MAPI_IMAPIFORMADVISESINK_METHODS(PURE)
};

#define MAPI_IMAPIVIEWADVISESINK_METHODS(IPURE)  \
    MAPIMETHOD(OnShutdown)(THIS) IPURE;  \
    MAPIMETHOD(OnNewMessage)(THIS) IPURE;  \
    MAPIMETHOD(OnPrint)(THIS_ ULONG,HRESULT) IPURE;  \
    MAPIMETHOD(OnSubmitted)(THIS) IPURE;  \
    MAPIMETHOD(OnSaved)(THIS) IPURE;

#undef INTERFACE
#define INTERFACE IMAPIViewAdviseSink
DECLARE_MAPI_INTERFACE_(IMAPIViewAdviseSink, IUnknown)
{
    BEGIN_INTERFACE
    MAPI_IUNKNOWN_METHODS(PURE)
    MAPI_IMAPIVIEWADVISESINK_METHODS(PURE)
};

typedef struct {
    LPTSTR pszDisplayName;
    ULONG nVal;
} SMAPIFormPropEnumVal, *LPMAPIFORMPROPENUMVAL;

typedef ULONG FORMPROPSPECIALTYPE;

#define FPST_VANILLA  0
#define FPST_ENUM_PROP  1

typedef struct {
    ULONG ulFlags;
    ULONG nPropType;
    MAPINAMEID nmid;
    LPTSTR pszDisplayName;
    FORMPROPSPECIALTYPE nSpecialType;
    union {
        struct {
            MAPINAMEID nmidIdx;
            ULONG cfpevAvailable;
            LPMAPIFORMPROPENUMVAL pfpevAvailable;
        } s1;
    } u;
} SMAPIFormProp, *LPMAPIFORMPROP;

typedef struct {
    ULONG cProps;
    ULONG ulPad;
    SMAPIFormProp aFormProp[MAPI_DIM];
} SMAPIFormPropArray, *LPMAPIFORMPROPARRAY;

#define CbMAPIFormPropArray(_c)  (offsetof(SMAPIFormPropArray,aFormProp)+(_c)*sizeof(SMAPIFormProp))

typedef struct {
    LONG lVerb;
    LPTSTR szVerbname;
    DWORD fuFlags;
    DWORD grfAttribs;
    ULONG ulFlags;
} SMAPIVerb, *LPMAPIVERB;

typedef struct {
    ULONG cMAPIVerb;
    SMAPIVerb aMAPIVerb[MAPI_DIM];
} SMAPIVerbArray, *LPMAPIVERBARRAY;

#define CbMAPIVerbArray(_c)  (offsetof(SMAPIVerbArray,aMAPIVerb)+(_c)*sizeof(SMAPIVerb))

#define MAPI_IMAPIFORMINFO_METHODS(IPURE)  \
    MAPIMETHOD(CalcFormPropSet)(THIS_ ULONG,LPMAPIFORMPROPARRAY*) IPURE;  \
    MAPIMETHOD(CalcVerbSet)(THIS_ ULONG,LPMAPIVERBARRAY*) IPURE;  \
    MAPIMETHOD(MakeIconFromBinary)(THIS_ ULONG,HICON*) IPURE;  \
    MAPIMETHOD(SaveForm)(THIS_ LPCTSTR) IPURE;  \
    MAPIMETHOD(OpenFormContainer)(THIS_ LPMAPIFORMCONTAINER*) IPURE;

#undef INTERFACE
#define INTERFACE IMAPIFormInfo
DECLARE_MAPI_INTERFACE_(IMAPIFormInfo, IMAPIProp)
{
    BEGIN_INTERFACE
    MAPI_IUNKNOWN_METHODS(PURE)
    MAPI_IMAPIPROP_METHODS(PURE)
    MAPI_IMAPIFORMINFO_METHODS(PURE)
};

#define MAPI_MESSAGE_BEHAVIOR_IPM  0
#define MAPI_MESSAGE_BEHAVIOR_FOLDER  1

typedef struct {
    ULONG cValues;
    LPCSTR aMessageClass[MAPI_DIM];
} SMessageClassArray, *LPSMESSAGECLASSARRAY;

#define CbMessageClassArray(_c)  (offsetof(SMessageClassArray,aMessageClass)+(_c)*sizeof(LPCSTR))

typedef struct {
    ULONG cForms;
    LPMAPIFORMINFO aFormInfo[MAPI_DIM];
} SMAPIFormInfoArray, *LPSMAPIFORMINFOARRAY;

#define CbMAPIFormInfoArray(_c)  (offsetof(SMAPIFormInfoArray,aFormInfo)+(_c)*sizeof(LPMAPIFORMINFO))

#define MAPIFORM_SELECT_ALL_REGISTRIES  0
#define MAPIFORM_SELECT_FOLDER_REGISTRY_ONLY  1
#define MAPIFORM_SELECT_NON_FOLDER_REGISTRY_ONLY  2

#define FORMPROPSET_UNION  0
#define FORMPROPSET_INTERSECTION  1

#define MAPIFORM_EXACTMATCH  0x0020

#define MAPI_IMAPIFORMMGR_METHODS(IPURE)  \
    MAPIMETHOD(LoadForm)(THIS_ ULONG,ULONG,LPCSTR,ULONG,ULONG,LPMAPIFOLDER,LPMAPIMESSAGESITE,LPMESSAGE,LPMAPIVIEWCONTEXT,REFIID,LPVOID*) IPURE;  \
    MAPIMETHOD(ResolveMessageClass)(THIS_ LPCSTR,ULONG,LPMAPIFOLDER,LPMAPIFORMINFO*) IPURE;  \
    MAPIMETHOD(ResolveMultipleMessageClasses)(THIS_ LPSMESSAGECLASSARRAY,ULONG,LPMAPIFOLDER,LPSMAPIFORMINFOARRAY*) IPURE;  \
    MAPIMETHOD(CalcFormPropSet)(THIS_ LPSMAPIFORMINFOARRAY,ULONG,LPMAPIFORMPROPARRAY*) IPURE;  \
    MAPIMETHOD(CreateForm)(THIS_ ULONG,ULONG,LPMAPIFORMINFO,REFIID,LPVOID*) IPURE;  \
    MAPIMETHOD(SelectForm)(THIS_ ULONG,ULONG,LPCTSTR,LPMAPIFOLDER,LPMAPIFORMINFO*) IPURE;  \
    MAPIMETHOD(SelectMultipleForms)(THIS_ ULONG,ULONG,LPCTSTR,LPMAPIFOLDER,LPSMAPIFORMINFOARRAY,LPSMAPIFORMINFOARRAY*) IPURE;  \
    MAPIMETHOD(SelectFormContainer)(THIS_ ULONG,ULONG,LPMAPIFORMCONTAINER*) IPURE;  \
    MAPIMETHOD(OpenFormContainer)(THIS_ HFRMREG,LPUNKNOWN,LPMAPIFORMCONTAINER*) IPURE;  \
    MAPIMETHOD(PrepareForm)(THIS_ ULONG,ULONG,LPMAPIFORMINFO) IPURE;  \
    MAPIMETHOD(IsInConflict)(THIS_ ULONG,ULONG,LPCSTR,LPMAPIFOLDER) IPURE;

#undef INTERFACE
#define INTERFACE IMAPIFormMgr
DECLARE_MAPI_INTERFACE_(IMAPIFormMgr, IUnknown)
{
    BEGIN_INTERFACE
    MAPI_IUNKNOWN_METHODS(PURE)
    MAPI_GETLASTERROR_METHOD(PURE)
    MAPI_IMAPIFORMMGR_METHODS(PURE)
};

#define MAPIFORM_CPU_X86  1
#define MAPIFORM_CPU_MIP  2
#define MAPIFORM_CPU_AXP  3
#define MAPIFORM_CPU_PPC  4
#define MAPIFORM_CPU_M68  5

#define MAPIFORM_OS_WIN_31  1
#define MAPIFORM_OS_WINNT_35  2
#define MAPIFORM_OS_WIN_95  3
#define MAPIFORM_OS_MAC_7x  4
#define MAPIFORM_OS_WINNT_40  5

#define MAPIFORM_PLATFORM(CPU,OS)  ((ULONG)((((ULONG)CPU)<<16)|OS))

#define MAPIFORM_INSTALL_DIALOG  MAPI_DIALOG
#define MAPIFORM_INSTALL_OVERWRITEONCONFLICT  0x0010

#define MAPI_IMAPIFORMCONTAINER_METHODS(IPURE)  \
    MAPIMETHOD(InstallForm)(THIS_ ULONG,ULONG,LPCTSTR) IPURE;  \
    MAPIMETHOD(RemoveForm)(THIS_ LPCSTR) IPURE;  \
    MAPIMETHOD(ResolveMessageClass)(THIS_ LPCSTR,ULONG,LPMAPIFORMINFO*) IPURE;  \
    MAPIMETHOD(ResolveMultipleMessageClasses)(THIS_ LPSMESSAGECLASSARRAY,ULONG,LPSMAPIFORMINFOARRAY*) IPURE;  \
    MAPIMETHOD(CalcFormPropSet)(THIS_ ULONG,LPMAPIFORMPROPARRAY*) IPURE;  \
    MAPIMETHOD(GetDisplay)(THIS_ ULONG,LPTSTR*) IPURE;

#undef INTERFACE
#define INTERFACE IMAPIFormContainer
DECLARE_MAPI_INTERFACE_(IMAPIFormContainer, IUnknown)
{
    BEGIN_INTERFACE
    MAPI_IUNKNOWN_METHODS(PURE)
    MAPI_GETLASTERROR_METHOD(PURE)
    MAPI_IMAPIFORMCONTAINER_METHODS(PURE)
};

#define MAPI_IMAPIFORMFACTORY_METHODS(IPURE)  \
    MAPIMETHOD(CreateClassFactory)(THIS_ REFCLSID,ULONG,LPCLASSFACTORY*) IPURE;  \
    MAPIMETHOD(LockServer)(THIS_ ULONG,ULONG) IPURE;

#undef INTERFACE
#define INTERFACE IMAPIFormFactory
DECLARE_MAPI_INTERFACE_(IMAPIFormFactory, IUnknown)
{
    BEGIN_INTERFACE
    MAPI_IUNKNOWN_METHODS(PURE)
    MAPI_GETLASTERROR_METHOD(PURE)
    MAPI_IMAPIFORMFACTORY_METHODS(PURE)
};

#endif /* _MAPIFORM_H */
