#pragma once;

// outdated (old) version of serialized object
#define EXAMPLEDO_STREAM_VERSION_1 0x00000001
// current version of serialized object
#define EXAMPLEDO_STREAM_VERSION 0x00000002

/**
@interface IRdExampleDataObject
This is an example of data object containing personal data. Since it implements IDispatch, it can be used 
from script. First version contained only name and address, then age was added. To maintain compatibility
with previously serialized data (where age was not present), versioning is employed. See Load implementation
for details
*/
// IRdExampleDataObject
[
    object,
    uuid("8378F80B-C269-4bc8-9DF7-622BF2E57D28"),
    helpstring("IRdExampleDataObject Interface"),
    pointer_default(unique)
]
__interface IRdExampleDataObject : IDispatch
{
    [id(1), helpstring("method SetName")] HRESULT SetName( [in] BSTR bszName );
    [id(2), helpstring("method GetName")] HRESULT GetName( [out, retval] BSTR *pbszName );
    [id(3), helpstring("method SetAddress")] HRESULT SetAddress( [in] BSTR bszAddress );
    [id(4), helpstring("method GetAddress")] HRESULT GetAddress( [out, retval] BSTR *pbszAddress );
    [id(5), helpstring("method SetAge")] HRESULT SetAge( [in] int age );
    [id(6), helpstring("method GetAge")] HRESULT GetAge( [out, retval] int *pAge );
};

// CRdExampleDataObject
[
    ATTRIBUTE_COCLASS,
    threading(both),
    vi_progid("ExamplesPlugin.RdExampleDataObject"),
    progid("ExamplesPlugin.RdExampleDataObject.1"),
    version(1.0),
    uuid("4ED53482-4F50-47ca-81AF-ACF9F7B2F2FE"),
    helpstring("RdExampleDataObject Class")
]
class ATL_NO_VTABLE CRdExampleDataObject : 
    IMPLEMENT_DISPATCH_TYPELIB(IRdExampleDataObject),
    public IRsDataObject,       
    public IRsPersistStream,    
    public IRsCloneable
{
private:
    /// Flag that data was changed after last save
    BOOL    m_bDirty;

    // Member of data object (person name)
    CComBSTR m_bszName;

    // Member of data object (person address)
    CComBSTR m_bszAddress;

    // Member of data object (person age) Note that this member is available only in versions
    // 0x00000002 and higher (see Load)
    int m_age;
    
public:
    
    // Default constructor
    CRdExampleDataObject()
    {
        m_age = 0;
        m_bszName = L"";
        m_bszAddress = L"";
    }

    // Destructor.
    virtual ~CRdExampleDataObject()
    {
    }

    // This method does usually nothing, but if object aggregates other data objects, instances can be created here.
    HRESULT FinalConstruct()
    {
        return S_OK;
    }

    // This method does nothing. If object contains aggregated instances, release them here
    void FinalRelease() 
    {
    }

    // IRdExampleDataObject
    STDMETHOD(SetName)(BSTR bszName);
    STDMETHOD(GetName)(BSTR *pbszName);
    STDMETHOD(SetAddress)(BSTR bszAddress);
    STDMETHOD(GetAddress)(BSTR *pbszAddress);
    STDMETHOD(SetAge)(int age);
    STDMETHOD(GetAge)(int *pAge);

    // IRsCloneable
    STDMETHOD(Clone)(IRsObject** ppNewObj);

    // IRsDataObject
    STDMETHOD(SetDefault)(void);
    
    // IRsPersistStream
    /** Returns S_FALSE if object is NOT changed since last save, S_OK otherwise */
    STDMETHOD(IsDirty)();
    /** Loads the content of data object from stream
    @param pStm - stream to read from
    @param pObjFileHeaderInfo - version information about object in stream
    */
    STDMETHOD(Load)(IStream *pStream, RtObjFileHeaderInfo* pObjFileHeaderInfo);
    /** Saves the data object to stream using current stream version
    @param pStream - stream to write to
    @param fClearDirty - flag indicating that "dirty" state of object must be cleared after saving it
    */
    STDMETHOD(Save)(IStream *pStream, RtBOOL fClearDirty);
    
    // Declares current version of serialized data
    RS_DECLARE_FILE_HEADER_INFO(EXAMPLEDO_STREAM_VERSION);
    
    // IRsObject
    RS_DECLARE_IRS_OBJECT(IRdExampleDataObject, L"Example data object")

   
    DECLARE_PROTECT_FINAL_CONSTRUCT()
};