/* -*- Mode: IDL; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */

/*
 *  Copyright (C) 2008 OMC Denmark ApS.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef F2T_TYPES_DEF
#define F2T_TYPES_DEF

#pragma prefix "omc.brutus"

#include "return_codes.idl"
#include "defines.idl"

module BRUTUS {

        // Java needs these constants for fixed length sequences, strings and arrays
	typedef unsigned long FixedSize;

        // The encoding of a Brutus GUID is:
        //
	// GUID BRUTUS_IID_IExchangeModifyTable = "0x2D734CB0 0x53FD 0x101B 0xB1 0x9D 0x08 0x00 0x2B 0x30 0x56 0xE3";
        // The first number is the string representation of GUID::Data1,
        // i.e: GUID::Data1 = 0x2D734CB0
        //
        // The second number is the string representation of GUID::Data2
        // i.e: GUID::Data2 = 0x53FD
        //
        // The third number is the string representation of GUID::Data3
        // i.e: GUID::Data3 = 0x101B
        //
        // The last 8 numbers are the string representation of GUID::Data4
        // i.e: GUID::Data4 = { 0xB1, 0x9D, 0x08, 0x00, 0x2B, 0x30, 0x56, 0xE3 }
        //
        // The presence of " " delimiters and "0x" prefixes are intended to 
        // make interpretation and decoding easy for the client developer. 
	//
	// Any GUID given to Brutus must obey strictly to this encoding. Failure to do so
	// will make the method return BRUTUS_MAPI_E_INVALID_PARAMETER.
	const FixedSize GUID_len = 65;
        typedef string<GUID_len> GUID;
        typedef sequence<GUID> seq_GUID; 

        //********************************************************************
        // The basic interface
        //
        interface IUnknown {
 
                BRESULT QueryInterface(in GUID iid,
                                       out IUnknown ppvObject);
 
		// InstanceID is ignored except for IMAPISession::Destroy()
                void Destroy(in unsigned long InstanceID);
	};

        //********************************************************************
        // Basic types
        //
        typedef sequence<octet>         seq_octet;
        typedef sequence<short>         seq_short;
        typedef sequence<long>          seq_long; 
        typedef sequence<unsigned long> seq_ulong; 
        typedef sequence<float>         seq_float; 
        typedef sequence<double>        seq_double; 
        typedef sequence<string>        seq_string; 
        typedef sequence<string>        seq_wstring; 

        //********************************************************************
        // Complex MAPI types
        //
        typedef seq_ulong SPropTagArray;

	const FixedSize MAPIUID_len = 80;
        typedef string<MAPIUID_len> MAPIUID;
        typedef sequence<MAPIUID> seq_MAPIUID;
 
        struct RECT {
                long left;
                long top;
                long right;
                long bottom;
        };

        struct MAPIERROR { 
                unsigned long ulVersion; 
                string        lpszError; 
                string        lpszComponent; 
                unsigned long ulLowLevelError; 
                unsigned long ulContext; 
        };

        struct CURRENCY { 
                unsigned long Lo; 
                long          Hi; 
        };
        typedef sequence<CURRENCY> seq_CURRENCY; 
        typedef seq_CURRENCY SCurrencyArray;

        struct FILETIME { 
                unsigned long dwLowDateTime;  
                unsigned long dwHighDateTime; 
        }; 
        typedef sequence<FILETIME> seq_FILETIME; 
        typedef seq_FILETIME SDateTimeArray;
 
        typedef seq_octet SBinary;
        typedef sequence<SBinary> seq_SBinary; 
        typedef seq_SBinary SBinaryArray;
 
        typedef long long LARGE_INTEGER;
        typedef sequence<LARGE_INTEGER> seq_LARGE_INTEGER;
        typedef seq_LARGE_INTEGER SLargeIntegerArray;

        typedef unsigned long long ULARGE_INTEGER;
        typedef sequence<ULARGE_INTEGER> seq_ULARGE_INTEGER;
        typedef seq_ULARGE_INTEGER SULargeIntegerArray;

        typedef seq_short SShortArray;

        typedef seq_long SLongArray;

        typedef seq_float SRealArray;

        typedef seq_double SDoubleArray;

        typedef seq_double SAppTimeArray;

        typedef seq_string SLPSTRArray;

	// UNICODE is translated to UTF8 before transmitting. UTF8
	// is likewise expected where UNICODE is specified by MSDN.
        typedef seq_wstring SWStringArray;

        typedef seq_GUID SGuidArray;

	// The 'ul' member can be written to, but never read from. The braindead 
	// reason is that MAPI does not have a native PT_ULONG type. So you can put
	// an unsigned value into the 'ul' member but the property value, upon reading
	// the value, will always report the type as PT_LONG, thus forcing you to 
	// read from the 'l' member instead. Doh!
        union PV switch (PT_TYPE) {
        case BRUTUS_PT_SHORT       : short              i;      
        case BRUTUS_PT_USHORT      : unsigned short     ui;     
        case BRUTUS_PT_LONG        : long               l;      
        case BRUTUS_PT_ULONG       : unsigned long      ul; // never use this one (see comment above)
        case BRUTUS_PT_FLOAT       : float              flt;   
        case BRUTUS_PT_DOUBLE      : double             dbl;    
        case BRUTUS_PT_BOOLEAN     : boolean            b;      
        case BRUTUS_PT_CURRENCY    : CURRENCY           cur;    
        case BRUTUS_PT_APPTIME     : double             at;     
        case BRUTUS_PT_SYSTIME     : FILETIME           ft;      
        case BRUTUS_PT_STRING8     : string             lpszA;    
        case BRUTUS_PT_BINARY      : SBinary            bin;     
        case BRUTUS_PT_UNICODE     : string             lpszW;
        case BRUTUS_PT_CLSID       : GUID               lpguid;  
        case BRUTUS_PT_LONGLONG    : LARGE_INTEGER      li;      
        case BRUTUS_PT_MV_SHORT    : SShortArray        MVi;      
        case BRUTUS_PT_MV_LONG     : SLongArray         MVl;      
        case BRUTUS_PT_MV_FLOAT    : SRealArray         MVflt;   
        case BRUTUS_PT_MV_DOUBLE   : SDoubleArray       MVdbl;   
        case BRUTUS_PT_MV_CURRENCY : SCurrencyArray     MVcur; 
        case BRUTUS_PT_MV_APPTIME  : SAppTimeArray      MVat;    
        case BRUTUS_PT_MV_SYSTIME  : SDateTimeArray     MVft;   
        case BRUTUS_PT_MV_BINARY   : SBinaryArray       MVbin;   
        case BRUTUS_PT_MV_STRING8  : SLPSTRArray        MVszA;    
        case BRUTUS_PT_MV_UNICODE  : SWStringArray      MVszW;    
        case BRUTUS_PT_MV_CLSID    : SGuidArray         MVguid;   
        case BRUTUS_PT_MV_LONGLONG : SLargeIntegerArray MVli;     
        case BRUTUS_PT_ERROR       : BRESULT            err;     
        case BRUTUS_PT_OBJECT      : IUnknown           obj;      
        case BRUTUS_PT_NULL        : long               x;      
        };

        // This naming of seq_SPropValue is consistent but
        // makes certain function parameters different from
        // their MSDN declaration.
	// Sample code on MSDN does initialize dwAlignPad, 
	// so I dare not remove it.
        struct SPropValue { 
                BDEFINE ulPropTag; 
                unsigned long dwAlignPad; // surposely padding bits
                PV Value; 
        };
        typedef sequence<SPropValue> seq_SPropValue;

        struct SPropProblem {
                unsigned long ulIndex; 
                BDEFINE ulPropTag; 
                BRESULT scode; 
        };
        typedef sequence<SPropProblem> seq_SPropProblem;
        typedef seq_SPropProblem SPropProblemArray;
        typedef sequence<SPropProblemArray> seq_SPropProblemArray;

        union tag_Kind switch (BDEFINE) { 
        case BRUTUS_MNID_ID : long lID; 
        case BRUTUS_MNID_STRING : string lpwstrName; 
        };  
        struct MAPINAMEID { 
                GUID lpguid; 
                tag_Kind Kind;
        };
        typedef sequence<MAPINAMEID> seq_MAPINAMEID;

	const FixedSize all_octet_4_len = 4;
	typedef octet arr_octet_4[all_octet_4_len];
        struct ENTRYID { 
                arr_octet_4 abFlags; 
                seq_octet ab;
        };
        typedef sequence<ENTRYID> seq_ENTRYID;
        typedef sequence<ENTRYID> ENTRYLIST;


        struct SMAPIFormPropEnumVal { 
                string        pszDisplayName; 
                unsigned long nVal; 
        }; 
        typedef sequence<SMAPIFormPropEnumVal> seq_SMAPIFormPropEnumVal;
 
        struct SMAPIFormPropStruct { 
                MAPINAMEID               nmidIdx; 
                seq_SMAPIFormPropEnumVal pfpevAvailable; 
        };

        union SMAPIFormPropUnion switch (BDEFINE) {
        case BRUTUS_FPST_ENUM_PROP : SMAPIFormPropStruct s1;
        };

        struct SMAPIFormProp { 
                unsigned long      ulFlags;      
                unsigned long      nPropType;      
                MAPINAMEID         nmid;           
                string             pszDisplayName; 
                SMAPIFormPropUnion u;
        };
        typedef sequence<SMAPIFormProp> seq_SMAPIFormProp;
        typedef seq_SMAPIFormProp SMAPIFormPropArray;

        // I have to use 'interface' instead of the more 
        // appropiate 'struct' as it is illegal to forward
        // declare idl structs in this manner.
        interface SAndRestriction;
        interface SOrRestriction;
        interface SNotRestriction;
        interface SContentRestriction;
        interface SPropertyRestriction;
        interface SComparePropsRestriction;
        interface SBitMaskRestriction;
        interface SSizeRestriction;
        interface SExistRestriction;
        interface SSubRestriction;
        interface SCommentRestriction;

        union SRestriction switch (RES_TYPE) {
        case BRUTUS_RES_ERROR          : BRESULT Error;
        case BRUTUS_RES_AND            : SAndRestriction resAnd;
        case BRUTUS_RES_OR             : SOrRestriction resOr;     
        case BRUTUS_RES_NOT            : SNotRestriction resNot;      
        case BRUTUS_RES_CONTENT        : SContentRestriction resContent;     
        case BRUTUS_RES_PROPERTY       : SPropertyRestriction resProperty;   
        case BRUTUS_RES_COMPAREPROPS   : SComparePropsRestriction resCompareProps;
        case BRUTUS_RES_BITMASK        : SBitMaskRestriction resBitMask;      
        case BRUTUS_RES_SIZE           : SSizeRestriction resSize;    
        case BRUTUS_RES_EXIST          : SExistRestriction resExist;     
        case BRUTUS_RES_SUBRESTRICTION : SSubRestriction resSub;      
        case BRUTUS_RES_COMMENT        : SCommentRestriction resComment;    
        };
        typedef sequence<SRestriction> seq_SRestriction;

        // This interface will be a container for an encapsulated
        // native language SRestriction. The reason for this container, 
        // is that it will enable us to construct a servant activator 
        // that can etheralize *all* recursive SRestriction instances 
        // in one go. Easier memory management in other words.
	//
	// The Brutus server will *never* call Destroy() on an
	// SRestrictionContainer reference that are giving to it by
	// a client, but the client *must* call Destroy() when given
	// an SRestrictionContainer reference by the Brutus server when
	// it is done using it.
        interface SRestrictionContainer {
                readonly attribute SRestriction content; 
                void Destroy(); // never invoked by Brutus server
        };

        interface SAndRestriction {
                readonly attribute seq_SRestriction lpRes; 
        };

        interface SOrRestriction {
                readonly attribute seq_SRestriction lpRes; 
        };

        interface SNotRestriction {
                attribute unsigned long ulReserved;
                readonly attribute SRestriction lpRes; 
        };

        interface SContentRestriction {       
                readonly attribute FUZZY_TYPE ulFuzzyLevel; 
                readonly attribute BDEFINE ulPropTag; 
                readonly attribute SPropValue lpProp; 
        };

        interface SPropertyRestriction { 
                readonly attribute RELOP_TYPE relop; 
                readonly attribute BDEFINE ulPropTag; 
                readonly attribute SPropValue lpProp; 
        };

        interface SComparePropsRestriction {
                readonly attribute RELOP_TYPE relop; 
                readonly attribute BDEFINE ulPropTag1; 
                readonly attribute BDEFINE ulPropTag2; 
        };

        interface SBitMaskRestriction { 
                readonly attribute BMR_TYPE relBMR; 
                readonly attribute BDEFINE ulPropTag;
                readonly attribute BDEFINE ulMask; 
        };

        interface SSizeRestriction { 
                readonly attribute RELOP_TYPE relop; 
                readonly attribute BDEFINE ulPropTag; 
                readonly attribute unsigned long cb; 
        };

        interface SExistRestriction { 
                attribute unsigned long ulReserved1; 
                readonly attribute BDEFINE ulPropTag; 
                attribute unsigned long ulReserved2; 
        };

        interface SSubRestriction {
                readonly attribute BDEFINE ulSubObject;
                readonly attribute SRestriction lpRes;
        };

        interface SCommentRestriction {
                readonly attribute SRestriction lpRes; 
                readonly attribute seq_SPropValue lpProp; 
        };

        struct SSortOrder {
                BDEFINE ulPropTag;   
                BDEFINE ulOrder; 
        };
        typedef sequence<SSortOrder> seq_SSortOrder;

        struct SSortOrderSet { 
                unsigned long  cCategories; 
                unsigned long  cExpanded; 
                seq_SSortOrder aSort; 
        };
 
        struct ADRENTRY {
                unsigned long  ulReserved1;
                seq_SPropValue rgPropVals;
        };
        typedef sequence<ADRENTRY> seq_ADRENTRY;
        typedef seq_ADRENTRY ADRLIST;

        typedef seq_SPropValue SRow;
        typedef sequence<SRow> seq_SRow;
        typedef seq_SRow SRowSet;

        struct ERROR_NOTIFICATION {     
                ENTRYID       lpEntryID;   
                long          scode; 
                BDEFINE ulFlags;    
                MAPIERROR     lpMAPIError; 
        };

        struct NEWMAIL_NOTIFICATION {
                ENTRYID lpEntryID;  
                ENTRYID lpParentID;  
                BDEFINE ulFlags;  
                string lpszMessageClass; 
                BDEFINE ulMessageFlags;  
        };

        struct OBJECT_NOTIFICATION {
                ENTRYID lpEntryID;  
                BDEFINE ulObjType; 
                ENTRYID lpParentID;   
                ENTRYID lpOldID;    
                ENTRYID lpOldParentID;     
                SPropTagArray lpPropTagArray; 
        };

        struct TABLE_NOTIFICATION {
                BDEFINE ulTableEvent;  
                BRESULT hResult;  
                SPropValue propIndex;     
                SPropValue propPrior;  
                SRow row;
        };

        struct EXTENDED_NOTIFICATION {
                BDEFINE ulEvent;       
                seq_octet     pbEventParameters; 
        };

        struct STATUS_OBJECT_NOTIFICATION {
                ENTRYID        lpEntryID; 
                seq_SPropValue lpPropVals; 
        };

	union U_NOTIFY_OBJECT switch (EVENT_TYPE) { 
	case BRUTUS_fnevObjectCopied         : 
	case BRUTUS_fnevObjectCreated        : 
	case BRUTUS_fnevObjectDeleted        :
	case BRUTUS_fnevObjectModified       :
	case BRUTUS_fnevObjectMoved          :
	case BRUTUS_fnevSearchComplete       : OBJECT_NOTIFICATION obj;
	case BRUTUS_fnevCriticalError        : ERROR_NOTIFICATION err;   
	case BRUTUS_fnevExtended             : EXTENDED_NOTIFICATION ext; 
	case BRUTUS_fnevNewMail              : NEWMAIL_NOTIFICATION newmail;
	case BRUTUS_fnevTableModified        : TABLE_NOTIFICATION tab;
	case BRUTUS_fnevStatusObjectModified : STATUS_OBJECT_NOTIFICATION statobj;
	};
	struct NOTIFICATION {
		EVENT_TYPE ulEventType;
		U_NOTIFY_OBJECT info;
	};
        typedef sequence<NOTIFICATION> seq_NOTIFICATION;
        
        struct ADRPARM { 
                unsigned long cbABContEntryID; 
                ENTRYID       lpABContEntryID; 
                unsigned      long ulFlags; 
                seq_octet     lpReserved; 
                unsigned long ulHelpContext; 
                string        lpszHelpFileName; 
                string        ACCELERATEABSDI_IOR; 
                string        DISMISSMODELESS_IOR; 
                any           lpvDismissContext; 
                string        lpszCaption; 
                string        lpszNewEntryTitle; 
                string        lpszDestWellsTitle; 
                unsigned long cDestFields; 
                unsigned long nDestFieldFocus; 
                string        lppszDestTitles; 
                unsigned long lpulDestComps; 
                SRestriction  ContRestriction; 
                SRestriction  HierRestriction; 
        }; 
        typedef sequence<ADRPARM> seq_ADRPARM;

	// Exchange: PR_REPLICA_VERSION (PT_LONGLONG)
	struct SERVER_VERSION {
		unsigned short MajorVersion; // (unsigned 16bit) (li >> 48)
		unsigned short MinorVersion; // (unsigned 16bit) ((li >> 32) & 0x0000FFFF)
		unsigned short Build;        // (unsigned 16bit) ((li >> 16) & 0x0000FFFF)
		unsigned short MinorBuild;   // (unsigned 16bit) li
	};

        //********************************************************************
	// IStream specific types
	//
        struct STnefProblem {
		unsigned long ulComponent; 
                unsigned long ulAttribute; 
		unsigned long ulPropTag; 
		BRESULT scode; 
        };
        typedef sequence<STnefProblem> seq_STnefProblem;
	typedef seq_STnefProblem STnefProblemArray;

	struct RENDDATA {
		unsigned short atyp;
		unsigned long ulPosition;
		unsigned short dxWidth;
		unsigned short dyHeight;
		unsigned long dwFlags;
	};

	struct DTR {
		unsigned short wYear;
		unsigned short wMonth;
		unsigned short wDay;
		unsigned short wHour;
		unsigned short wMinute;
		unsigned short wSecond;
		unsigned short wDayOfWeek;
	};

	struct TRP {
		unsigned short trpid;
		unsigned short cbgrtrp;
		unsigned short cch;
		unsigned short cbRgb;
	};

	struct ADDRALIAS {
		string<BRUTUS_cbDisplayName> rgchName;
		string<BRUTUS_cbEmailName> rgchEName;
		string<BRUTUS_cbSeverName> rgchSrvr;
		unsigned long dibDetail;
		unsigned short type;
	};

	union address_kind switch (BDEFINE) {
	case BRUTUS_NSID_ALIAS : ADDRALIAS alias;
	case BRUTUS_NSID_NET : char rgchInterNet;			
	};
	struct NSID {
		unsigned long dwSize;
		string<BRUTUS_cbTYPE> uchType;
		unsigned long xtype;
		long lTime;
		address_kind address;
	};

	struct STATSTG { 
		string pwcsName; 
		unsigned long type; 
		unsigned long long cbSize; 
		FILETIME mtime; 
		FILETIME ctime; 
		FILETIME atime; 
		unsigned long grfMode; 
		unsigned long grfLocksSupported; 
		GUID clsid; 
		unsigned long grfStateBits; 
		unsigned long reserved; 
	}; 


        //********************************************************************
        // SPI specific types
        //
        typedef seq_octet NOTIFKEY;

        struct OPTIONDATA {
                BDEFINE ulFlags;             
                GUID lpRecipGUID;            
                string lpszAdrType;          
                string lpszDLLName;          
                unsigned long ulOrdinal;     
                seq_octet lpbOptionsData;    
                SPropValue lpOptionsProps;   
        };


        //********************************************************************
        // Exchange Information Store specific types
        //

	struct TRACEENTRY {
		long lAction;
		FILETIME ftArrivalTime;
		FILETIME ftDeferredTime;
		string<BRUTUS_MAX_ADMD_NAME_SIZ + BRUTUS_ADMN_PAD> rgchADMDName;
		string<BRUTUS_MAX_COUNTRY_NAME_SIZ + BRUTUS_COUNTRY_PAD> rgchCountryName;
		string<BRUTUS_MAX_PRMD_NAME_SIZ + BRUTUS_PRMD_PAD> rgchPRMDId;
		string<BRUTUS_MAX_ADMD_NAME_SIZ + BRUTUS_ADMN_PAD> rgchAttADMDName;
		string<BRUTUS_MAX_COUNTRY_NAME_SIZ + BRUTUS_COUNTRY_PAD> rgchAttCountryName;
		string<BRUTUS_MAX_PRMD_NAME_SIZ + BRUTUS_PRMD_PAD> rgchAttPRMDId;
	};
        typedef sequence<TRACEENTRY> seq_TRACEENTRY;
        typedef seq_TRACEENTRY TRACEINFO;

	struct INTTRACEENTRY {
		long lAction;
		FILETIME ftArrivalTime;
		FILETIME ftDeferredTime;

		string<BRUTUS_MAX_ADMD_NAME_SIZ + BRUTUS_ADMN_PAD> rgchADMDName;
		string<BRUTUS_MAX_COUNTRY_NAME_SIZ + BRUTUS_COUNTRY_PAD> rgchCountryName;
		string<BRUTUS_MAX_PRMD_NAME_SIZ + BRUTUS_PRMD_PAD> rgchPRMDId;
		string<BRUTUS_MAX_ADMD_NAME_SIZ + BRUTUS_ADMN_PAD> rgchAttADMDName;
		string<BRUTUS_MAX_COUNTRY_NAME_SIZ + BRUTUS_COUNTRY_PAD> rgchAttCountryName;
		string<BRUTUS_MAX_PRMD_NAME_SIZ + BRUTUS_PRMD_PAD> rgchAttPRMDId;
		string<BRUTUS_MAX_MTA_NAME_SIZ + BRUTUS_MTA_PAD> rgchMTAName;
		string<BRUTUS_MAX_MTA_NAME_SIZ + BRUTUS_MTA_PAD> rgchAttMTAName;
	};
        typedef sequence<INTTRACEENTRY> seq_INTTRACEENTRY;
        typedef seq_INTTRACEENTRY INTTRACEINFO;

	struct ROWENTRY {
		BDEFINE  ulRowFlags;
		seq_SPropValue rgPropVals;
	};
        typedef sequence<ROWENTRY> seq_ROWENTRY;
        typedef seq_ROWENTRY ROWLIST;

        // IExchangeRuleAction::GetAction()
	enum ACTTYPE {
		BRUTUS_OP_MOVE,
		BRUTUS_OP_COPY,
		BRUTUS_OP_REPLY,
		BRUTUS_OP_OOF_REPLY,
		BRUTUS_OP_DEFER_ACTION,
		BRUTUS_OP_BOUNCE,
		BRUTUS_OP_FORWARD,
		BRUTUS_OP_DELEGATE,
		BRUTUS_OP_TAG,
		BRUTUS_OP_DELETE,
		BRUTUS_OP_MARK_AS_READ
	};
	//
	// these are used in struct ACTION
	//
	struct actMoveCopy {
		ENTRYID lpStoreEntryId;
		ENTRYID lpFldEntryId;
	};
	struct actReply {
		ENTRYID lpEntryId;
		GUID guidReplyTemplate;
	};
	union action_option switch (ACTTYPE) {
	case BRUTUS_OP_MOVE :
	case BRUTUS_OP_COPY :
		actMoveCopy move_copy;
	case BRUTUS_OP_REPLY :
	case BRUTUS_OP_OOF_REPLY :
		actReply reply;
	case BRUTUS_OP_DEFER_ACTION :
		seq_octet actDeferAction;
	case BRUTUS_OP_BOUNCE :
		BDEFINE scBounceCode;
	case BRUTUS_OP_FORWARD :
	case BRUTUS_OP_DELEGATE :
		ADRLIST lpadrlist;
	case BRUTUS_OP_TAG :
		SPropValue propTag;
	};

	// dwAlignPad padding bits not included
	struct ACTION {
		ACTTYPE actionType;
		BDEFINE ulActionFlavor; // sole defined value is BRUTUS_DO_NOT_SEND_TO_ORIGINATOR
		SRestrictionContainer lpRes; // unused, must be NIL according to MSDN
		SPropTagArray lpPropTagArray; // unused, length must be zero according to MSDN
		BDEFINE ulFlags; // User defined flags
		action_option options;
	};
        typedef sequence<ACTION> seq_ACTION;
        typedef seq_ACTION ACTIONS; // EDK_RULES_VERSION is taken care of at the server side

	struct READSTATE {
		seq_octet pbSourceKey;
		BDEFINE ulFlags;
	};
        typedef sequence<READSTATE> seq_READSTATE;

	enum BrutusTC {
		BrutusCheck_tc,
		BrutusLogOn_tc,
		BrutusSession_tc,
		IABContainer_tc,
		IABLogon_tc,
		IABProvider_tc,
		IAddrBook_tc,
		IAttach_tc,
		IDistList_tc,
		IExchangeExportChanges_tc,
		IExchangeFavorites_tc,
		IExchangeImportContentsChanges_tc,
		IExchangeImportHierarchyChanges_tc,
		IExchangeManageStore_tc,
		IExchangeModifyTable_tc,
		IExchangeRuleAction_tc,
		IMAPIAdviseSink_tc,
		IMAPIContainer_tc,
		IMAPIControl_tc,
		IMAPIFolder_tc,
		IMAPIForm_tc,
		IMAPIFormAdviseSink_tc,
		IMAPIFormContainer_tc,
		IMAPIFormFactory_tc,
		IMAPIFormInfo_tc,
		IMAPIFormMgr_tc,
		IMAPIMessageSite_tc,
		IMAPIProgress_tc,
		IMAPIProp_tc,
		IMAPISession_tc,
		IMAPIStatus_tc,
		IMAPISupport_tc,
		IMAPITable_tc,
		IMAPIViewAdviseSink_tc,
		IMAPIViewContext_tc,
		IMSLogon_tc,
		IMSProvider_tc,
		IMailUser_tc,
		IMessage_tc,
		IMsgServiceAdmin_tc,
		IMsgStore_tc,
		IPersistMessage_tc,
		IProfAdmin_tc,
		IProfSect_tc,
		IPropData_tc,
		IProviderAdmin_tc,
		ISequentialStream_tc,
		ISpoolerHook_tc,
		IStream_tc,
		ITableData_tc,
		ITnef_tc,
		IXPLogon_tc,
		IXPProvider_tc,
		log_server_tc,
		SRestrictionContainer_tc,
		SAndRestriction_tc,
		SOrRestriction_tc,
		SNotRestriction_tc,
		SContentRestriction_tc,
		SPropertyRestriction_tc,
		SComparePropsRestriction_tc,
		SBitMaskRestriction_tc,
		SSizeRestriction_tc,
		SExistRestriction_tc,
		SSubRestriction_tc,
		SCommentRestriction_tc,
		IUnknown_tc
	};

	struct TIME_OF_DAY_INFO {
		unsigned long tod_elapsedt;
		unsigned long tod_msecs;
		unsigned long tod_hours;
		unsigned long tod_mins;
		unsigned long tod_secs;
		unsigned long tod_hunds;
		long tod_timezone;
		unsigned long tod_tinterval;
		unsigned long tod_day;
		unsigned long tod_month;
		unsigned long tod_year;
		unsigned long tod_weekday;
	};

	enum SID_NAME_USE {
		BRUTUS_SidTypeUser,
		BRUTUS_SidTypeGroup,
		BRUTUS_SidTypeDomain,
		BRUTUS_SidTypeAlias,
		BRUTUS_SidTypeWellKnownGroup,
		BRUTUS_SidTypeDeletedAccount,
		BRUTUS_SidTypeInvalid,
		BRUTUS_SidTypeUnknown,
		BRUTUS_SidTypeComputer	
	};

	enum BRUTUS_ATTACH_TAG {
		BRUTUS_OID_NONE, // signal no attachment tag - never sent to Exchange server
		BRUTUS_OID_TNEF,
		BRUTUS_OID_OLE,
		BRUTUS_OID_OLE1,
		BRUTUS_OID_OLE1_STORAGE,
		BRUTUS_OID_OLE2,
		BRUTUS_OID_OLE2_STORAGE,
		BRUTUS_OID_MAC_BINARY,
		BRUTUS_OID_MIMETAG
	};

	enum OUTLOOK_FOLDER {
		OUTLOOK_NONE,    // only applicable in IMessage::SubmitMessage() 
		OUTLOOK_DEVNULL, // only applicable in IMessage::SubmitMessage() 
		OUTLOOK_INBOX,   // for the IPM.Note message class in the private message store
		OUTLOOK_OUTBOX,
		OUTLOOK_WASTEBASKET,
		OUTLOOK_SENTMAIL,
		OUTLOOK_VIEWS,
		OUTLOOK_COMMON_VIEWS,
		OUTLOOK_FINDER,
		OUTLOOK_CALENDAR,
		OUTLOOK_CONTACTS,
		OUTLOOK_JOURNAL,
		OUTLOOK_NOTES,
		OUTLOOK_TASKS,
		OUTLOOK_REMINDERS,
		OUTLOOK_DRAFTS,
		OUTLOOK_ROOT_FOLDER,
		OUTLOOK_FAVORITES,
		OUTLOOK_JUNK
	};

	enum SERVER_TYPE {
		SERVER_TYPE_EXCHANGE,
		SERVER_TYPE_DOMINO
	};

	// IStream::Seek()
	enum STREAM_SEEK { 
		BRUTUS_STREAM_SEEK_SET, 
		BRUTUS_STREAM_SEEK_CUR, 
		BRUTUS_STREAM_SEEK_END 
	}; 

	// IStream::Stat()
	enum STATFLAG { 
		BRUTUS_STATFLAG_DEFAULT,
		BRUTUS_STATFLAG_NONAME
	};
	enum STGTY { 
		BRUTUS_STGTY_STORAGE,
		BRUTUS_STGTY_STREAM,
		BRUTUS_STGTY_LOCKBYTES,
		BRUTUS_STGTY_PROPERTY
	}; 

	enum IDType {
		BRUTUS_ID_INTEGER,
		BRUTUS_ID_STRING
	};
	union BName switch (IDType) {
	case BRUTUS_ID_INTEGER : unsigned long int_name;
	case BRUTUS_ID_STRING : string str_name;			
	};
	struct NamedPropertyTag {
		PT_TYPE type;
		BName name;
	};
	typedef sequence <NamedPropertyTag> seq_NamedPropertyTag;
	

        //********************************************************************
	// Recurrence types for appointments and tasks.
	// Please see: http://www.geocities.com/cainrandom/dev/MAPIRecurrence.html
	//

	/////////////////////////////////////////////////////////////////////
	//                                                                 //
	//                      Occurrence ID - oID                         //
	//                                                                 //
	// The ID of a specifc occurence is central to the Brutus          //
	// recurrence API. Ths oID is a way to uniquely identify an        //
	// occurrence in a recurrent serie of events or tasks. The oID is  //
	// defined as:                                                     //
	//                                                                 //
	//    0 => the series                                              //
	//    1 => the first occurrence                                    //
	//    2 => the second occurrence...                                //
	//                                                                 //
	/////////////////////////////////////////////////////////////////////

	/////////////////////////////////////////////////////////////////////
	//                                                                 //
	//                          Base date                              //
	//                                                                 //
	// The date in minutes since 1601 excluding the time of day.       //
	//                                                                 //
	/////////////////////////////////////////////////////////////////////


	typedef unsigned long OccurrenceID;

	// OccurrenceTime specifies the time of a specifc occurence by 
	// oID or actual FILETIME. Knowledge of the recurrence pattern is 
	// needed to go from one time representation to another.
	enum OccurrenceTimeType {
		tt_oID,
		tt_BaseDate,
		tt_FILETIME
	};
	union OccurrenceTime switch (OccurrenceTimeType) {
	case tt_oID      : OccurrenceID oID;    // the oID of the occurrence in the unmodified series
	case tt_BaseDate : unsigned long bdate; // the base date of the occurrence in the unmodified series
	case tt_FILETIME : FILETIME ft;         // the start FILETIME of the occurrence in the unmodified series
	};

	enum RecurrenceException {
		ExceptionNONE,            // No change - used internally by Brutus Server
		ExceptionDeletion,        // The occurrence has been deleted from the series
		ExceptionStartTime,       // Start time changed
		ExceptionEndTime,         // End time changed
		ExceptionDescription,     // Description changed
		ExceptionAttendee,        // Attendee list changed
		ExceptionReminderTime,    // Reminder time changed
		ExceptionReminderSet,     // Reminder added
		ExceptionLocation,        // Locatetion changed
		ExceptionShowTimeAs,      // Transparency changed
		ExceptionIsAllDay,        // Is-All-Day changed
		ExceptionLabelColor,      // Label/Color changed
		ExceptionNotesAttachment  // A note or an attachment has changed/been added
	};

	// The modified data of a specific occurence in a recurrent 
	// serie of events or tasks.
	//
	// The RecurrenceExceptionData structure is special in the
	// regard that it always contains the start and end times
	// of the occurrence. 
	//
	// The ExceptionData union is also special in that it has no 
	// support for specifying start or end time modifications. 
	// Such modifications must be expressed in the 'start' and 
	// 'end' member in the RecurrenceExceptionData structure.
	// 
	// The only reason for this is that the underlying native 
	// MAPI code is greately simplified by this, admittedly, 
	// ugly design.
	union ExceptionData switch (RecurrenceException) { 
	case ExceptionNONE            :               // any instances with this discriminator will be ignored
	case ExceptionDeletion        : boolean moot; // the value of moot is ignored 
	case ExceptionDescription     :  
	case ExceptionLocation        : string str;
	case ExceptionReminderTime    :   
	case ExceptionReminderSet     :   
	case ExceptionShowTimeAs      :   
	case ExceptionIsAllDay        :   
	case ExceptionLabelColor      : unsigned long int32;   // a 32 bits unsigned integer value
	case ExceptionNotesAttachment : 
	case ExceptionAttendee        : seq_octet binary_data; // data for attachment/note/attendee (not supported yet)
	};
	struct RecurrenceExceptionData {
		OccurrenceTime oc_time; // 0 => the series, 1 => the first occurrence, 2 => the second occurrence...
		FILETIME start;        // start time of the occurrence
		FILETIME end;          // endtime of the occurrence
		ExceptionData data;
	};
	typedef sequence<RecurrenceExceptionData> seq_RecurrenceExceptionData;

	typedef octet DayOfWeek;
	const DayOfWeek Monday     = 0x01;
	const DayOfWeek Tuesday    = 0x02;
	const DayOfWeek Wednessday = 0x04;
	const DayOfWeek Thursday   = 0x08;
	const DayOfWeek Friday     = 0x10;
	const DayOfWeek Saturday   = 0x20;
	const DayOfWeek Sunday     = 0x40;
 
	enum Month {
		January,
		February,
		March,
		April,
		May,
		June,
		July,
		August,
		September,
		October,
		November,
		December
	};

	enum RecurrenceType {
		recur_none,                                        // not a recurring event or task
		recur_daily_every_N_days,
		recur_weekly_every_N_weeks,                        // all events and non-regenerating tasks
		recur_weekly_every_N_weeks_for_regenerating_tasks,
		recur_monthly_every_N_months_on_day_D,
		recur_monthly_every_N_months_on_Xth_Y,             // e.g "every 2nd months on the 3th Tuesday"
		recur_yearly_on_day_D_of_month_M,
		recur_yearly_on_the_Xth_Y_of_month_M
	};

	enum RecurrenceTerminationType {
		term_date,   // terminate on a given date
		term_number, // terminate after a given number of occurrences
		term_never   // never terminate, recurring infinitely
	};

	struct data_recur_daily_every_N_days {
		unsigned long N;
		boolean regenerating_task;
	};

	struct data_recur_weekly_every_N_weeks {
		unsigned long N;
		boolean regenerating_task;
		DayOfWeek which_days;      // Bitmask for determining which days of the week the event recurs on using DayOfWeek
	};

	struct data_recur_weekly_every_N_weeks_for_regenerating_tasks {
		unsigned long N; 
	};

	struct data_recur_monthly_every_N_months_on_day_D {
		unsigned long N;
		octet D;                   // 1..31 - if (D>=31) ==> (D==31)
		boolean regenerating_task;
	};

	struct data_recur_monthly_every_N_months_on_Xth_Y {
		unsigned long N;
		octet X;                    // 1 for first occurrence, 2 for second, etc. 5 for last occurrence.
		DayOfWeek Y;                // Bitmask for determining which days of the week the event recurs on using DayOfWeek
		boolean regenerating_task;
	};

	struct data_recur_yearly_on_day_D_of_month_M {
		octet D;                   // 1..31 - if (D>=31) ==> (D==31)
		Month M;                   
		boolean regenerating_task;
	};

	struct data_recur_yearly_on_the_Xth_Y_of_month_M {
		octet X;     // 1 for first occurrence, 2 for second, etc. 5 for last occurrence.
		DayOfWeek Y; // Bitmask for determining which days of the week the event recurs on using DayOfWeek
		Month M;     
	};

	union RecurrencePattern switch (RecurrenceType) {
	case recur_daily_every_N_days : data_recur_daily_every_N_days daily_every_N_days;
	case recur_weekly_every_N_weeks : data_recur_weekly_every_N_weeks weekly_every_N_weeks;
	case recur_weekly_every_N_weeks_for_regenerating_tasks : data_recur_weekly_every_N_weeks_for_regenerating_tasks weekly_every_N_weeks_for_regenerating_tasks;
	case recur_monthly_every_N_months_on_day_D : data_recur_monthly_every_N_months_on_day_D monthly_every_N_months_on_day_D;
	case recur_monthly_every_N_months_on_Xth_Y : data_recur_monthly_every_N_months_on_Xth_Y monthly_every_N_months_on_Xth_Y;
	case recur_yearly_on_day_D_of_month_M : data_recur_yearly_on_day_D_of_month_M yearly_on_day_D_of_month_M;
	case recur_yearly_on_the_Xth_Y_of_month_M : data_recur_yearly_on_the_Xth_Y_of_month_M yearly_on_the_Xth_Y_of_month_M;
	};

	struct RecurrenceState {
		unsigned long occurrence_count;       // The total number of occurrences to happen if how_to_end is term_date or term_number. 10 (the default number) for an infinite sequence. 
		unsigned long exception_count;        // Number of exceptions to the pattern (i.e. deleted or modified occurrences)
		unsigned long modification_count;     // Number of modified occurrences
		RecurrenceTerminationType how_to_end; // never, after a certain number of occurences or on a specific date
		DayOfWeek first_day_of_week;          // First day of week

		RecurrencePattern pattern;
	};

}; // End of module BRUTUS

#endif
