/*
 *  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: System & Document Space Connection 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

#define MAXSYSTEMS 100              // arbitrary         
#define MAXDOCSPACE_PERSYSTEM 100   // Maximums

// external functions
DmaRC FreeString(pDmaString pDmaStr);
pDmaString  AsciiDmaStringFromCString(char *string);

// forward declarations
DmaRC Authenticate ( IUnknown *punk, char *LoginStr );

/* 
 * This example is comprised of 2 loops; an outer system loop,
 * and an inner document space loop
 *
 * An enumerated list of systems that are connected to the system manager
 * is created. 
 *
 * For each system (the outer loop) the Display name is obtained, 
 * and an authentication is performed.
 *
 * Inside this outer loop an enumeration of all the document spaces is
 * obtained.
 *
 * For each document space in that system(the inner loop) the Display name 
 * is obtained, and an authentication is performed 
 */

DmaRC IntegrationExample()
{
    DmaRC            rc;
    pDmaString       pSystemDisplayName, pDocSpaceDisplayName;
    IdmaSystemManager *pISysMgr;
    IdmaEnumOfObject  *pIEnumSystems,*pIEnumDocSpaces;
    DmaIndex32        NumSystem, NumDocSpace;
    IdmaProperties    *pIProps;
    DmaIndex32        iSystem, iDocSpace;
    char *SystemLoginString =   "SCHEME=DMA-BASIC;UID=SYSTEM;PWD=MANAGER";
    char *DocSpaceLoginString = "SCHEME=DMA-BASIC;UID=SCOTT;PWD=TIGER";

    /*
     * Get a IdmaSystem Manager Interface
     */
    rc = dmaConnectSystemManager( NULL,           // Environment info
                                  NULL,           // System config location
                                  NULL,           // IMalloc Interface
                                  DMA_CS_UNICODE, // Char Set Coding ID
                                  NULL,           // Name Of Display
                                  IID_IdmaSystemManager,   
                                                  // Desired Interface 
                                  (pDmapv) &pISysMgr);

    if (rc != DMARC_OK)
    {
        return(rc);
    }

    // All future error handling omitted for simplicity

    /*
     *  Enumerate the Systems Connected To
     */
    rc = pISysMgr->EnumerateSystems(IID_IdmaEnumOfObject,
                                   (pDmapv) &pIEnumSystems); 

    IUnknown * rgpunkSystems[MAXSYSTEMS];

    rc = pIEnumSystems->GetNextObject ( MAXSYSTEMS, rgpunkSystems, &NumSystem );
    pIEnumSystems->Release();  // no longer needed

    /* 
     * Loop through systems and attempt to find the name of a system
     */

    for (iSystem = 0; iSystem < NumSystem; iSystem++)
    {
        /*
         * Get System's Property Interface
         */
        rc = rgpunkSystems[iSystem]->QueryInterface( IID_IdmaProperties, 
                                                     (pDmapv)&pIProps );
        /*
         * Get Display Name
         */
        rc = pIProps->GetPropValStringById ( &dmaProp_DisplayName,
                                             &pSystemDisplayName );
        pIProps->Release();        // No Longer Needed

        // Authenticate if necessary
        rc = Authenticate ( rgpunkSystems[iSystem], SystemLoginString );

        FreeString(pSystemDisplayName);

        /*
         *  Enumerate the DocSpaces Available for this system
         */
        IdmaSystem *pISystem;
        rc = rgpunkSystems[iSystem]->QueryInterface ( IID_IdmaSystem,
                                                      (pDmapv)&pISystem );

        rc = pISystem->EnumerateDocSpaces( IID_IdmaEnumOfObject,
                                           (pDmapv) &pIEnumDocSpaces); 

        pISystem->Release();
        rgpunkSystems[iSystem]->Release();

        IUnknown *rgpunkDocSpaces[MAXDOCSPACE_PERSYSTEM];

        rc = pIEnumDocSpaces->GetNextObject ( MAXDOCSPACE_PERSYSTEM,
                                              rgpunkDocSpaces,
                                              &NumDocSpace );
        pIEnumDocSpaces->Release(); // no longer needed

        /* 
         * Loop through Doc Spaces in this System
         */

        for (iDocSpace = 0; iDocSpace < NumDocSpace; iDocSpace++)
        {
            rc = rgpunkDocSpaces[iDocSpace]->QueryInterface (
                                                    IID_IdmaProperties, 
                                                    (pDmapv) &pIProps ); 

            rc = pIProps->GetPropValStringById ( &dmaProp_DisplayName,
                                                 &pDocSpaceDisplayName );
            pIProps->Release();        // No Longer Needed

            // Authenticate if necessary
            rc = Authenticate ( rgpunkDocSpaces[iDocSpace], 
                                DocSpaceLoginString );

            rgpunkDocSpaces[iDocSpace]->Release();     // No Longer Needed

            FreeString(pDocSpaceDisplayName);

        }  // while no more Doc Spaces enumerated

    } // while no more Systems enumerated

    return(DMARC_OK);
}

 
DmaRC Authenticate (
    IUnknown *punk,
    char *LoginStr )
{
    IdmaAuthentication *pIAuth;

    DmaRC rc = punk->QueryInterface ( IID_IdmaAuthentication,
                                      (pDmapv)&pIAuth );
    if ( rc == DMARC_OK )
    {
        // The authentication interface is supported. Therefore we must
        //  try to authenticate.
        pDmaString StringIn;
        pDmaString StringOut;

        StringIn = AsciiDmaStringFromCString(LoginStr);

        do 
        {
            // Iteratively attempt to Authenticate
            rc = pIAuth->AuthenticateUser ( StringIn, &StringOut );

            FreeString(StringIn); // no longer needed

            if ( rc == DMARC_ALREADY_AUTHENTICATED || 
                 rc == DMARC_OK)
            {
                FreeString(StringOut);
                return(DMARC_OK);
            }

            if (rc == DMARC_NEED_MORE_DATA)
            {
                /* 
                 * Note:At this point the Application would display
                 * the information in the StringOut and get the
                 * additional parameters needed in LoginStr via
                 * user interface.
                 */ 

                StringIn = AsciiDmaStringFromCString(LoginStr);
                FreeString(StringOut); 
            }
            
        } while (rc == DMARC_NEED_MORE_DATA);

        pIAuth->Release();
    }
    else if ( rc == DMARC_BAD_INTERFACE )
    {
        // The authentication interface is not supported, meaning that
        //  it is not necessary to authenticate.
        rc = DMARC_OK;
    }

    return(rc);
}