//
//  (C) Copyright 1994-2008 by Autodesk, Inc.  All rights reserved.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted, 
// provided that the above copyright notice appears in all copies and 
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting 
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. 
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.  AUTODESK, INC. 
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to 
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//

// DESCRIPTION: This file contains base definitions used throughout
//              the MCAD API.
//
#ifndef AMIBASE_H
#define AMIBASE_H

// Includes
//
#include <tchar.h>
#include <basetsd.h>
#include "rxobject.h"
#include "dbid.h"
#include "dbmain.h"
#include "gevec3d.h"
#include "gepnt3d.h"

#include "miStatus.h"
#include "miarray.h"
#include "AdAChar.h"

class AcApDocument;

// Definitions
//
#define NULL_FUNC_PTR       (AmiNullFuncPtr)0
#define UNSET_FUNC_ID       -1
#define UNSET_APP_ID        -1
#define NUM_INIT_API_FUNCS  400 // Maximum number of registered functions.
#define NUM_INIT_APPS       5

// Forward class declarations.
//
class AcDbDwgFiler;
class AcDbDatabase;
class AcDbFullSubentPath;
class AcGePoint3d;
class AcDbSubentId;
class AcDbObjectId;
class AcMeDoc;
class AcDbXrefGraph;

// "Ami" namespace scopes names to avoid collisions.
//
namespace Ami
{
    // Enumeration of valid key types.
    //
    enum KeyType
    {
        objectKey,
        geomKey,
        pointKey,
        curveKey,
        lineKey,
        arcKey,
        ellipseKey,
        splineCrvKey,
        polylineKey,
        auglineKey,
        surfKey,
        planeKey,
        coneKey,
        cylinderKey,
        sphereKey,
        torusKey,
        splineSrfKey,
        constrKey,
        compConstrKey,
        sketchConstrKey,
        paramKey,
        sketchKey,
        featKey,
        bodyKey,
        solidKey,
        partKey,
        compKey,
        compDefKey,
        sceneKey,
        vectorKey,
        dwLayoutKey,
        dwvwKey,
        dwAnnotKey,
        sketchPlaneKey,
        oldSize,            // for binary compat., keep placeholder
        quiltKey,
        compViewKey,
        compViewDefKey,
        folderKey,
        folderDefKey,
        annotationViewDefKey,
        hideKey,
        cpxHideKey,
        size
    };

    // DesignEnvironment must be kept in sync with AcMeStateMgr::modelState
    //
    enum DesignEnvironmentType
    {
       kPartAssembly,  // Database only contains components, no parts.
       kSinglePart,    // Database only contains a single part, no components.
       kProxy,         // File was created on a newer Desktop.
                       // This state will NEVER be saved to a file.
       kMultiPart,     // Database contains more than one part, no components. (Legacy data.)
       kMixed,         // Database contains both components and parts.(Legacy data.)
       kForeign,       // No Parts or Components in file
       kUnknown        // MDT APP's not loaded, file state undeterminable
    };

    // DwgType identifies the content of the drawing
    enum DwgType {
      kAcad = 0,                          // AutoCAD
      kAcadM = 2,                         // AutoCAD Mechanical
      kAcadMStruct = 3,                   // AutoCAD Mechanical Structure
      kMDT = 4,                           // MDT Assembly
      kMDTPart = 5,                       // MDT Part
      kInventorLink = 6,                  // Inventor Link
      kUndefined = 7                      // Undefined Drawing Type
    };

    // DesignMode
    //
    enum DesignModeType
    {
        kModelMode,       // Developing the model whether assembly or part
        kDrawingMode,     // Creating drawings
        kSceneMode,       // Creating scenes for assemblies
        kUninitialized    // when there is no database
    };

    // AttributeDataType
    // Used to specify a descriptor attribute data type.
    // For internal use only.
    //
    enum AttributeDataType
    {
        attTypeInt        =   0,
        attTypeDouble     =   1,
        attTypeCharPtr    =   2,
        attTypeEnum       =  10,
        attTypePoint3d    =  50,
        attTypeMatrix3d   =  51,
        attTypeEntity3d   =  55,
        attTypeObjKey     =  70,
        attTypeValue      =  71,
        attTypeSelection  =  72,
        attTypeExternalId =  80,
        attTypeSpecial    =  9999
    };

    // AttSpecialValues
    // Used to pass special values as function arguments.
    //
    enum AttSpecialValues
    {
        attNAV      = 1         // NAV:  Not A Value
    };


    // Axis direction
    //
    enum AxisDirType
    {
        kPositiveX = 1,
        kNegativeX = 2,
        kPositiveY = 3,
        kNegativeY = 4,
        kXAxisPos       = kPositiveX,
        kYAxisNeg       = kNegativeY,
        kXAxisNeg       = kNegativeX,
        kYAxisPos       = kPositiveY
    };

    // Enumeration of geometry reference orientation.
    //
    enum NormalOrientnType
    {
      kRaw,
      kReversed
    };
};

// Convenience typedefs for namespace scoped enums.
//
typedef Ami::FlatStatus            AmiFlatStatus;
typedef Ami::KeyType               AmiKeyType;
typedef Ami::DesignEnvironmentType AmiDesignEnvironmentType;
typedef Ami::DesignModeType        AmiDesignModeType;
typedef Ami::DwgType               AmiDwgType;
typedef Ami::AttributeDataType     AmiAttributeDataType;
typedef Ami::AxisDirType           AmiAxisDirType;
typedef Ami::NormalOrientnType     AmiNormalOrientnType;



// MCAD API State identifier
//
// AmiObjectState is used with amiGetObjectState() to report basic state
// information for various types of objects.  The values of AmiObjectState
// are defined in terms of macros, with the macros for a given object
// type defined in the header-file where the corresponding MCADAPI key is
// defined.  These macros are all prefixed with "AMI_STATE_".
//
typedef Adesk::UInt32 AmiObjectState;

#define AMI_STATE_USERCREATED   0x01



// MCAD API Key Error Return
//
#define AMI_INVALID_KEY ((unsigned) -1)



// MCAD API pick object.
//
class AMIAPI AmiPickObj
{
  public:

    AmiPickObj() : mpData(NULL) {}
   ~AmiPickObj();

    void* mpData;
};

// Disable the warning that an exported class is derived from a non-
// exported class (AcRxObject)
//
#pragma warning( disable : 4251 4275 )

// Base mcadapi object class.
//
class AMIAPI AmiObjectBase : public AcRxObject
{
  public:

    MCADAPI_DECLARE_MEMBERS(AmiObjectBase);

    // Functions increment/decrement/return the object reference count.
    // When a reference count decrement causes the count to hit zero,
    // the object deletes itself.
    //
    virtual unsigned addRef ();
    virtual unsigned release();
    virtual unsigned refCnt () const;

	virtual Acad::ErrorStatus copyFrom(const AcRxObject* other);

  protected:

    // Protected constructor dis-allows direct construction.
    //
    AmiObjectBase() : mcRef   (1),
                      mOwnerId(UNSET_APP_ID),
                      mpData  (NULL),
                      mpDoc   (NULL)
                      {}

  // The data members are public, but external applications
  // should not access them directly and should NOT modify them.
  //
  public:

    unsigned mcRef;          // Object reference count.
    AmiAppId mOwnerId;       // Object owner identification.
    void*    mpData;         // Pointer to object implementation.
    void*    mpDoc;          // Doc pointer (transient, not written to DWG).
};

// Base object key class.
//
class AMIAPI AmiObjectKey : public AmiObjectBase
{
  public:

    MCADAPI_DECLARE_MEMBERS(AmiObjectKey);

    // Functions increment/decrement/return the key reference count.
    // When a reference count decrement causes the count to hit zero,
    // the erases and deletes itself.
    //
    virtual unsigned addRef ();
    virtual unsigned release();
    virtual unsigned refCnt () const;

    // Functions increment/decrement/return the key persistent
    // reference count.
    //
    virtual unsigned addPersistentRef(AcDbObject* pRefferingObj);
    virtual unsigned persistentRefCnt() const;
    virtual unsigned erase(bool fErasing = true);

    AcDbObjectId mPersKey;

  protected:

    // Protected constructor dis-allows direct creation.
    //
    AmiObjectKey() {}

    friend class AmiDocInfo;
};

// Base descriptor class definition.
//
// The descriptor holds a void-ptr to internal implementation of
// descriptor classes.
//
// Objects of this class are NOT persistent.
//
class AMIAPI AmiDescrip : public AmiObjectBase
{
  public:

    MCADAPI_DECLARE_MEMBERS(AmiDescrip);

    // Release method for descriptors decrements the reference count
    // and, in the event that the count hits zero, calls the owning
    // app's function to clean up the descriptor.
    //
    virtual unsigned release();
};

// Macro to set the editor state to the structure entity edit mode.
// Macro should be added to the beginning of outer-most user functions that 
// call structure API, prior to structure entity modifications.
// When the structure entity edit mode is turned on, structure entity modifications 
// using API are tracked for update to the Mechanical Structure.
// Macro turns off the structure entity edit mode at the end of the outer-most user
// functions. 
#define SET_STRUCTURE_MODE_EDIT_ENTITY                                    \
  AmiStructApiAccess oStructApiAcc;                                       \
  oStructApiAcc.setStructApiMode(true);                                   \
  if (!oStructApiAcc.isInStructApiMode())                                 \
  {                                                                       \
    AmiStatus status(Ami::kSetStructModeEditEntityError, Ami::kError);    \
    acutPrintf(ACRX_T(/*MSG0*/"%s\n"), status.text().c_str());            \
  }

// Class sets the editor state to be in the Structure API mode.
class AMIAPI AmiStructApiAccess
{
public:
  AmiStructApiAccess();
  virtual ~AmiStructApiAccess();

public:
  // Sets the editor state to Structure API mode.
  void setStructApiMode(bool bMode);
  // Checks if the editor state is in Structure API mode.
  bool isInStructApiMode();

private:
  void setStructApiRef(bool bRef);
  bool isRefByStructApi();
  void openOuterTrans();
  void closeOuterTrans();

  void validateDoc();
  void clear();

private:
  AcMeDoc* mpDoc;
  bool mbSetStructApiRef;
  bool mbSetStructApiMode;
  bool mbClosedOuterTrans;
};

// Define array types for the base classes.
//
typedef AmiArray<AmiObjectBase> AmiObjectBaseArray;
typedef AmiArray<AmiObjectKey>  AmiObjectKeyArray;
typedef AmiArray<AmiDescrip>    AmiDescripArray;

#define AMI_NULLOBJKEYREF *((AmiObjectKey**) NULL)

// Type of function pointer used in storing/retrieving all function pointers.
//
typedef void (*AmiNullFuncPtr) ();

// Type of function pointers used in support of active notification.
//
typedef void (*AmiNotifFcnPtr ) (AmiObjectKey* pObjectKey);
typedef void (*AmiNotifFcnPtr2) (AmiObjectKey* pObjectKey, AcDbObjectId id);

// Description: Returns the database which is actively being editted.  This
//              will change as the document changes and as external databases
//              are editted locally (xref edit).
AMIAPI AmiStatus amiGetCurrentDatabase( AcDbDatabase*& pDb );

// Description: Returns the information from the specified pick object.
// Input      : pPickObj   - Pick object to retrieve information from.
// Output     : subentPath - Full sub entity path of pick.
//              pickPoint  - Pick point.
//              pickVector - Pick vector.
//              viewTrans  - View transformation matrix.
//              isGhost    - True if geometric resolution is possible even
//                           after the entity has dissappeared.
AMIAPI AmiStatus amiGetPickInfo( AmiPickObj* pPickObj, AcDbFullSubentPath& subentPath,
								 AcGePoint3d& pickPoint, AcGeVector3d& pickVector,
								 AcGeMatrix3d& viewTrans, Adesk::Boolean& isGhost );

// Description: Converts a subent path from graphical to logical or from
//              logical to graphical. In the pure MCADAPI, object keys
//              mainly refer to logical (or database) entities. Within MDT,
//              many of these database entities of graphical (displayable)
//              counterparts. When using objectDBX to perform picking, the
//              subent path's usually refer to the graphical entities. This
//              utility function can be used to convert those subent paths
//              to refer to logical entities or, if a subent path already
//              refers to the logical entity, this function can convert it
//              to refer to the graphical entities.
//
//              NOTE: If a subent already refers to the entity that the
//                    function is asked to convert to, the subent will come
//                    back unchanged.
// Input      : subentPath - The subent path to convert.
//              toLogical  - If true, converts the subent path to refer to
//                           the logical entity. If false, converts the path
//                           to refer to the graphical entity.
// Output     : subentPath - Input subent path is returned converted.
AMIAPI AmiStatus amiConvertPath( AcDbFullSubentPath& subentPath,
								 Adesk::Boolean toLogical = Adesk::kTrue );

// Description: Checks whether the given object keys has been initialized.
// Input      : pObjKey - A pointer to an object key.
// Output     : nullKey - A value of true if the key is null;
//                        otherwise, it is false.
AMIAPI AmiStatus amiIsKeyNull( AmiObjectKey* pObjKey, Adesk::Boolean& nullKey );

// Description: Returns the type of the specified key.
// Input      : pObjKey - A pointer to a key.
// Output     : type    - The type of the key.
AMIAPI AmiStatus amiGetKeyType( AmiObjectKey* pObjKey, AmiKeyType& type );

// Description: Checks if the type of the key is derived from or the same as
//              type.
// Input      : pObjKey - The pointer to a key type.
//              type    - The type to check against.
// Output     : isType  - A value of true if the key is of the same type as type or
//                        if the key type is derived from type; otherwise, isType
//                        is false.
AMIAPI AmiStatus amiIsKeyKindOf( AmiObjectKey* pObjKey, AmiKeyType type,
								 Adesk::Boolean& isType );

// Description: Reads a key from a given filer. This function is usually called
//              from the dwgin method of the application object that owns the
//              key.  It is the callers responsibility to release the key.
// Input      : filer      - A pointer to the filer.
//              pFilingObj - The filing database object.
// Output     : pObjKey    - The pointer to the key.
AMIAPI AmiStatus amiReadKey( AcDbDwgFiler* filer, AcDbObject* pFilingObj,
							 AmiObjectKey*& pObjKey );

// Description: Writes the key to the given filer. This function is usually
//              called from the dwgout method of the application object that
//              owns the key.
// Input      : filer      - A pointer to the filer.
//              pFilingObj - The filing database object.
//              pObjKey    - The pointer to the key.
AMIAPI AmiStatus amiWriteKey( AcDbDwgFiler* filer, AcDbObject* pFilingObj,
							  AmiObjectKey* pObjKey );

// Description: Creates a geometric key from the given object id.  If an
//              error occurs a bad status is returned and pGeomKey is set to
//              NULL.  It is the caller's responsibility to release the key.
//
// Input    : id - The object id from which the geom key is created.
//            type - indicates what kind of key to create.
//            inferFlag - indicates whether or not to infer a key.
//            pSubId - An optional subentity from which to create the key.
//            pPoint - An optional point to clarify how the key should be
//                     created.
// Output   : pObjectKey - a pointer to the key.
AMIAPI AmiStatus amiGetKeyFromId( AcDbObjectId id,
								  AmiKeyType type, AmiObjectKey*& pObjectKey,
								  Adesk::Boolean inferFlag = Adesk::kTrue,
								  AcDbSubentId* pSubId = NULL,
								  AcGePoint3d* pPoint = NULL );

// Description: Creates an object key from the given subentity path.
//              The key will refer to the subentity identified by the subentPath,
//              if any.  If no subentity is identified, the key will refer to
//              the entity itself.  If the entity's id is not contained in the
//              AcDbFullSubentPath, an error is returned.  If an error occurs
//              a bad status is returned and pObjectKey is set to NULL.  It is
//              the caller's responsibility to release the key.
//
// Input    : subentPath - The subentPath from which the object key is created.
//            type       - Indicates what kind of key to create.
//            inferFlag  - Indicates whether or not to infer a key.
//            pPoint     - An optional point to clarify how the key should be
//                         created.
// Output   : pObjectKey - a pointer to the key.
AMIAPI AmiStatus amiGetKeyFromPath( const AcDbFullSubentPath& subentPath,
								    AmiKeyType type, AmiObjectKey*& pObjectKey,
								    Adesk::Boolean inferFlag = Adesk::kTrue,
								    AcGePoint3d* pPoint = NULL );

// Description: Creates a new key from pObjKey which refers to the equivalent
//              object to that referred to by pObjKey at the scope implied by
//              pRefKey. For example, if one has a line key to the boundary of a
//              part, it is possible, using this function, to obtain a key to the
//              same line in the scope of an instance of that part in an assembly
//              and vice-versa. If there is no equivalent entity in the scope
//              of pRefKey, amiRefocusKey returns eUnmatchedLeafObject.
// Input      : pObjKey   - Pointer to key to be refocused. Only geom Keys and
//                          feature keys are supported.
//            : pRefKey   - Pointer to key to object that specifies desired
//                          focus (currently only leaf component, part, geometry
//                           and feature keys supported).
// Output     : pNewObjKey- Key created which references the equivalent
//                          object as pObjKey in the scope of pRefKey.
AMIAPI AmiStatus amiRefocusKey( AmiObjectKey *pObjKey, AmiObjectKey *pRefKey,
							    AmiObjectKey *&pNewObjKey = AMI_NULLOBJKEYREF );

// Description: Copies the given key and returns another key that resolves to the
//              same application object as the original key.   It is the caller’s
//              responsibility to release the key.
// Input      : pObjKey - A pointer to original key.
//            : pTargetDatabase - The database into which the key is copied
// Output     : pCopy   - A pointer to copy of the key.
AMIAPI AmiStatus amiCopyKey( AmiObjectKey* pObjKey, AmiObjectKey*& pCopy,
							 AcDbDatabase* pTargetDatabase = NULL );

// Description: Fills data fields of pick object, given a result buffer in the
//              format returned by ads_ssnamex() and the type of key to be created
//              usingpickObj. Note that, when set to Adesk::kTrue, the allowGhost
//              flag is effective only for AutoCAD Designer edges or vertices.
// Input      : pickResBuf - A resbuf that contains pick information as
//                           formatted and returned by ads_ssnamex().
//              type       - The type of the key that the caller creates. An
//                           abstract type can be used.  Not all concrete
//                           types are supported (e.g. compKey, dwvwKey,
//                           dwLayoutKey, and sceneKey are not supported).
//              allowGhost - A value of true when the caller wants resolution
//                           even if entity has disappeared, for example,
//                           resolution to an edge that has been chamfered.
// Output     : pickObj    - An object with all of its data fields filled that
//                           represents the object picked by the user.  This
//                           object selected by the user.
AMIAPI AmiStatus amiFillPickObj( struct resbuf* pickResBuf,
								AmiKeyType type, AmiPickObj& pickObj,
								Adesk::Boolean allowGhost = Adesk::kFalse );

// Description: Get an object key based on an object name.
//
//              Given an object name, this function attempts to create a
//              key of the given key type. The scope key is used to determine
//              the starting point where to look for the object. For example,
//              given a key type of "Ami::featKey" and a part key as the scope,
//              the function will look for a feature within that part with the
//              given name and create a feature key to that feature. If the
//              scope key is NULL, it is assumed that we're looking for an
//              object in the global scope such as a part or component
//              definition.
//
//              Currently, this function is only implemented to create
//              feature, parameter, or sketch keys. The feature and sketch
//              key creation requires a part key as the scope key. The
//              parameter key creation will work with a part key or a NULL
//              key (global parameter).
//
// Input      : name      - Name of object to get key for.
//              keyType   - Type of key that is to be created.
//              pScopeKey - Key to scope object.
//              appName   - Application to create key.
// Output     : pKey      - Pointer to created key.
AMIAPI AmiStatus amiGetKeyFromName( const ACHAR* name,
								    AmiKeyType keyType, AmiObjectKey*& pKey,
								    AmiObjectKey* pScopeKey = NULL, const ACHAR* appName = NULL);

// Description: Tag the internal state of the specified MDT object to indicate
//              that the object is not up-to-date and requires regeneration.
// Input      : pKey - Pointer to an object key.
// Output     : none
AMIAPI AmiStatus amiSetNeedsRegen( AmiObjectKey* pKey );


AMIAPI AmiStatus amiRegenAllOfAType(Ami::KeyType objType, Adesk::Boolean fForce = Adesk::kFalse);

// Description: This function get the Document associated with the key.
//              Every key is associated with at most one document.
// Input    : pAmiBase - pointer to an MCADAPI object (e.g. a key).
// Output   : pDoc - pointer to document associated with input argument.
//
// NOTE: If no document is associated with the given object, then the
//       output pointer is set to NULL but the returned status is not
//       an error status.
//
AMIAPI AmiStatus amiGetAssociatedDoc( AmiObjectBase* pAmiObject,
                   AcApDocument*& pDoc );

extern AmiStatus AMIAPI amiGetAssociatedDbs( AmiObjectKey* pObjKey,
                                             INT_PTR &numDatabases,
                                             AcDbDatabase**& pDbs );

// Description: Creates an object key from a pick object and returns the type
//              of key created. If an error occurs a bad status is returned
//              and pObjKey is set to NULL. It is the caller’s responsibility
//              to release the key.
// Input      : pPickObj - The pointer to the pick object.
// Output     : type     - The type of the key that was created.
//              pObjKey  - The pointer to the key.
AMIAPI AmiStatus amiGetKeyFromPick( AmiPickObj* pPickObj,
                   AmiKeyType& type, AmiObjectKey*& pObjKey );

// Description: Compares two keys to determine if they refer to the same entity.
//              The pKey1 parameter points to the first object key.  The pKey2
//              parameter points to second object key.  When the function
//              returns, the areEquivalent parameter is true if the keys resolve
//              to the same entity; otherwise, it is false.  The considerComp
//              parameter allows you to determine not only whether the geometry
//              or features of two keys are equivalent, but also whether they are
//              located on the same component.  The two keys must resolve to the
//              same lowest-level component to be equal.  The differsInCompOnly
//              parameter allows you to determine whether the difference between
//              keys is caused solely by location on different components.
//              Note also that considerComp is applicable only to component keys,
//              geometry keys and feature keys.  It is ignored (differsInCompOnly
//              returns false) for part, constraint, parameter, sketch, solid and
//              component definition keys.
// Input      : pKey1 - pointer to first object key.
//              pKey2 - pointer to second object key.
//              considerComp      - If true, the equivalence test considers the
//                                  component as a criterion for determining if
//                                  the keys are equivalent. If false, the
//                                  component is not considered.  In other words,
//                                  if true,two keys must not only refer to the
//                                  same geometry or feature to be equivalent,
//                                  but they must also be on the same component.
//                                  If false, two keys referring to the same
//                                  geometry or feature will return true
//                                  regardless of the component.
// Output     : areEquivalent - A value of true if the keys resolve to the
//                              same entity; otherwise, it is false.
//              differsByCompOnly - If a pointer to a boolean is specified
//                                  here, the result will tell whether
//                                  the keys are not equivalent only
//                                  because they are located on different
//                                  components. This is independant of the
//                                  considerComp argument and is ignored if
//                                  a NULL pointer is specified.
AMIAPI AmiStatus amiAreKeysEquivalent( AmiObjectKey* pKey1,
							   AmiObjectKey* pKey2, Adesk::Boolean& areEquivalent,
							   Adesk::Boolean considerComp = Adesk::kTrue,
							   Adesk::Boolean* differInCompOnly = NULL);

// Description: Checks if the object referenced by pObjKey has been erased.
//              Currently supported for all keys.
// Input      : pKey - A pointer to the object key.
// Output     : erased - A value of true if the application object was erased;
//                        otherwise, it is false.
AMIAPI AmiStatus amiObjectWasErased( AmiObjectKey* pKey, Adesk::Boolean& erased );

// New signature which takes a default keyword argument
// Description: Prompts user to perform a single pick and fills the pick
//              object data fields. The pick object (pickObj) can be used in
//              creating a key to the object picked by the user. Note that, when
//              set to Adesk::kTrue, the allowGhost flag is effective only for
//              AutoCAD Designer edges or vertices.
// Input      : prompt     - The prompt displayed to the user.
//              type       - The type of key that the caller intends to create.
//                           An abstract type can be used.
//              entmask    - The kind of result-buffer list that ads_ssget() uses
//                           to filter a drawing to select particular entities.
//              allowGhost - A value of true when the caller wants resolution
//                           even if the entity has disappeared, for example,
//                           resolution to an edge that has been chamfered.
//              activeInstance - A value of true restricts the picking to the currently
//                           active part instance (if valid for the specified key type).
//              keyWords   - A list of keywords seperated by spaces.
//              defaultKeyWord - specify a default, use NULL for NO default keyword
//              includeInList - true indicates that the default keyword is added to the main list
//                              e.g. [Aaa/Bbb/Ccc/Ddd]<Ddd>
//                            - false indicates that the default keyword is not added to the list
//                              e.g. [Aaa/Bbb/Ccc]<Ddd>
// Output     : pickObj    - An object with all of its data fields filled that
//                           represents the object picked by the user.  This
//                           construct can then be used to create a key to the
//                           object picked by the user.
//              keyWordUsed - The keyword that the user accepted.  This argument
//                           is only filled when the return status is kKeyWord.
//                           The user is responsible for releasing the memory
//                           used by keyWordUsed.
AMIAPI AmiStatus amiPick(const ACHAR* prompt, Ami::KeyType type,
                   struct resbuf* entmask, AmiPickObj& pickObj,
                   Adesk::Boolean allowGhost,
				   Adesk::Boolean activeInstance,
				   const ACHAR* keyWords, const ACHAR* defaultKeyWord,
                   Adesk::Boolean includeInList,
                   ACHAR** keyWordUsed);

// Still exists to maintain Binary compatibility
AMIAPI AmiStatus amiPick (  const ACHAR* prompt, Ami::KeyType type,
                            struct resbuf* entmask, AmiPickObj& pickObj,
                            Adesk::Boolean allowGhost = Adesk::kFalse,
				                    Adesk::Boolean activeInstance = Adesk::kFalse,
				                    const ACHAR* keyWords = NULL, ACHAR** keyWordUsed = NULL) ;

// Description: Highlights or turns off highlighting of the entity referred to by
//              pObjKey.
// Input      : pObjKey     - Pointer to key.
//              highlight   - A value of true to highlight the entity referred
//                            to by pObjKey or false to turn off highlighting
//                            for the entity.
//              scaleFactor - A value applied to the default size of
//                            graphics used in highlighting unbounded or
//                            inferred entities.
AMIAPI AmiStatus amiHighlight( AmiObjectKey* pObjKey, Adesk::Boolean highlight, double scaleFactor = 1.0 );

// Description: Erases the object referenced by the key, if allowed.
// Input      : pObjKey - Pointer to the key.
AMIAPI AmiStatus amiEraseObject ( AmiObjectKey* pObjKey );

// Description: Returns an array of AcDbObjectId's corresponding to the given
//              object key. It is not guaranteed to work for all key types.
//              It is the caller’s responsibility to delete the array.
// Input      : pObjKey   - Pointer to key.
// Output     : numIds    - Number of DbId's in pIdsArray.
//              pIdsArray - Array of DbId's (to be deleted by caller)
AMIAPI AmiStatus amiGetDbIdsFromKey( AmiObjectKey* pObjKey,
                   int& numIds, AcDbObjectId*& pIdsArray );

// Description: Retrieves the name for the object specified by the
//              object key. The user is responsible for releasing the
//              memory used by objName.
// Input      : pObjKey - The pointer to the object key.
// Output     : objName - Name of object of the given key.
AMIAPI AmiStatus amiGetObjectName(AmiObjectKey* pObjKey, ACHAR*& objName);

// Description: Sets the name for the object specified by the object
//              key. An error is returned if the name is the same as
//              that of another object of the same type. This function is
//              currently implemented for feature keys only.
// Input      : pObjKey - The pointer to the object key.
//              objName - New name for the object.
AMIAPI AmiStatus amiSetObjectName(AmiObjectKey* pObjKey, const ACHAR* objName);

// Description: Checks if the object referred to by the specified key is
//              directly editable.
// Input      : pObjKey  - Pointer to object key.
// Output     : editable - true, object is directly editable.
//                         false, otherwise.
AMIAPI AmiStatus amiIsDirectlyEditable( AmiObjectKey* pObjKey,
                   Adesk::Boolean& editable );

// Description: Regenerates the specified MDT object.  If the object has been
//              marked for update, then this function will regen the object.
//              The force-flag can be used to force a regen.
//              This function does not necessarily update the display to
//              bring it in sync with the object (update of the displayed
//              graphics is often done at end-of-command following a regen).
//              Not all objects can be regenerated directly.  For example,
//              amiRegen() returns eNotApplicable for feature keys and
//              constraint keys.  Instead, the part or assembly should be
//              regenerated with respect to these objects.
//
// Input      : pKey - Pointer to an object key.
//              fForce - Force regen even if internal states indicates that
//                     regeneration is not necessary (i.e. object not marked
//                     for update).
// Output     : none
AMIAPI AmiStatus amiRegen( AmiObjectKey* pKey, Adesk::Boolean fForce = Adesk::kFalse );

// Description: Retrieves the state for the object specified by the
//              object key. Macros can be used to retrieve the specific
//              attributes packed into the state.
//
//              Not all types of keys are supported at this time.  Currently,
//              the following types of keys are supported: parts, features,
//              and parameters.
//              Features and parts are also supported by the older functions,
//              amiGetFeatState() and amiGetPartState().  Eventually, these
//              functions will be replaced with amiGetObjectState().
//
// Input      : pObjKey  - The pointer to the object key.
// Output     : objState - Bit packed representation of the object state
//                         The state attribute location is dependent on the type
//                         of key used.  These locations are defined by macros
//                         in the header files, where these macros are all
//                         prefixed with "AMI_STATE_".
AMIAPI AmiStatus amiGetObjectState(AmiObjectKey* pObjKey, AmiObjectState& objState);

// Description: Gets the visibility of the object referenced by the given key.
//              This function is not implemented for all types of keys.
//
//              NOTE: Currently, this function only works on:
//                          Components (AmiCompKey)
//                          Work features (AmiFeatKey, AmiGeomKey)
//
//              NOTE: For comp keys, the key must be for a "comp in def".
//                    In other words, visibility is a property of only those
//                    comps that are not contained within other comps.
//                    The function, amiGetCompInDef() can be used to convert
//                    a comp key to one that meets this criterion.
//
// Input      : pObjKey - Pointer to an object key.
// Output     : bVisibilityOn - kTrue if and only if the underlying object
//                    has not had visibility turned off.
AMIAPI AmiStatus amiGetObjectVisibility(AmiObjectKey* pObjKey,
                                 Adesk::Boolean& bVisibilityOn);

// Description: Sets the visibility of the object referenced by the given key.
//              This function is not implemented for all types of keys.
//
//              NOTE: Currently, this function only works on:
//                          Components (AmiCompKey)
//                          Work features (AmiFeatKey, AmiGeomKey)
//
//              NOTE: For comp keys, the key must be for a "comp in def".
//                    In other words, visibility is settable on only those
//                    comps that are not contained within other comps.
//                    The function, amiGetCompInDef() can be used to convert
//                    a comp key to one that meets this criterion.
//
// Input      : pObjKey - Pointer to an object key.
//              bVisibilityOn - the desired visibility setting for the object.
AMIAPI AmiStatus amiSetObjectVisibility(AmiObjectKey* pObjKey,
                  Adesk::Boolean bVisibilityOn);

// Description: Returns the type of drawing for the specific database.
AMIAPI AmiStatus amiGetDrawingType( AcDbDatabase * pDb, AmiDwgType &value );

// Description: Fills in graph with a completed graph of xrefs in the database pointed to by pHostDb.
//              This graph will not contain the temporary xref connections that ACM/MDT forms. Refer
//              to object arx documentation on acdbGetHostDwgXrefGraph for more information on the parameters.
AMIAPI Acad::ErrorStatus amiGetHostDwgXrefGraph( AcDbDatabase *  pHostDb,
												 AcDbXrefGraph & graph,
												 Adesk::Boolean  includeGhosts = Adesk::kFalse);

#endif  // AMIBASE_H
