/* OdmNative100.hpp 0.23             UTF-8                   dh:2007-01-18
 *
 *                OdmNative100 ENTRY AND INTERFACE DEFINITIONS
 *                ********************************************
 *
 * This header file defines the IodmApplication100 interface and the
 * entry to the OdmBindNative100 factory function.  This function and the
 * interfaces to the COM objects it creates provide all of the OdmNative100
 * functionality needed to implement the OdmConnection object of ODMJNI 1.0.
 *
 *
 *                       Copyright © 2006-2007 NuovoDoc
 *                           <http://NuovoDoc.com>
 *
 *              This software is released under the Open
 *              Document Management API License 1.0, an open-
 *              source software license modeled on the BSD
 *              License template.
 *
 *              A copy of the license should accompany the
 *              source code that includes this file.  If the
 *              license has has been separated from the code,
 *              obtain a copy at <http://DMware.info/license/>.
 *
 *  FIXME: The level of abstraction of this interface above ODMA is broken.
 *         For initial development and confirmation, we need to represent
 *         the higher-level abstraction of wrappers like practical100
 *         in parts because of the need to return ODMSTATUS values in
 *         some cases and QueryInterface results in other cases.
 *
 *         This has the lower-level exposed bits be fragile and depending
 *         on too many out-of-band preconditions.
 *
 *         The remedy is to coalesce operations that traffic in
 *         Document IDs and Document Locations into single interface
 *         delivering functions in the manner of makeWorkingDocument.
 *         This is done by using HRESULT everywhere and eliminating the
 *         returns of ODMSTATUS in most cases.  Those ODMSTATUS values
 *         that don't map to common HRESULT values will be incorporated
 *         in the operation-specific block.  The higher-level functions
 *         that use value ranges to distinguish between interface references
 *         and error codes (as in ODMJNI 1.0) can handle the rewriting of
 *         HRESULTS to small non-zero numbers (in range 1 to 31).
 *
 *         This will make breaking changes of OdmNative100 that must be
 *         accomodated in a corresponding upgrade of odmjni100.dll.  The
 *         benefit will be in the stability of the contracted OdmNative100
 *         interfaces and greater simplicity in the odmjni100.dll handling
 *         of native methods for ODMJNI 1.0.
 *
 *         These changes are not expected before the 0.50beta release of
 *         ODMJNI 1.0.
 */

#ifndef ODMNATIVE100_H
#define ODMNATIVE100_H

#define OdmNative100_H_Version_ "0.22 OdmNative100.hpp " \
                                "2007-01-01T19:39Z"

    /* This is a preprocessor text about this header file.  It is a
       string value that can be incorporated into other text.
       */

#ifndef __cplusplus
#error  OdmNative100 INTERFACE DEFINITIONS REQUIRE C++.  DON'T USE WITH C.
    /* XXX: We might fix this some day, but not now. */
#endif

#include <windows.h>

#include "Odma32types100.h"
    /* Stick with the ODMA 1.0 Types and Values definitions */


/*                        Define IodmNative IID Values
                          ***************************** */

    /*  Each interface has a globally-unique Interface ID (IID).  The
        IIDs are specified by Microsoft for the standard COM interfaces
        such as IUnknown.  For the IodmNative-unique interfaces, the IIDs
        have been generated using the GuidGen.exe tool provided with
        the Microsoft Platform SDK.
        */

#ifndef IID_IodmUnknown_
#define IID_IodmUnknown_ { 0x00000000, 0x0000, 0x0000, \
               { 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46 } }

        /* This is the IID for the standard IUnknown interface. The
           distinct name is used to avoid confusion with any name given
           in <windows.h> and to also avoid assumption of where there
           might be a stored copy of the IID.  If it is necessary to
           store this or any other IID_Iodm..._ value, use something
           like

                static const IID IID_IodmUnknown = IID_IodmUnknown_ ;

           to make a private, local copy.  That's how it is done
           internal to the implementation of OdmNative classes.  There
           is no dependency on a shared library like UUID.lib even for
           such well-known IIDs as the one for IUnknown.
           */
#endif


#define IID_IodmApplication100_ { 0x81069e90, 0x74d2, 0x4472, \
               { 0x8e, 0xea, 0xf0, 0xf2, 0xd1, 0xcb, 0xe1, 0x22 } }


        /* This IID represents both the signature and the contract for
           the current version of IodmApplication100.  Every time the
           signature and contract change for a version released to the
           wild, there will be a new IID.  This is a safeguard against
           calling for an implementation of a different interface contract
           than the one represented by this IID.

           Each caller must make their own stored copy of an IID with
           this value.  It is important to avoid  using a shared value
           that might also be the one employed by an implementation, losing
           the benefit of interface confirmation by query.

           Once an interface is frozen and is to be preserved as a distinct
           version, later versions will have new names as well as their own
           IIDs.  Generally, the only time an IID changes and the interface
           name remains unchanged is during alpha and beta releases of the
           interfaces, as in intermediate stages of IodmApplication100
           development.

           The current IID was introduced in version 0.21 of this interface-
           definition header file.
           */


/*                     Define IodmNative Interfaces
                       **************************** */


interface IodmApplication100 : IUnknown
{   /* Inherit from IUnknown as required for all COM interfaces */

    virtual LPCSTR WINAPI interfaceImplementation(void) PURE;
        /* A constant '\0'-terminated char string of '\n'-separated lines
           that identify the version of I0dmApplication100 implementation.
           This constant is available only so long as the interface is
           held.  A copy must be made for use beyond that duration.
           */

    virtual BOOL WINAPI hasConMan(void) PURE;
        /* TRUE if the ODMA Connection Manager is available.  FALSE
           if the ODMA Connecction Manager cannot be linked.

           This value will not change.  There is no action that will
           change the result for a given IodmApplication100 interface
           reference.
           */

    virtual BOOL WINAPI hasDefaultDMS(void) PURE;
        /* TRUE if the ODMA Connection Manager is available and there is
           a default DMS for the current application.  FALSE otherwise.

           Again, this value will not change.  There is no action that
           will change the result for a given IodmApplication100 interface
           reference.

           It may still be possible to access a DMS by other means.  But
           operations that depend on a default DMS cannot succeed when
           hasDefaultDMS() is FALSE.
           */


    /* Implementation Note: There is no indication when the operations
       that determine these results are actually performed.  They must
       be determined at most once and the same result reported thereafter.

       It is recommended that implementations be "lazy" and only
       determine these conditions when the result is requested or when
       determination is a prerequisite to the performance of other
       operations.

       This delay is valuable for speeding up application initialization
       and when there is some concern about not having the ODMA Connection
       Manager loaded until the caller is operating under thread-safe conditions on a GUI thread.
       */


    virtual ODMSTATUS WINAPI
        selectDocID(LPSTR pszDocId, BOOL *pViewMode) PURE;

        /* Method for bringing up the ODMSelectDoc dialog and capturing
           the result.  The *pViewMode output is TRUE if the document
           should be opened in ViewMode.

           Possible ODMSTATUS values are:

                ODM_SUCCESS  there is a Document ID and *pViewMode
                             determines whether access should be in
                             ViewMode or else ModifyMode.

                 ODM_E_FAIL  There is a failure in usage or operation.

               ODM_E_CANCEL  The user has cancelled the operation.  See the
                             considerations about "stuck" cancel status
                             under the ODMSelectDoc description in
                             Odma32api100.h.

                ODM_E_NODMS  There is no (Default) DMS available to perform
                             this operation.

            ODM_E_APPSELECT  The user requests that the application perform
                             the non-ODMA operation for which this ODMA
                             operation was given the "first refusal."
            */

    virtual ODMSTATUS WINAPI
        openDoc(LPCSTR pszDocId, LPSTR pszDocLoc, BOOL viewMode) PURE;

        /* OpenDoc uses a give ODMA Document ID and a chosen viewMode
           to request that the DMS responsible for the document place it
           in an opened state and provide a location that the application
           can use to create, access, and update the content for the DMS
           document.

           If the Document ID is for a freshly-initiated document that has
           not yet had content provided, viewMode should be FALSE.  The
           pszDocLoc[] is set to the file-system location where the
           document content should be stored.

           In all other cases of successful openDoc operation, the value of
           pszDocLoc[] is the file-system location where the content has
           been delivered and where any changes should be stored.

                DOCUMENT ME
                ***********
           */

    virtual HRESULT WINAPI
        makeWorkingDocument(  LPCSTR pszDocId, LPSTR pszDocLoc,
                              BOOL viewMode,
                              REFIID rIID, void **ppIface
                              ) PURE;

        /* Given successful results from an openDoc, create a working-
           document object that can be used to operate with the document.

                DOCUMENT ME
                ***********
           */


    virtual ODMSTATUS WINAPI
        startNewDoc(  LPSTR pszDocId, LPCSTR pszDocFormatName ) PURE;

        /* This operation causes the Default DMS to be requested to
           prepare for establishment of a new Document.  If the
           operation succeeds, the Document ID is returned in the
           pszDocId[] buffer.  This Document ID can be opened and
           the new content supplied for it.

          Possible ODMSTATUS values are:

                ODM_SUCCESS  there is a Document ID for provisional
                             use in establishing a new document.

                 ODM_E_FAIL  There is a failure in usage or operation.

               ODM_E_CANCEL  The user has cancelled the operation.  See the
                             considerations about "stuck" cancel status
                             under the ODMSelectDoc description in
                             Odma32api100.h.

            ODM_E_APPSELECT  The user requests that the application perform
                             the non-ODMA operation for which this ODMA
                             operation was given the "first refusal."

                      other  are to be treated as ODM_E_FAIL.
            */


    virtual HRESULT WINAPI
        makePendingDocument(  LPCSTR pszDocId, LPCSTR pszDocLoc,
                              REFIID rIID, void **ppIface
                              ) PURE;

        /* This operation causes a pending document object to be
           created for the given Document ID value and the given
           docLocation.  This operation is the natural follow-on
           to successful startNewDoc and following openDoc.

           FIXME: It is not OK to do multiple makePendingDocument and
              makeWorkingDocument objects with the same parameters.
              Those are essentially one-time uses.  That suggests we
              need to refactor these methods or use a higher-level
              wrapper.  The only problem is the need to use special
              HRESULTS for the error cases, but we can do that using
              application-specific HRESULTS that decode into ODMSTATUS
              values quite easily.

                    DOCUMENT ME
                    ***********
           */

    };  /* IodmApplication100 */



/*                       Define OdmBindNative100 Entry
                         ***************************** */


HRESULT WINAPI
    OdmBindNative100(  const char pszAppId[],
                                     /* Clean Basic Latin string of
                                        the Application ID */
                           REFIID pIID,
                                     /* The requested interface */
                             void **ppIface
                                     /* The location to receive the
                                        Interface pointer or NULL */
                       );

        /* OdmBindNative100 constructs an OdmApplication object that
           is tied to the given Application ID.  This object provides an
           application face to the ODMA Connection Manager.  It and the
           objects produced by it are the only users of the ODMA API.  The
           application is expected to obtain all of its ODMA-aware behavior
           via the IodmNative interfaces provided for that purpose.

           If the construction is successful, OdmBindNative returns via the
           OdmApplication's IodmApplication::QueryInterface(piid, ppIface).
           At least IUnknown and IodmApplication100 are implemented by the
           object.
           */


/* More information about the construction of COM interfaces and their
   defining header files can be found in

       Rogerson, Dale.  Inside COM: Microsoft's Component Object Model.
           Microsoft Press (Redmond, WA: 1997).  ISBN 1-57231-349-8 pbk.

   For our needs, that simple style and the basic bottom-up structure
   with hand-crafted binary interfaces works just fine.

   The Microsoft Platform SDK has a set of COM Tutorial Samples that are
   also useful.  Look under Samples\Com\Fundamentals\TutSamp\TutorIAL.Htm
   */


/* 0.23 2007-01-18-13:29 Add results information to startNewDoc.
   0.22 2007-01-01-11:39 Correct the new methods to all be PURE so the
        inheritance of IodmApplication100 works properly for OdmApplication.
        Add up-front FIXME about the refactoring that will happen to give us
        pure abstractions in the OdmNative100 interfaces.
   0.21 2006-12-30-17:26 Add in the additional methods needed for complete
        practical100 implementation.
   0.20 2006-11-25-20:56 Incorporated in the 0.20alpha OdmNative100 release.
   0.09 2006-11-23-14:32 Change selectDoc to selectDocID as more accurate.
   0.08 2006-11-22-22:32 Add pViewMode output for selectDoc method and
        document the operation.
   0.07 2006-11-22-19:00 Eliminate use of fixed-size arrays in the
        selectDoc prototype.
   0.06 2006-11-22-18:03 Switch from Odma.h to Odma32types100.h for
        ODMA types and values here.
   0.05 2006-11-21-15:12 Add provisional selectDoc method that can
        be used as a lead-in to known-document opening.
   0.04 2006-11-18-23:34 Add interfaceImplementation method to the
        IodmApplication100 interface and define OdmNativeVersion_ value.
   0.03 2006-11-16-21:02 Change OdmBindNative100 to C++ signature and
        use REFIID out of harmony with QueryInterface and other usages.
   0.02 2006-11-15-21:55 Rename to OdmNative100.hpp and begin tracking to
        definitions in OdmNative100.cpp.  The key interface settles out to
        be IodmApplication100 and the external entry into OdmNative100 is
        defined as OdmBindNative100.
   0.01 2006-11-15-17:58 Simplify to IodmNative.hpp and document the use of
        the IIDs and the individual interface functions.  We have committed
        to using C++ for simplicity and clarity.  There is no meaningful
        use outside of C++ for OdmNative.
   0.00 2006-11-14-18:50 Obtain the information that I need for the initial
        version.  Simply replicate IUnknown, adding only the simplest methods for initial operation.
        */

#endif ODMNATIVE100_H
/* $Header: /ODMdev/info/odma/OdmNative100/OdmNative100.hpp 14    07-01-18 13:35 Orcmid $
   */
/*                     *** end of OdmNative100.hpp ***                  */
