//////////////////////////////////////////////////////////////////////////////
//
//  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.   
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __PARTREF_H
#define __PARTREF_H

class AcmPartRefImp;

///<summary>This existing class is the class for a part reference object.</summary>
class ACMSYMBB_CRX_DLLSHARE AcmPartRef : public AcmSymbol
{
public:
    ACRX_DECLARE_MEMBERS(AcmPartRef);
    AcmPartRef();           
    AcmPartRef(const AcDbObjectId& dataId);             
    AcmPartRef(const AcGePoint3d& origin);  
    ///<summary>The class destructor.</summary>
    virtual ~AcmPartRef();             

    virtual Acm::ErrorStatus setSymbolDefaults(AcDbDatabase* pDb = NULL);
    AcDbObjectId dataEntryId() const;    

    void setDataEntryId(const AcDbObjectId& id);  
    Adesk::UInt32 numItem() const;

    Acad::ErrorStatus setNumItem(Adesk::UInt32 num);

    ///<summary>For internal use only.</summary>
    AcDbObjectId getAttachEntity() const;

    ///<summary>This returns the id of the attached external bom for this part reference if any.</summary>
    AcDbObjectId attachedExternalBom() const;     
 
    ///<summary>This sets the attached external bom of this part reference. 
    ///Prior to this, the xref drawing to which the bom belongs to, should have already been attached as an xref.</summary>
    ///<param name="id">Specifies the external bom id to attach</param>
    Acad::ErrorStatus setAttachedExternalBom(const AcDbObjectId& id);

    ///<summary>This sets the attached external bom of this part reference.</summary>
    ///<param name="xrefPath">Specifies the full path of the xref drawing to attach.</param>
    ///<param name="bomName">Specifies the name of the bom in the xref drawing to attach.</param>
    Acad::ErrorStatus setAttachedExternalBom(const ACHAR *xrefPath, const ACHAR *bomName); 

    ///<summary>This returns the id of the acad block of the attached external bom for this part reference if any. 
    ///The path of the xref can be obtained by checking pathName of the acad block.</summary>
    AcDbObjectId attachedExternalBomXrefBlock() const;

    ///<summary>This function detaches the external bom that has been attached to this part reference.</summary>
    ///<param name="detachXref">Defaults to true. Indicates if the xref drawing itself should be detached.</param>
    Acad::ErrorStatus detachExternalBom(bool detachXref = true);

    virtual void setOrigin(const AcGePoint3d &origin);

    Adesk::Boolean clonePartRef(AcDbObjectId& newPartRefId);

    Acad::ErrorStatus convertDataEntryData(AcDbObjectId& dataEntryBlkId, AcDbObjectId& refObjId) const;

    virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler* filer);             
    virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* filer) const;             
    virtual Acad::ErrorStatus dxfInFields(AcDbDxfFiler* filer);             
    virtual Acad::ErrorStatus dxfOutFields(AcDbDxfFiler* filer) const;    
    virtual Acad::ErrorStatus subClose();

    ///<summary>This checks if there is a bom override for the specified attribute/column of this partref and if so, returns the override properties.</summary>
    ///<param name="attribute">Input Only. Name of attribute/column to check.</param>
    ///<param name="originalValue">The original evaluated value (what would be there if there is no override). 
	  ///Would be empty if there is no bom override.</param>
    ///<param name="originalData">The original unevaluated data (what would be there if there is no override). 
	  ///Would be empty if there is no bom override.</param>
    ///<param name="value">The current evaluated value.</param>
    ///<param name="data">The current unevaluated data.</param>
    ///<param name="overrideType">The type of bom override if any. Would be set to sbNoOverride if there is no bom override.</param>
    ///<param name="editable">Indicates if the attribute can be edited.</param>
    Acad::ErrorStatus getBomOverride(
      const ACHAR *attribute,
      ACHAR *& originalValue,
      ACHAR *& originalData,
      ACHAR *& value,
      ACHAR *& data,
      Acm::BomOverrideType &overrideType,
      bool &editable
    ) const;

    ///<summary>This removes the specified local attribute if any from this partref.</summary>
    ///<param name="attribute">Input Only. Name of attribute/column to remove.</param>
    Acad::ErrorStatus removeAttribute(const ACHAR *attribute);

protected:
  virtual Adesk::Boolean    subWorldDraw(AcGiWorldDraw*mode); 

  ///<summary>Queries all leaders for their grip points.</summary>
  virtual Acad::ErrorStatus subGetGripPoints( AcGePoint3dArray&  gripPoints,AcDbIntArray&  osnapModes,AcDbIntArray&  geomIds) const; 
  ///<summary>Queries all leaders for their grip points.</summary>
  virtual Acad::ErrorStatus	subGetGripPoints(AcDbGripDataPtrArray& grips,
											 const double curViewUnitSize,
											 const int gripSize,
											 const AcGeVector3d& curViewDir,
											 const int bitflags) const;

  ///<summary>Determines which sub-symbols or leaders belong to the GS marker. 
  ///Then, it asks for sub-entities and applies getOsnapPoints to them.</summary>
  virtual Acad::ErrorStatus subGetOsnapPoints( AcDb::OsnapMode osnapMode,
											   INT_PTR gsSelectionMark,
											   const AcGePoint3d&  pickPoint,
											   const AcGePoint3d&  lastPoint,
											   const AcGeMatrix3d& viewXform,
											   AcGePoint3dArray&   snapPoints,
											   AcDbIntArray&   geomIds) const; 

  ///<summary>Determines the leaders to which indices belong and apply moveGripPointsAt to them. 
  ///If the tip point is being edited, then the leaderTipPointChanged() member function of the symbol will be called. 
  ///If the leader contains a landing and it is changed, then the leaderLanding() member function of the symbol is called.</summary>
  virtual Acad::ErrorStatus subMoveGripPointsAt(const AcDbIntArray& indices,const AcGeVector3d& offset); 

  ///<summary>Queries the standard for sub-entities for all leaders and then the server for all sub-entities for all sub-symbols. 
  ///All sub-entities are then exploded.</summary>
  virtual Acad::ErrorStatus subExplode(AcDbVoidPtrArray& entitySet) const;  

  ///<summary>Sums geometry extents for a leader.</summary>
  virtual Acad::ErrorStatus subGetGeomExtents(AcDbExtents& extents) const;    
  ///<summary>Lists all leaders including their vertices, standard name and original name, server name and version.</summary>
  virtual void              subList() const;      
  virtual Acad::ErrorStatus	subGetClassID(CLSID* pClsid) const;

private:
  AcmPartRefImp *mpImp;
};                      

DBREF_DECLARE(AcmPartRef)

#endif












