//////////////////////////////////////////////////////////////////////////////
//
//  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 __ACMPARTLISTOBJECT_H
#define __ACMPARTLISTOBJECT_H

class AmdtItemFilter;
class AcmCPartListImp;
class AcmBom;

///<summary>A part list symbol.</summary>
class ACMSYMBB_CRX_DLLSHARE AcmPartList : public AcmSymbol
{
public:
  ACRX_DECLARE_MEMBERS(AcmPartList);
  ///<summary>Constructs the parts list class.</summary>
  ///<param name="items">view :</param>
  AcmPartList(bool bCreateImpl = true);
  ///<summary>Constructs the parts list class.</summary>
  ///<param name="items">view :</param>
  AcmPartList(Adesk::Int32 minItem,Adesk::Int32 maxItem);
  ///<summary>Constructs the parts list class.</summary>
  ///<param name="items">view :</param>
  AcmPartList(AcDbObjectIdArray items);
  ///<summary>Constructs the parts list class.</summary>
  ///<param name="items">view :</param>
  AcmPartList(AcDbObjectId view);
  ///<summary>Destructs the parts list class.</summary>
  virtual ~AcmPartList();
  ///<summary>Sets the properties of the symbol to the factory default values.</summary>
  virtual Acm::ErrorStatus setSymbolDefaults(AcDbDatabase* pDb = NULL);
  ///<summary>Gets the associated BOM Id.</summary>
  virtual AcDbObjectId bomId() const;
  ///<summary>Sets the associated BOM Id.</summary>
  virtual void setBomId(const AcDbObjectId& bomId);
  AcmBom* tempBomObj() const;

  void setTempBomObj(AcmBom* pBom) const;
  ///<summary>Returns the visibility of the grip frame.</summary>
  bool isGripFrameEnabled() const;
  ///<summary>Sets the visibility of the grip frame.</summary>
  void setIsGripFrameEnabled(bool isUse);

  ///<summary>Returns the visibility of the result bar for the current parts list.</summary>
  bool isResultBarEnabled() const;
  ///<summary>Sets the visibility of the result bar for the current parts list.</summary>
  void setIsResultBarEnabled(bool isUse);
  ///<summary>Returns the visibility of the formula bar for the parts list. This is persistent data.</summary>
  bool isFormulaBarEnabled() const;
  ///<summary>Sets the visibility of the formula bar for the parts list. This is persistent data.</summary>
  void setIsFormulaBarEnabled(bool isUse);
  ///<summary>Returns the setting for heading.</summary>
  bool isHeadingEnabled() const;
  ///<summary>Returns the setting for heading.</summary>
  void setIsHeadingEnabled(bool isUse);
  ///<summary>Gets the attachment point type.</summary>
  AcmCPartListStd::AttachmentPoint attachPoint() const;
  ///<summary>Sets the attachment point type.</summary>
  ///<param name="aPoint">Input Only, specify the attachment point type.</param>
  ///<returns>Acm::eOK Operation successful;Acm::NotSupported Operation fail.Currently, it returns Acm:: eNotSupported if the part list is wrapping around title block.</returns>
  Acm::ErrorStatus setAttachPoint(AcmCPartListStd::AttachmentPoint aPoint);
  ///<summary>Gets the default parts list width.</summary>
  double width() const;
  ///<summary>Sets default parts list width.</summary>
  void setWidth(double width);

  double columnWidth(int columnIndex);
  void setColumnWidth(int columnIndex, double width);
  ///<summary>Gets the default parts list height.</summary>
  double height() const;
  ///<summary>Sets default parts list height.</summary>
  void setHeight(double height);
  ///<summary>Returns the origin of the defining plane.</summary>
  AcGePoint3d origin() const; 
  void setOrigin(const AcGePoint3d& pt);
  ///<summary>Gets the setting for title.</summary>
  int title() const;
  ///<summary>Sets the setting for title.</summary>
  void setTitle(const int title);
  ///<summary>Returns the title text, typically used as the parts list name.</summary>
  LPCTSTR titleText() const;
  ///<summary>Sets the title text, typically used as the parts list name.</summary>
  void setTitleText(const LPCTSTR titleText);
  ///<summary>Gets the default value for the word wrap feature</summary>
  ///<param name="enText">Indicates the text type information to retrieve. Default is to retrieve the data text information (kData)</param>
  int overFlow(AcmCPartListStd::TextType enText = AcmCPartListStd::kData) const;
  ///<summary>Sets whether to use word wrap.</summary>
  ///<param name="enText">Indicates the text type information to set. Default is to set both the header and data text information.</param>
  void setOverFlow(const int overflow, AcmCPartListStd::TextType enText = AcmCPartListStd::kAll);
  ///<param name="enText">Indicates the text type information to retrieve. Default is to retrieve the data text information.</param>
  int textInOneLine(AcmCPartListStd::TextType enText = AcmCPartListStd::kData) const;
  ///<param name="enText">Indicates the text type information to retrieve. Default is to retrieve the data text information.</param>
  void setTextInOneLine(const int textiol, AcmCPartListStd::TextType enText = AcmCPartListStd::kAll);

  ///<summary>Retrieves the Parts List heading and row text controls.</summary>
  ///<param name="enText">Specifies whether the heading or the row text control is retrieved. 
  ///Refer to the AcmCPartListStd::TextType enumerated type for the available text types. AcmCPartListStd::kAll should not be used. Specifying this text type retrieves the data text control instead.</param>
  ///<returns>Returns one of the enumerated item from the AcmCPartListStd::TextControl enumerated type.</returns>
  AcmCPartListStd::TextControl textControl(AcmCPartListStd::TextType enText) const;

  ///<summary>Sets the Parts List heading and row text controls.</summary>
  ///<param name="enControl">Specifies the text control to set. Refer to the AcmCPartListStd::TextControl enumerated type for the available text controls.</param>
  ///<param name="enText">Specifies whether the heading or the row text control is set. 
  ///Refer to the AcmCPartListStd::TextType enumerated type for the available text types. 
  ///Use AcmCPartListStd::kAll to set both the heading and row text controls.</param>
  void setTextControl(AcmCPartListStd::TextControl enControl, AcmCPartListStd::TextType enText);

  void setTIOLfromStd();

  ///<summary>Gets the line spacing for the parts list.</summary>
  Acm::PartListMultipleRow multipleRow() const;
  ///<summary>Sets the line spacing for the parts list.</summary>
  void setMultipleRow(const Acm::PartListMultipleRow multiple);
  AcmCPartList *subSymbol() const;

  ///<summary>Gets the index of the first item, which should be included in parts list.</summary>
  Adesk::Int32 minItem() const;
  ///<summary>Sets the index of the first item, which should be included in parts list.</summary>
  Acm::ErrorStatus setMinItem(const Adesk::Int32 min);
  ///<summary>Gets the index of the last item, which should be included in parts list.</summary>
  Adesk::Int32 maxItem() const;
  ///<summary>Sets the index of the last item, which should be included in parts list.</summary>
  Acm::ErrorStatus setMaxItem(const Adesk::Int32 max);
  ///<summary>Returns the evaluated item list. In this case the items are filtered using current filters.</summary>
  Acm::ErrorStatus getItemList(AcDbObjectIdArray& items) const;
  ///<summary>Sets the item list, which are displayed in parts list.</summary>
  Acm::ErrorStatus setItemList(const AcDbObjectIdArray& items);
  ///<summary>Gets the ID of the view containing the parts list.</summary>
  Acm::ErrorStatus getViewId(AcDbObjectId& viewId) const;
  ///<summary>Sets the ID of the view containing the parts list.</summary>
  Acm::ErrorStatus setViewId(const AcDbObjectId& viewId);

  ///<summary>Returns the comp view owner. This is the basic view id of an annotation view to which this partlist is associated to, if any.</summary>
  AcDbObjectId compViewId() const;
  ///<summary>Sets the comp view owner. This is the basic view id of an annotation view to which this partlist is associated to, if any.</summary>
  void setCompViewId(const AcDbObjectId& compViewId);

  ///<summary>This function is called during the updating of symbols that takes place when the standard is changed.</summary>
  virtual void           regen();

  using AcmSymbol::transformBy;
  ///<param name="xform"></param>
  ///<param name="symbolScale">Optional</param>
  virtual Acad::ErrorStatus transformBy(const AcGeMatrix3d& xform,
											 double symbolScale);
 
  virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler* pFiler);
  virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* pFiler) const;
  virtual Acad::ErrorStatus dxfInFields(AcDbDxfFiler* pFiler);
  virtual Acad::ErrorStatus dxfOutFields(AcDbDxfFiler* pFiler) const;
  virtual Acad::ErrorStatus subClose();

  virtual Acad::ErrorStatus subErase(Adesk::Boolean erasing);


  virtual bool getCustomBlockIds(AcDbObjectIdArray&) const;
  virtual bool setCustomBlock(LPCTSTR blName);
  virtual LPCTSTR customBlock() const;

  virtual void setFilterEmpty(bool useFilter);
  virtual bool filterEmpty() const;

  ///<summary>Creates a filter of a specified type and adds it to the Parts List.</summary>
  ///<returns>Returns Acad::eOk if a filter is successfully created and added to the Parts List.</returns>
  virtual Acad::ErrorStatus addFilter(AmdtItemFilter*, AcDbObjectId&);

  ///<summary>Creates a filter of a specified type and adds it to the Parts List.</summary>
  ///<param name="enType">Specifies the filter type to create and add to the Parts List. 
  ///Refer to the Acm::FilterType enumerated type for the available filter types.</param>
  ///<param name="oId">Returns the object ID of the filter object if successfully created and added.</param>
  ///<returns>Returns Acad::eOk if a filter is successfully created and added to the Parts List.</returns>
  virtual Acad::ErrorStatus addFilter(Acm::FilterType enType, AcDbObjectId& oId);

  ///<summary>Gets the list of ids for the part list.</summary>
  virtual bool getFilterIds(AcDbObjectIdArray&) const ;
  ///<summary>Removes and/or erases a filter.</summary>
  virtual Acad::ErrorStatus removeFilter(const AcDbObjectId&, bool erase = true);
  ///<summary>Indicates if the Parts List column splitting is enabled.</summary>
  bool isColumnSplitEnable() const;
  ///<summary>Enables or disables the Parts List column splitting.</summary>
  ///<param name="bEnable">Indicates if column splitting is to be enabled or disabled.</param>
  void setColumnSplitEnable(bool bEnable);
  ///<summary>Retrieves the Parts List column split wrap.</summary>
  AcmCPartListStd::ColumnSplitWrap  columnSplitWrap() const;
  void                              setColumnSplitWrap(AcmCPartListStd::ColumnSplitWrap enWrap);
  ///<summary>Retrieves the Parts List column splitting style.</summary>
  AcmCPartListStd::ColumnSplitStyle columnSplitStyle() const;
  ///<summary>Sets the Parts List column splitting style.</summary>
  ///<param name="enStyle">Indicates the column split style to set.</param>
  void                              setColumnSplitStyle(AcmCPartListStd::ColumnSplitStyle enStyle);
  ///<summary>Retrieves the Parts List column split rows.</summary>
  int  columnSplitRows() const;
  ///<summary>Sets the Parts List column split rows.</summary>
  ///<param name="nRows">Indicates the column split rows to set.</param>
  void setColumnSplitRows(int nRows);
  ///<summary>Retrieves the Parts List column split sections.</summary>
  int  columnSplitSections() const;
  ///<summary>Sets the Parts List column split sections.</summary>
  ///<param name="nSections">Indicates the column split sections to set.</param>
  void setColumnSplitSections(int nSections);

  ///<summary>This new member function returns true if the part list wraps around title block.</summary>
  bool isColumnSplitWrapAroundTitle() const;
  ///<summary>This new member function sets whether or not the part list wraps around the title block.</summary>
  void setColumnSplitWrapAroundTitle(bool bWrapTitle);

  ///<summary>This new member function returns the Id of the title block which the partlist wrapped.</summary>
  AcDbObjectId getTitleId() const;

  ///<summary>This new member function sets the title block for wrapped part list. 
  ///The title block was used to calculate the attachment for part list internally. It's type should be AcDbBlockReference.</summary>
  ///<param name="titleId">Input Only, Specify the title block Id.</param>
  void setTitleId(const AcDbObjectId& titleId);

  ///<summary>This new member function returns the height of the title block which is warpped.</summary>
  double getTitleHeight()const;
  ///<summary>It sets the height of the title block whick is wrapped around.</summary>
  void setTitleHeight(const double& dHeight);

  void setTitleHeight();

  ///<summary>This new member function sets the attachment point for wrapped partlist specially, as the wrapped part list can't set attachment point directly.</summary>
  ///<returns>Acm::eOK Operation successful;Acm::eInvalidContext Operation fail;Acm::eInvalidInput Operation fail.</returns>
  virtual Acm::ErrorStatus setWrapPListAttachPoint();


  virtual Acm::ErrorStatus setWrapPListAttachPoint(AcGePoint3d& insertPt);

protected:
  virtual Adesk::Boolean subWorldDraw(AcGiWorldDraw* pMode);
  virtual Acad::ErrorStatus subTransformBy(const AcGeMatrix3d& xform);

  
  ///<summary>Lists all leaders including their vertices, standard name and original name, server name and version.</summary>
  virtual void subList() const;
  ///<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;
  virtual Acad::ErrorStatus subWblockClone(AcRxObject* pOwnerObject,
                                        AcDbObject*& pClonedObject,
                                        AcDbIdMapping& idMap,
                                        Adesk::Boolean isPrimary = Adesk::kTrue) const;
  ///<summary>Sums geometry extents for a leader.</summary>
  virtual Acad::ErrorStatus subGetGeomExtents(AcDbExtents& extents) 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>Queries all leaders for their grip points.</summary>
  virtual Acad::ErrorStatus subGetGripPoints(AcGePoint3dArray& gripPnts,
                                          AcDbIntArray& osnapMasks,
                                          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 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 all leaders to get their intersections with the specified entity. 
  ///If it is a user-defined entity, it will be exploded first, and created entities will be resolved using the same member function.</summary>
  virtual Acad::ErrorStatus subIntersectWith(const AcDbEntity* ent,
	                            AcDb::Intersect intType, 
                              AcGePoint3dArray& points,
	                            INT_PTR thisGsMarker = 0, 
                              INT_PTR otherGsMarker = 0) const;
  ///<summary>Queries all leaders to get their intersections with the specified entity. 
  ///If it is a user-defined entity, it will be exploded first, and created entities will be resolved using the same member function.</summary>
  virtual Acad::ErrorStatus subIntersectWith(const AcDbEntity* ent,
	                            AcDb::Intersect intType, 
                              const AcGePlane& projPlane,
	                            AcGePoint3dArray& points, 
                              INT_PTR thisGsMarker = 0,
	                            INT_PTR otherGsMarker = 0) const;
  virtual Acad::ErrorStatus subGetClassID(CLSID* pClsid) const;
  virtual AcmCPartList* getPList();
  AcmCPartList *mpPartList;
};

DBREF_DECLARE(AcmPartList)

#endif
