/*
 *  Copyright 1995,1996,1997 by the Association for Information and Image Management Int'l
 *                                             1100 Wayne Avenue
 *                                             Silver Spring, MD 20910-5603
 *                                             Tel: 301/587-8202
 *                                             Fax: 301/587-2711
 *      All Rights Reserved.
 *      DMA (Document Management Alliance) working group.
 *
 *  Code example: Versioning Example
 *
 */

#include <dmatypes.h>
#include <dmacom.h>
#include <dmarc.h>
#include <dmaenums.h>
#include <dmaiface.h>
#include <dmaenums.h>
#include <dmaids.h>
#include <dmaidvar.h>
#include <dmacfunc.h>

#ifndef NULL
#define NULL    0
#endif

// This example creates a new versioned entity (Configuration History
//  and primary Version Series), then makes a Reservation against the
//  version series and checks in a new DocVersion.
//
// The following function is assumed to exist outside this module
//  for initialising (but not saving) a new DocVersion object. See
//  the content samples to see how this might be done.
extern DmaRC PrepareNewDocVer ( IdmaObjectFactory *pIFactory,
                                DMA_REFIID riidDovVer,
                                pDmapv ppIDocVer );

// Forward declarations
DmaRC DoExecuteChange ( IUnknown *punkToSave );

DmaRC VersionExample (
    IdmaObjectFactory *pIFactory )
{
    // Step 1: Create a Configuration History object
    IdmaEditProperties *pedpropCfg;
    DmaRC rc = pIFactory->CreateObject ( &dmaClass_ConfigurationHistory,
                                         IID_IdmaEditProperties,
                                         (pDmapv)&pedpropCfg );
    if ( rc != DMARC_OK )
        return rc;

    // All remaining error handling omitted

    // Set any extended properties of Config History
    // *** None in this example ***

    // Step 2: Create a Version Series object
    IdmaEditProperties *pedpropVerSer;
    rc = pIFactory->CreateObject ( &dmaClass_VersionSeries,
                                   IID_IdmaEditProperties,
                                   (pDmapv)&pedpropVerSer );

    // Step 3: associate Version Series with Config History as primary
    rc = pedpropVerSer->PutPropValObjectById ( &dmaProp_ConfigurationHistory,
                                               pedpropCfg );
    rc = pedpropVerSer->PutPropValBooleanById ( &dmaProp_IsPrimarySeries,
                                                DMA_TRUE );

    // Step 4: save both objects. Note that the order is important
    rc = DoExecuteChange ( pedpropCfg );
    rc = DoExecuteChange ( pedpropVerSer );

    // The Config History object is not required in what follows.
    pedpropCfg->Release();

    // Get the Version Series interface
    IdmaVersionSeries *pIVerSer;
    rc = pedpropVerSer->QueryInterface ( IID_IdmaVersionSeries,
                                         (pDmapv)&pIVerSer );
    // The EditProperties interface is no longer required
    pedpropVerSer->Release();

    // Step 5: Create a Reservation object
    IdmaEditProperties *pedpropRes;
    rc = pIFactory->CreateObject ( &dmaClass_Reservation,
                                   IID_IdmaEditProperties,
                                   (pDmapv)&pedpropRes );

    // Set any extended properties of Reservation object
    // *** None in this example ***

    // Step 6: Make the reservation against the version series
    pIVerSer->SetReserveNext ( pedpropRes );
    pedpropRes->Release();      // no longer required
    DoExecuteChange ( pIVerSer );

    // Step 7: Prepare new Version Description
    IdmaEditProperties *pedpropVerDesc;
    rc = pIFactory->CreateObject ( &dmaClass_VersionDescription,
                                   IID_IdmaEditProperties,
                                   (pDmapv)&pedpropVerDesc );

    // Set any extended properties of Version Description object
    // *** None in this example ***

    // Step 8: Prepare new DocVersion
    IdmaVersionable *pverDocVer;
    rc = PrepareNewDocVer ( pIFactory, IID_IdmaVersionable,
                            (pDmapv)&pverDocVer );

    // Step 9: Make the checkin
    rc = pverDocVer->SetCheckIn ( pIVerSer, pedpropVerDesc );
    pIVerSer->Release();
    pedpropVerDesc->Release();
    rc = DoExecuteChange ( pverDocVer );
    pverDocVer->Release();

    return rc;
}

DmaRC DoExecuteChange (
    IUnknown *punkSave )
{
    IdmaConnection *pconnSave;
    DmaRC rc = punkSave->QueryInterface ( IID_IdmaConnection,
                                          (pDmapv)&pconnSave );
    if ( rc == DMARC_OK )
    {
        rc = pconnSave->ExecuteChange ( NULL,
                                        DMA_MODIFY_UNPROTECTED,
                                        DMA_TRUE );     // refresh
        pconnSave->Release();
    }

    return rc;
}