//
// Definition file for abstract class AmiAttribute.
//
// The information contained herein is confidential, proprietary
// to Autodesk, Inc., and considered a trade secret as defined
// in section 499C of the penal code of the State of California.
// Use of this information by anyone other than authorized
// employees of Autodesk, Inc. is granted only under a written
// non-disclosure agreement, expressly prescribing the scope
// and manner of such use.
//
// DESCRIPTION: This file contains the description for the abstract class 
//              AmiAttribute, the base class for all attributes used in
//              conjunction with the MCAD API.  In addition, the
//              instantiable attribute class AmiInstAtt is defined.
// 
#ifndef AMD_ATTRIBUTE_H
#define AMD_ATTRIBUTE_H

// Includes
//
#include <tchar.h>
#include "dbmain.h"      // AcDbObject
#include "attr.h"        // Attr name space and Status
#include "AdAChar.h"

namespace AmdtAttr
{

// Field data type enumeration.
//
// IMPORTANT: Any items add to this enumeration MUST BE APPENDED as
//            the values are used for attribute I/O.
//
enum FieldType { kAmiShort,
                 kAmiLong,
                 kAmiDouble,
                 kAmiChar,
                 kAmiShortArray,
                 kAmiLongArray,
                 kAmiDoubleArray,
                 kAmiCharArray,
				 kAmiObjectId,
				 kAmiObjectIdArray,
                 kAmiObjectKey,
                 kAmiObjectKeyArray};

}
// Attribute field descriptor structure.
//        
struct AmiAttFieldDesc
{
    AmiAttFieldDesc () : mFieldName (NULL),
                         mFieldDesc (NULL),
                         mFieldType (AmdtAttr::kAmiShort),
                         mStaticFlag(Adesk::kFalse) {}

    const ACHAR*       mFieldName;
    const ACHAR*       mFieldDesc;
    AmdtAttr::FieldType   mFieldType;
    Adesk::Boolean    mStaticFlag;
};

// Array field content structure.
//
struct AmiArrayFieldContent
{
    int   mSize;  //64BIT: The structure should remain as fixed, and no change is allowed.
    void *mPtr;
};

// mcadapi compatibility/convenience.
//
typedef AmdtAttr::FieldType    AmiFieldType;

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

// Abstract attribute class definition.
//
class MCADATTS_SDK AmiAttribute: public AcDbObject 
{ 
  public:

    ACRX_DECLARE_MEMBERS(AmiAttribute);

    // Constructor/Destructor.
    //
    AmiAttribute(Adesk::Boolean ownerIsMCADAPI = Adesk::kFalse);

    // Query methods:
    //
    virtual AmdtAttr::Status getOwningApp ( const ACHAR*& appName ) const=0;
    virtual AmdtAttr::Status getName      ( const ACHAR*& attributeName ) const=0;
    virtual AmdtAttr::Status getNumFields ( int& numFields ) const=0;
    virtual AmdtAttr::Status getFieldName ( int index, const ACHAR*& fieldName ) const=0;
    virtual AmdtAttr::Status getFieldDesc ( int index, const ACHAR*& fieldDesc ) const=0;
    virtual AmdtAttr::Status getFieldType ( int index, AmdtAttr::FieldType& type ) const=0;
    virtual AmdtAttr::Status getFieldCont ( int index, const void*& pContent ) const=0;

    // Set method:
    //
    virtual AmdtAttr::Status setFieldCont ( int index, const void* pContent );

    // Persistency methods.
    //
    virtual Acad::ErrorStatus dwgOutFields ( AcDbDwgFiler* filer ) const;
    virtual Acad::ErrorStatus dwgInFields  ( AcDbDwgFiler* filer );

  private:

    // Following are transient members.
    //
    unsigned long  mReferenceCount;
    Adesk::Boolean mIsOwner;

    friend class AmiAttXProtocol;

  protected:

    // We are making this constructor and destructor private to try and
    // ensure that they are not used.  The Tahoe team has discovered a 
    // bug with the destructor so has made it private in AcDbObject.
    // This doesn't allow us to compile unless we declare it on our classes
    // that are exported.  No implementation is supplied so that link
    // errors are encountered if either of these are used.
    // See Tahoe subdoc t39dca1.txt for more details.
    //
    void *operator new[](size_t nSize) { assert(0); return NULL; }
    void operator delete[](void *p) { assert(0); }
};

// Instantiable attribute class definition.
//
class MCADATTS_SDK AmiInstAtt : public AmiAttribute
{
  public:

    ACRX_DECLARE_MEMBERS(AmiInstAtt);

    // Constructor/Destructor.
    //
    AmiInstAtt();
};

// Inline methods:
//
inline AmiAttribute::AmiAttribute(Adesk::Boolean ownerIsMCADAPI)
: mIsOwner(ownerIsMCADAPI), mReferenceCount(0) 
{}

inline Acad::ErrorStatus AmiAttribute::dwgOutFields ( AcDbDwgFiler* filer ) const
{ return  AcDbObject::dwgOutFields( filer ); }

inline AmdtAttr::Status AmiAttribute::setFieldCont ( int, const void* )
{ return AmdtAttr::eObjectNotEditable; }

inline AmiInstAtt::AmiInstAtt()
: AmiAttribute(Adesk::kTrue)
{}


/*******************************************************************************
Attribute method descriptions:

virtual AmdtAttr::Status getOwningApp ( const char*& appName ) const
//
// Description: Gets the name of the application that created the attribute.
// Output     : appName - Application name.

AmdtAttr::Status getName ( const char*& attributeName ) const
//
// Description: Gets the attribute name.
// Output     : attributeName - Attribute name.

AmdtAttr::Status getNumFields ( int& numFields ) const
//
// Description: Gets the number of fields in the attribute.
// Output     : numFields - Number of attribute fields.

AmdtAttr::Status getFieldName ( int index, const char*& fieldName ) const
//
// Description: Gets the field name corresponding to the given index.
// Input      : index     - Index for the desired field (starts at zero).
// Output     : fieldName - Field name.

AmdtAttr::Status getFieldDesc ( int index, const char*& fieldDesc ) const
//
// Description: Gets a string that gives a description of the meaning of the
//              specified field.
// Input      : index     - Index for the desired field (starts at zero).
// Output     : fieldDesc - Description of field meaning.

AmdtAttr::Status getFieldType ( int index, AmdtAttr::FieldType& type ) const
//
// Description: Gets the data type contained in the specified field.
// Input      : index - Index for the desired field (starts at zero).
// Output     : type  - Type of the data contained in the field.

AmdtAttr::Status getFieldCont ( int index, const void*& pContent ) const
//
// Description: Gets the data stored in the specified field by giving the caller
//              a pointer to the data location.
// Input      : index    - Index for the desired field (starts at zero).
// Output     : pContent - Pointer to data location for the field.

AmdtAttr::Status setFieldCont ( int index, const void* pContent ) const
//
// Description: Sets the data stored in the specified field by giving the caller
//              a pointer to the data location from where to copy the new data.
// Input      : index    - Index for the desired field (starts at zero).
// Output     : pContent - Pointer to data location for the data to be used
//                         in updating the field.

*******************************************************************************/

#endif  // AMI_ATTRIBUTE_H
