//////////////////////////////////////////////////////////////////////////////
//
//  Copyright 2025 Autodesk, Inc.  All rights reserved.
//
//  Use of this software is subject to the terms of the Autodesk license 
//  agreement provided at the time of installation or download, or which 
//  otherwise accompanies this software in either electronic or hard copy form.   
//
//////////////////////////////////////////////////////////////////////////////

// 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

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

namespace AmdtAttr
{

enum FieldType { kAmiShort,
                 kAmiLong,
                 kAmiDouble,
                 kAmiChar,
                 kAmiShortArray,
                 kAmiLongArray,
                 kAmiDoubleArray,
                 kAmiCharArray,
				 kAmiObjectId,
				 kAmiObjectIdArray,
                 kAmiObjectKey,
                 kAmiObjectKeyArray};

}
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;
};

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

typedef AmdtAttr::FieldType    AmiFieldType;

#pragma warning( disable : 4275 )

///<summary>Abstract attribute class definition.</summary>
class MCADATTS_SDK AmiAttribute: public AcDbObject 
{ 
  public:
    
    ACRX_DECLARE_MEMBERS(AmiAttribute);

    ///<summary>Class constructor.</summary>
    AmiAttribute(Adesk::Boolean ownerIsMCADAPI = Adesk::kFalse);

    ///<summary>Gets the name of the application that created the attribute.</summary>
    ///<param name="appName">Application name.</param>
    virtual AmdtAttr::Status getOwningApp ( const ACHAR*& appName ) const=0;
    ///<summary>Gets the attribute name.</summary>
    ///<param name="attributeName">Attribute name.</param>
    virtual AmdtAttr::Status getName      ( const ACHAR*& attributeName ) const=0;
    ///<summary>Gets the number of fields in the attribute.</summary>
    ///<param name="numFields">Number of attribute fields.</param>
    virtual AmdtAttr::Status getNumFields ( int& numFields ) const=0;
    ///<summary>Gets the field name corresponding to the given index.</summary>
    ///<param name="index">Input only. Specifies the index for the desired field (starts at zero).</param>
    ///<param name="fieldName">Output only. Returns the field name.</param>
    virtual AmdtAttr::Status getFieldName ( int index, const ACHAR*& fieldName ) const=0;
    ///<summary>Gets a string that gives a description of the meaning of the specified field.</summary>
    ///<param name="index">Input only. Specifies the index for the desired field (starts at zero).</param>
    ///<param name="fieldDesc ">Output only. Returns the description of field meaning.</param>
    virtual AmdtAttr::Status getFieldDesc ( int index, const ACHAR*& fieldDesc ) const=0;
    ///<summary>Gets the data type contained in the specified field.</summary>
    ///<param name="index ">Input only. Specifies the index for the desired field (starts at zero).</param>
    ///<param name="type">Output only. Returns the type of the data contained in the field.</param>
    virtual AmdtAttr::Status getFieldType ( int index, AmdtAttr::FieldType& type ) const=0;
    ///<summary>Gets the data stored in the specified field by giving the caller a pointer to the data location.</summary>
    ///<param name="index">Input only. Specifies the index for the desired field (starts at zero). </param>
    ///<param name="pContent ">Output only. Returns the pointer to data location for the field.</param>
    virtual AmdtAttr::Status getFieldCont ( int index, const void*& pContent ) const=0;

    ///<summary>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.</summary>
    ///<param name="index">Input only. Specifies the index for the desired field (starts at zero).</param>
    ///<param name="pContent">Output only. Returns the pointer to data location for the data to be used in updating the field.</param>
    virtual AmdtAttr::Status setFieldCont ( int index, const void* pContent );

    virtual Acad::ErrorStatus dwgOutFields ( AcDbDwgFiler* filer ) const;
    virtual Acad::ErrorStatus dwgInFields  ( AcDbDwgFiler* filer );

  private:

    unsigned long  mReferenceCount;
    Adesk::Boolean mIsOwner;

    friend class AmiAttXProtocol;

  protected:

    void *operator new[](size_t nSize) { assert(0); return NULL; }
    void operator delete[](void *p) { assert(0); }
};

///<summary>This is class AmiInstAtt.</summary>
class MCADATTS_SDK AmiInstAtt : public AmiAttribute
{
  public:

    ACRX_DECLARE_MEMBERS(AmiInstAtt);

    AmiInstAtt();
};

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

AmdtAttr::Status getName ( const char*& attributeName ) const

AmdtAttr::Status getNumFields ( int& numFields ) const

AmdtAttr::Status getFieldName ( int index, const char*& fieldName ) const

AmdtAttr::Status getFieldDesc ( int index, const char*& fieldDesc ) const

AmdtAttr::Status getFieldType ( int index, AmdtAttr::FieldType& type ) const

AmdtAttr::Status getFieldCont ( int index, const void*& pContent ) const

AmdtAttr::Status setFieldCont ( int index, const void* pContent ) const

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

#endif  // AMI_ATTRIBUTE_H
