//////////////////////////////////////////////////////////////////////////////
//
//  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 __BOMSTD_H
#define __BOMSTD_H
class AcmCColumnDef;
class AcmCBalloonStd;
class AcmCBalloonStdImp;
class AcmCBalloonImp;
class AcmCPartList;
class AcmCPartListImp;
class AcmCPartListStd;
class AcmCPartListStdImp;
class AmdtItemFilter;
class AcmBalloon;
class AcmBOMStdImp;
class AcmPartList;
class CGridHolder;

#include <vector>
///<summary>This class defines the common interface for BOM standards. All of its virtual member functions
///need to be overloaded to get symbol-specific behavior. This class is not instantiable. It overrides all 
///virtual functions defined at AcmSymbolStd.</summary>
class ACMSYMBB_CRX_DLLSHARE AcmBOMStd : public AcmSymbolStd
{
  friend class AcmSymbbInternals;
public:
  ACRX_DECLARE_MEMBERS(AcmBOMStd);
  ///<summary>Destructs the BOM standard class.</summary>
  virtual ~AcmBOMStd();

  const ACHAR* getBaseSymStdClassName() const override;
  ///<summary>Creates a new column of the specified type, name, and caption and appends it to the end of the 
  ///column list. If successful, the function returns the new column definition.</summary>
  Acm::ErrorStatus appendColumn(AcmCColumnDef*& pColumn,Acm::ColType type, 
                           Acm::DataType dataType,LPCTSTR colName,LPCTSTR caption = NULL);
  ///<summary>Creates a new column of the specified type, name, and caption and inserts it into the specified 
  ///position in the column list. If successful, the function returns the new column definition.</summary>
  Acm::ErrorStatus insertColumn(int pos, AcmCColumnDef*& pCol,Acm::ColType type, 
                           Acm::DataType dataType,LPCTSTR colName,LPCTSTR caption = NULL);
  ///<summary>Deletes the specified column of the specified position.</summary>
  ///<param name="pos">Specifies the position in the list of AcmCColumnDef objects in this BOM standard.</param>
  Acm::ErrorStatus deleteColumn(int pos);
  ///<summary>Reorders the specified column from the oldPos position to the newPos position.</summary>
  ///<param name="oldPos">Specifies the original position in the list of AcmCColumnDef objects in this BOM standard.</param>
  ///<param name="newPos">Specifies the new position in the list of AcmCColumnDef objects in this BOM standard.</param>
  Adesk::Boolean   moveColumn(int oldPos, int newPos);
  ///<summary>Returns the number of columns in the standard.</summary>
  Adesk::UInt16    columnLength() const;
  ///<summary>Gets the column object in the specified position in the columns list.</summary>
  AcmCColumnDef*       column(int pos);
  ///<summary>Gets the column object in the specified position in the columns list.</summary>
  const AcmCColumnDef* column(int pos) const;
  ///<summary>Gets the column object in the specified position in the columns list.</summary>
  ///<param name="name">If name is not null, the name is used to find the matching column.</param>
  ///<param name="caption ">If name is null and caption is not null, than caption is used to find the column.</param>
  AcmCColumnDef*       column(LPCTSTR name, LPCTSTR caption=NULL);
  ///<summary>Gets the column object in the specified position in the columns list.</summary>
  ///<param name="name">If name is not null, the name is used to find the matching column.</param>
  ///<param name="caption ">If name is null and caption is not null, than caption is used to find the column.</param>
  const AcmCColumnDef* column(LPCTSTR name, LPCTSTR caption=NULL) const;
  ///<summary>Gets the column using the persistent column index.</summary>
  AcmCColumnDef*       columnByIdx(Adesk::Int16 index);
  ///<summary>Gets the column using the persistent column index.</summary>
  const AcmCColumnDef* columnByIdx(Adesk::Int16 index) const;
  ///<summary>Gets the column by its type.</summary>
  AcmCColumnDef*       columnByType(Acm::ColType type);
  ///<summary>Gets the column by its type.</summary>
  const AcmCColumnDef* columnByType(Acm::ColType type) const;
  ///<summary>Gets the type of lines used for printing graphics.</summary>
  Acad::ErrorStatus getPrnLines(Acm::LineTypes& border,  Acm::LineTypes&  title,
                               Acm::LineTypes& heading, Acm::LineTypes&  item,
                               Acm::LineTypes& vertical) const;                              
  ///<summary>Sets the type of lines used for printing graphics.</summary>
  Acad::ErrorStatus setPrnLines(Acm::LineTypes border,  Acm::LineTypes  title,
                               Acm::LineTypes heading, Acm::LineTypes  item,
                               Acm::LineTypes vertical);                              
  ///<summary>Gets the page properties for printing.</summary>
  Acad::ErrorStatus getPrnPageProp(Adesk::Boolean& titleUsed,
                                   CString& titleText,
                                   Adesk::Boolean& centered) const;
  ///<summary>Sets the page properties for printing.</summary>
  Acad::ErrorStatus setPrnPageProp(Adesk::Boolean titleUsed,
                                   LPCTSTR titleText,
                                   Adesk::Boolean centered);
  ///<summary>Gets whether to print heading or not.</summary>
  Adesk::Boolean isPrnHeaderUsed() const;
  ///<summary>Sets whether to print heading or not.</summary>
  void setPrnIsHeaderUsed(Adesk::Boolean isUsed);
  ///<summary>Gets the height of the text in a different part of the printing table.</summary>
  Acad::ErrorStatus getPrnHeights(Adesk::Int16& title,
                                  Adesk::Int16& heading,
                                  Adesk::Int16& item) const;
  ///<summary>Sets the height of the text in a different part of the printing table.</summary>
  Acad::ErrorStatus setPrnHeights(Adesk::Int16 title,
                                  Adesk::Int16 heading,
                                  Adesk::Int16 item);
  ///<summary>Gets the font for printing the title of the BOM table.</summary>
  Acad::ErrorStatus getPrnTitleFont(CString& fntName,
                                    Adesk::Int16& height,
                                    Adesk::Boolean& isBold,
                                    Adesk::Boolean& isItalic) const;
  ///<summary>Sets the font for printing the title of the BOM table.</summary>
  Acad::ErrorStatus setPrnTitleFont(LPCTSTR fntName,
                                    Adesk::Int16 height,
                                    Adesk::Boolean isBold,
                                    Adesk::Boolean isItalic);
  ///<summary>Gets the font for printing the heading of the BOM table.</summary>
  Acad::ErrorStatus getPrnHeadingFont(CString& fntName,
                                      Adesk::Int16& height,
                                      Adesk::Boolean& isBold,
                                      Adesk::Boolean& isItalic) const;
  ///<summary>Sets the font for printing the heading of the BOM table.</summary>
  Acad::ErrorStatus setPrnHeadingFont(LPCTSTR fntName,
                                      Adesk::Int16 height,
                                      Adesk::Boolean isBold,
                                      Adesk::Boolean isItalic);
  ///<summary>Gets the font for printing the item text in the BOM table.</summary>
  Acad::ErrorStatus getPrnItemFont(CString& fntName,
                                   Adesk::Int16& height,
                                   Adesk::Boolean& isBold,
                                   Adesk::Boolean& isItalic) const;
  ///<summary>Sets the font for printing the item text in the BOM table.</summary>
  Acad::ErrorStatus setPrnItemFont(LPCTSTR fntName,
                                   Adesk::Int16 height,
                                   Adesk::Boolean isBold,
                                   Adesk::Boolean isItalic);
  ///<summary>Gets the margins for print pages.</summary>
  Acad::ErrorStatus getPrnMargins(Adesk::Int32& bottom,
                                  Adesk::Int32& left,
                                  Adesk::Int32& right,
                                  Adesk::Int32& top) const;
  ///<summary>Sets the margins for print pages.</summary>
  Acad::ErrorStatus setPrnMargins(Adesk::Int32 bottom,
                                  Adesk::Int32 left,
                                  Adesk::Int32 right,
                                  Adesk::Int32 top);
  ///<summary>Resets all settings to the factory default setting. You may preview this setting right
  ///after creating the new standard.</summary>
  virtual Adesk::Boolean setPrnFactoryDefaults();

  virtual Adesk::Boolean isBomEquivalents(const CMapStringToString& equiMap,
                                          CMapStringToString& attMap) const;
  ///<summary>Accesses parts list specific settings.</summary>
  AcmCPartListStd* partListServer() const;
  ///<summary>Accesses balloon specific settings.</summary>
  AcmCBalloonStd*  balloonServer() const;
  ///<summary>You may overload this method in their classes to initialize the BOM standard with their own
  ///parts list standard balloon standards.</summary>
  virtual Acm::ErrorStatus cInit();
  ///<summary>This member function will forward the call to the parts list standard and balloon standard objects, 
  ///if they are defined.</summary>
  virtual Adesk::Boolean setFactoryDefaults();
  ///<summary>This member function is implemented for the AcmSymbolStd interface. It is necessary to be 
  ///able to properly edit the standard.</summary>
  virtual Acm::ErrorStatus getRevision(CString& rev, Adesk::UInt16& year) const;
  ///<summary>This member function is implemented for the AcmSymbolStd interface. It is necessary to be 
  ///able to properly edit the standard.</summary>
  virtual Adesk::Boolean getTreeItems(AcmCObjPtrArray<CSymStdTreeItemDesc>& descArray) const;
  ///<summary>This member function is implemented for the AcmSymbolStd interface. It is necessary to be
  ///able to properly edit the standard.</summary>
  virtual Acm::ErrorStatus getDescription(CString& desc,
                                          CBitmap*& pBmpLoaded,
                                          CBitmap*& pBmpReg,
                                          Adesk::Boolean& enablePref) 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;

  void setCurrentBomName(CString& bomName);
  void getCurrentBomName(CString& bomName);

  ///<summary>Returns a CString containing the language code that the BOM was last translated to 
  ///(e.g. 'RUS' for Russian, 'ITA' for Italian, etc.). If the BOM has not been translated, the string is empty..</summary>
  CString getTrnLanguage() const;

  ///<summary>Returns the name string of a give BOM UOM type.</summary>
  ///<param name="type">Input only. Specifies one of the enumerated BOM UOM type.</param>
  ///<param name="uom">Output only. Returns the UOM name string.</param>
  virtual void getUOMName(Acm::UOMType type, CString& uom) const;

  ///<param name="type">Indicates the bom type.</param>
  ///<param name="separator">Separator used for structured bom.</param>
  ///<param name="useAssyPath">Whether to use assembly path for structured bom.</param>
  virtual void getDefaultBOMView(Acm::BOMType& type, CString& separator, bool& useAssyPath) const;

  ///<param name="type">Indicates the bom type.</param>
  ///<param name="separator">Separator used for structured bom.</param>
  ///<param name="useAssyPath">Whether to use assembly path for structured bom.</param>
  virtual void setDefaultBOMView(const Acm::BOMType& type, LPCTSTR separator, bool useAssyPath);

  ///<param name="list">Each item of the list is a column definition index.</param>
  virtual void setPropColumnList(const AcDbIntArray& list);
  ///<param name="list">Each item of the list is a column definition index.</param>
  virtual void getPropColumnList(AcDbIntArray& list) const;

protected:
  ///<summary>Constructs the BOM standard class. The constructor is protected.</summary>
  AcmBOMStd();
  ///<summary>This is a protected member function that is used to properly synchronize the BOM
  ///standard if the standard changes units.</summary>
  virtual Acm::ErrorStatus onChangeUnits(Adesk::Boolean isMetric);
  ///<summary>Sets up the internal BOM standard structure.</summary>
  void setPartListServer(AcmCPartListStd* pStd);
  ///<summary>Sets up the internal BOM standard structure.</summary>
  void setBalloonServer(AcmCBalloonStd* pStd);
  virtual Acad::ErrorStatus	subGetClassID(CLSID* pClsid) const;

private:
  AcmBOMStdImp* mpImp;
};                      
DBREF_DECLARE(AcmBOMStd);
///<summary>This is a virtual class. You may get the pointers to these objects from the AcmBOMStd object.</summary>
class ACMSYMBB_CRX_DLLSHARE AcmCColumnDef
{
public:
  ///<summary>Indicates the Column Definition information source.</summary>
  enum DataSource {
    ///<summary>Both Parts List and BOM column definition information.</summary>
    kAll = 0,
    ///<summary>BOM column definition information.</summary>
    kBOM,
    ///<summary>Parts List column definition information.</summary>
    kPartList
  };

public:
  virtual ~AcmCColumnDef();
  ///<summary>Gets the name (or tag) of the column.</summary>
  virtual LPCTSTR name() const = 0;
  ///<summary>Columns that do not allow their names to be changed will return local version of 
  ///the column name. This string is typically displayed in a dialog, so that you will understand
  ///what these columns mean.</summary>
  virtual CString localName() const = 0;
  ///<summary>Sets the name (or tag) of the column.</summary>
  virtual void  setName(LPCTSTR str) = 0;
  ///<summary>Gets the description of the column. It is used in the column heading in the parts list or BOM dialog.</summary>
  virtual LPCTSTR caption() const = 0;
  ///<summary>Sets the description of the column. It is used in the column heading in the parts list or BOM dialog.</summary>
  virtual void setCaption(LPCTSTR caption) = 0;
  ///<summary>This is support for online translation for column headings. If the input string can be translated, 
  ///the translated string will become caption and generated format specification is stored for translation 
  ///to another target language.</summary>
  virtual void createCaption(LPCTSTR translCaption) = 0;
  ///<summary>Gets the column's type.</summary>
  virtual Acm::ColType type() const = 0;
  ///<summary>Sets the column's type.</summary>
  virtual void setType(Acm::ColType type) = 0;

  ///<summary>Gets the alignment for the caption.</summary>
  ///<param name="enSrc">Indicates the column definition information source to retrieve from. Default is to 
  ///retrieve from the BOM columns definition information.</param>
  virtual Acm::AlignmentType captionAlign(AcmCColumnDef::DataSource enSrc = AcmCColumnDef::kBOM) const = 0;
  ///<summary>Sets the alignment for the caption.</summary>
  ///<param name="enSrc">Indicates the column definition information source to set to. Default is to set to 
  ///both the BOM and parts list column definition information.</param>
  virtual void setCaptionAlign(Acm::AlignmentType type, AcmCColumnDef::DataSource enSrc = AcmCColumnDef::kAll) = 0;  
  ///<summary>Gets the alignment for the data.</summary>
  ///<param name="enSrc">Indicates the column definition information source to set to. Default is to set to
  ///both the BOM and parts list column definition information.</param>
  virtual Acm::AlignmentType dataAlign(AcmCColumnDef::DataSource enSrc = AcmCColumnDef::kBOM) const = 0;
   ///<summary>Sets the alignment for the data.</summary>
  ///<param name="enSrc">Indicates the column definition information source to set to. Default is to set to
  ///both the BOM and parts list column definition information.</param>
  virtual void  setDataAlign(Acm::AlignmentType type, AcmCColumnDef::DataSource enSrc = AcmCColumnDef::kAll) = 0;
  ///<summary>Gets the column's persistent index.</summary>
  virtual Adesk::Int16 index() const = 0;
  ///<summary>Gets the column's data type. Column can have kGeneralText, kInteger, kDouble types.</summary>
  virtual Acm::DataType dataType() const = 0;
  ///<summary>Sets the column's data type. Column can have kGeneralText, kInteger, kDouble types.</summary>
  virtual void  setDataType(Acm::DataType type) = 0; 
  ///<summary>Gets the meaning for the column of the kDouble type, and also the precision used to display
  ///the data. For example, precision two means two digits after the decimal point.</summary>
  virtual Adesk::Int16 precision() const = 0;
  ///<summary>Determines the meaning for the column of the kDouble type, and also the precision used to 
  ///display the data. For example, precision two means two digits after the decimal point.</summary>
  virtual void setPrecision(Adesk::Int16 val) = 0;
  ///<summary>Gets the size of the buffer for the data. It has a meaning for the kGeneralText only.
  ///Other column types will use an appropriate value and the user cannot change it.</summary>
  virtual Adesk::Int16 size() const = 0;
  ///<summary>Sets the size of the buffer for the data. It has a meaning for the kGeneralText only. 
  ///Other column types will use an appropriate value and the user cannot change it.</summary>
  virtual void setSize(Adesk::Int16 size) = 0;
  ///<summary>Gets the column width. If the column is that used in the parts list, we use this width
  ///to print the data.. This is the default value for each parts list. You may override the general
  ///width for each parts list.</summary>
  virtual double width() const = 0;
  ///<summary>Sets the column width. If the column is that used in the parts list, we use this width
  ///to print the data.. This is the default value for each parts list. You may override the general
  ///width for each parts list.</summary>
  virtual void setWidth(double width) = 0;

  virtual Acad::ErrorStatus getEquivalents(CStringList& list) const = 0;
  virtual void setEquivalents(const CStringList& list) = 0;
  ///<summary>Gets the visibility of the column in the BOM dialog.</summary>
  virtual bool isVisible() const = 0;
  ///<summary>Sets the visibility of the column in the BOM dialog.</summary>
  virtual void setVisible(bool visible) = 0;
  ///<summary>Gets whether the column is being summed.</summary>
  virtual bool isSummed() const = 0;
  ///<summary>Sets whether the column is being summed.</summary>
  virtual void setIsSummed(bool isSummed) = 0;
  ///<summary>Gets the default data associated with the column.</summary>
  virtual LPCTSTR data() const = 0;
  ///<summary>Sets the default data associated with the column.</summary>
  virtual void setData(LPCTSTR data) = 0;
  ///<summary>Gets whether the column is generally editable from the UI.</summary>
  virtual bool isLocked() const = 0;
  ///<summary>Sets whether the column is generally editable from the UI.</summary>
  virtual void setIsLocked(bool isLocked) = 0;
  virtual void applyFormatting(CString &value) const {};  // added by DPT 8/14/02 for bug 408793
  virtual Adesk::Int16 leadingZeros() const = 0;       //for bug 402395  
  ///<summary>Returns the display prompt for this column. If not set or cleared, the display prompt 
  ///will return the value of caption.</summary>
  virtual LPCTSTR displayPrompt() const = 0;
  ///<param name="prompt">The new prompt to set to.</param>
  virtual void setDisplayPrompt(LPCTSTR prompt) = 0;
  ///<summary>Gets whether the column has a predefined list.</summary>
  virtual bool isPredDefList () const = 0;

  ///<summary>Checks whether the supplied value is a valid key for this predefined list column.</summary>
  ///<param name="value">Input Only. The string value to be checked.</param>
  virtual bool isValidPreDefinedListValue(const ACHAR *value) const = 0;

  ///<summary>Retrieves the predefined list associated with this column if any.</summary>
  ///<param name="preDefList">An empty vector should be passed in.The contents of the predefined list 
  ///will be returned into this vector string pair. The first string of the string pair is the key and 
  ///the second is the associated description. The caller is expected to deallocate the memory allocated
  ///for const ACHAR* using delete [].</param>
  ///<param name="default">The default key value, if any.</param>
  virtual void getPreDefinedList(
    std::vector< std::pair<const ACHAR *,const ACHAR * >> &preDefList,
    ACHAR * &defValue) const = 0;

  ///<summary>This sets the predefined list for this column.</summary>
  ///<param name="preDefList">Input Only. The predefined list to set to. The vector contains a string pair 
  ///of which the first is the key and the second is the description of the associated key.</param>
  ///<param name="default">Input Only, optional. The default key value, if any.</param>
  virtual Acm::ErrorStatus setPreDefinedList(
    const std::vector< std::pair<const ACHAR *,const ACHAR * >> &preDefList,
    const ACHAR * defValue = NULL) = 0;

  ///<summary>Removes the predefined list associated with this column, if any.</summary>
  virtual void removePreDefinedList() = 0;

};

inline 
AcmCColumnDef::~AcmCColumnDef()
{}
///<summary>A symbol contains one sub-symbol ?C AcmCBalloon.</summary>
class ACMSYMBB_CRX_DLLSHARE AcmCBalloon : public AcmCSubSymbol
{
public:

  AcmCBalloon(AcmBalloon* pSym);
  virtual ~AcmCBalloon();

  // Copy constructor
  AcmCBalloon(const AcmCBalloon& other);

  Adesk::Boolean operator==(const AcmCBalloon&) const;
  virtual AcmCBalloon& operator=(const AcmCBalloon&);
  virtual AcmCBalloon* clone()const;
  virtual void clear();

  AcmCBalloonImp* getImp() const { return mpImp; }

  ///<summary>Gets the list of items with which the balloon is associated.</summary>
  virtual AcDbObjectIdArray rowIds() const;
  ///<summary>Gets the list of items with which the balloon is associated.</summary>
  virtual void getRowIds(AcDbObjectIdArray& rowIds) const;
  ///<summary>Gets the list of items with which the balloon is associated.</summary>
  virtual void setRowIds(const AcDbObjectIdArray& rowIds);
  ///<summary>Sets the balloon type.</summary>
  virtual Acm::BalloonType type() const;
  ///<summary>Sets the balloon type.</summary>
  virtual void setType(const Acm::BalloonType type);
  ///<summary>Gets the balloon collection type.</summary>
  virtual Acm::BalloonCollectionType collectionType() const;
  ///<summary>Sets or get the collection type. It can be kHorizontal or kVertical.</summary>
  virtual void setCollectionType(const Acm::BalloonCollectionType bct);
  ///<summary>Gets the leader direction. It can be kToTop, kToBottom, kToLeft, or kToRight, 
  ///depending on the quadrant the leader is pointing to.</summary>
  virtual Acm::Direction leaderDirection() const;

  ///<summary>Sets the custom block name.</summary>
  virtual bool setUserType(LPCTSTR blkName);
  ///<summary>Sets the custom block ID used to display the current balloon. The block must exist in
  ///the current drawing, otherwise it will not be displayed.</summary>
  virtual bool setUserTypeId(const AcDbObjectId& btrId);
  ///<summary>Gets the custom block name.</summary>
  virtual LPCTSTR userType() const;
  ///<summary>Gets the custom block ID used to display the current balloon. The block must exist in 
  ///the current drawing, otherwise it will not be displayed.</summary>
  virtual AcDbObjectId userTypeId() const;
  ///<summary>Gets the type of balloon attachment which control where the leader tip point is pointing to.</summary>
  virtual Acm::BalloonAttachType attachType() const;
  ///<summary>Sets the type of balloon attachment which control where the leader tip point is pointing to.</summary>
  virtual void setAttachType(Acm::BalloonAttachType type);

  virtual AcGePoint3d origin() const override;
  ///<summary>Sets the origin of the symbol in WCS.</summary>
  virtual void setOrigin(const AcGePoint3d& origin) override;
  ///<summary>Gets the value of any symbol variable.</summary>
  virtual LPCTSTR value(Acm::Variable var) const override;
  ///<summary>Gets the value of any symbol variable.</summary>
  virtual Acm::ErrorStatus getValue(Acm::Variable var, CString& value) const override;
  ///<summary>Sets the value of any symbol variable.</summary>
  virtual Acm::ErrorStatus setValue(Acm::Variable var, LPCTSTR value) override;
  ///<summary>Gets the visibility status of the editing controls.</summary>
  virtual Acm::Visibility  variableStatus(Acm::Variable var) const override;
  ///<summary>Sets the visibility status of the editing controls.</summary>
  virtual Acm::ErrorStatus setVariableStatus(Acm::Variable var, Acm::Visibility status) override;
  ///<summary>Gets the variable support data, such as the help index, dialog index, tooltip string, and label string.</summary>
  virtual Acm::ErrorStatus getVarDlgInfo(Acm::Variable var, CVarDlgInfo& v) const override;
  ///<summary>Sets the variable support data, such as the help index, dialog index, tooltip string, and label string.</summary>
  virtual Acm::ErrorStatus setVarDlgInfo(Acm::Variable var, const CVarDlgInfo& v) override;


  virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler* filer, Adesk::UInt16 ver) override;
  virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* filer) const override;

  Acad::ErrorStatus varInFields(const AcmVariant* pVar, AcRxObject* pFiler = nullptr) override;
  Acad::ErrorStatus varOutFields(AcmVariant* pVar, AcRxObject* pFiler = nullptr) const override;


  virtual Acad::ErrorStatus dxfInFields(AcDbDxfFiler* filer) override;
  virtual Acad::ErrorStatus dxfOutFields(AcDbDxfFiler* filer) const override;

private:
    AcmCBalloonImp* mpImp{ nullptr };
};

///<summary>This is the parent virtual class, used to implement new balloon services.</summary>
class ACMSYMBB_CRX_DLLSHARE AcmCBalloonService
{
public:
  virtual ~AcmCBalloonService();
  ///<summary>Sets the list of the column indexes to be used to properly display the balloon.</summary>
  virtual void setColumnList(const AcDbIntArray& lst) = 0;
  ///<summary>Gets the list of the column indexes to be used to properly display the balloon.</summary>
  virtual void getColumnList(AcDbIntArray& lst) const = 0;
  ///<summary>This member function is called by AcmCBalloonStd when attempting to remove the column. 
  ///If the column is used in any balloon service, the member function will return false and the column
  ///will not be removed.</summary>
  virtual Adesk::Boolean removeColumnByIdx(Adesk::Int16 idx) = 0;
  virtual Acm::BalloonType type() const = 0;
  ///<summary>Returns the maximum number of columns that may be displayed by the service.</summary>
  virtual Adesk::Int16 maxNumber() const = 0;

  virtual void getDesc(AcmCSymbolDesc& pHan, bool useSmallBitmap = false) const = 0;
  ///<summary>Returns the radius of the given balloon shape in the given direction.</summary>
  virtual double radius(AcmBalloon* , const AcGeVector3d& direction) const = 0;
  ///<summary>Calculates the last point of the leader.</summary>
  ///<param name="ptEnd">The end point of the leader is the center point of the balloon</param>
  virtual void recalcPoint(const AcmCBalloon* pSubSym,
                           const AcGePoint3d& ptLea,
                           AcGePoint3d& ptEnd) const = 0;
  ///<summary>This is the main member function used to get the sub-entities for the balloon. 
  ///It calls getSubEntsSingle for each item saved in balloon.</summary>
  virtual void getSubEnts(const AcmCBalloon* pData,
                          AcmCAuxEntArray& subEnts) const;
  ///<summary>Gets the sub-entities for the single item.</summary>
  ///<param name="index">Specifies the index in the list of items.</param>
  virtual void getSubEntsSingle(const AcmCBalloon* pData,
                                AcmCAuxEntArray& subEnts, 
                                int index = 0) const = 0;
  ///<summary>This member function will forward the call to the balloon service objects, if they are defined.</summary>
  virtual Adesk::Boolean setFactoryDefaults() = 0;
  
  virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler* filer, Adesk::UInt16 ver) = 0;
  virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* filer) const = 0;
  virtual Acad::ErrorStatus dxfInFields(AcDbDxfFiler* filer) = 0;
  virtual Acad::ErrorStatus dxfOutFields(AcDbDxfFiler* filer) const = 0;

  ///<summary>Returns the horizontal distance for the balloon.</summary>
  virtual double horizDistance() const = 0;
  ///<summary>Sets the horizontal distance for the balloon</summary>
  virtual void setHorizDistance(double horDist) = 0;
  ///<summary>Returns the vertical distance for the balloon.</summary>
  virtual double vertDistance() const = 0;
  ///<summary>Sets the vertical distance for the balloon</summary>
  virtual void setVertDistance(double verDist) = 0;
  ///<summary>Gets the pattern used to display the balloon to '=Part: (name)' and you'll get the
  ///desired result without having to create new columns.</summary>
  virtual LPCTSTR pattern() const = 0;
  ///<summary>Sets the pattern used to display the balloon to '=Part: (name)' and you'll get the
  ///desired result without having to create new columns.</summary>
  virtual void setPattern(LPCTSTR pattern) = 0;
};

inline 
AcmCBalloonService::~AcmCBalloonService()
{}

///<summary>This class is responsible for balloon symbols. It contains services for different types of balloons. 
///The class has the following successors: AcmCBalloonStdANSI, AcmCBalloonStdBS, AcmCBalloonStdDIN, AcmCBalloonStdISO,
///AcmCBalloonStdJIS, and AcmCBalloonStdGB, which implement standard-specific variations.</summary>
class ACMSYMBB_CRX_DLLSHARE AcmCBalloonStd
{
  friend class AcmSymbbInternals;
public:
  ///<summary>Constructs the balloon standard class. The constructor is protected.</summary>
  AcmCBalloonStd(AcmBOMStd *std);
  ///<summary>Destructs the balloon standard class.</summary>
  virtual ~AcmCBalloonStd();
  ///<summary>Gets the BOM standard data.</summary>
  AcmBOMStd* getBOMStandard() const;
  ///<summary>Initialization member function. It will prepare the symbol standard to be edited as the original 
  ///or non-original standard.</summary>
  virtual void initToEditOriginal();
  ///<summary>Initialization member function. It will prepare the symbol standard to be edited as the original 
  ///or non-original standard.</summary>
  virtual void initToEdit();
  ///<param name="bSettingsOnly">Indicates if the Balloon settings are to be edited only. If bSettingsOnly is 
  ///true, the Balloon settings are edited using the Balloon Settings dialog. If bSettingsOnly is false, the 
  ///Balloon configuration is edited using the BOM Settings dialog. Default is to edit the Balloon configuration.</param>
  virtual Adesk::Boolean edit(CWnd* parentWindow = NULL, bool bSettingsOnly = false);
  
  virtual Acm::ErrorStatus getRevision(CString& rev, Adesk::UInt16& year) const;
  ///<summary>You may overload this method in their classes to initialize the balloon standard.</summary>
  virtual Acm::ErrorStatus cInit();
  ///<summary>This member function will forward the call to the parts list standard and balloon standard objects,
  ///if they are defined.</summary>
  virtual Adesk::Boolean setFactoryDefaults();
  virtual Adesk::Boolean getDesc(AcmCObjArray<AcmCSymbolDesc>& list, bool useSmallBitmap = false) const;
  virtual Adesk::Boolean getBalloonArrowDesc(AcmCObjArray<AcmCArrowDesc>& list,
                                             Adesk::Boolean allSrv=Adesk::kFalse,
                                             Adesk::Boolean bDarkTheme = Adesk::kFalse) const;
  Acm::ArrowType arrow() const;
  void setArrow(Acm::ArrowType type);
  ///<summary>Retrieves the by standard state for the corresponding property.</summary>
  bool arrowByStandard() const;
  ///<summary>Retrieves the by standard state for the corresponding property.</summary>
  ///<param name="byStandard">New state to set to.</param>
  void setArrowByStandard(bool byStandard);
  Acm::ArrowType auxArrow() const;

  void setAuxArrow(Acm::ArrowType type);
  ///<summary>Retrieves the by standard state for the corresponding property.</summary>
  bool auxArrowByStandard() const;
  ///<summary>Retrieves the by standard state for the corresponding property.</summary>
  ///<param name="byStandard">New state to set to.</param>
  void setAuxArrowByStandard(bool byStandard);
  
  void setAuxUsing(bool use);
  bool isAuxUsed() const;
  Acm::BalloonType defaultBalloonType() const;

  void setDefaultBalloonType(Acm::BalloonType type);
  Adesk::UInt16 color() const;

  void setColor(Adesk::UInt16 color);
  const AcCmColor & trueColor() const;
  void setTrueColor(const AcCmColor & color);
  ///<summary>Retrieves the by standard state for the corresponding property.</summary>
  bool colorByStandard() const;
  ///<summary>Retrieves the by standard state for the corresponding property.</summary>
  ///<param name="byStandard">New state to set to.</param>
  void setColorByStandard(bool byStandard);
  ///<summary>Retrieves the by standard state for the corresponding property.</summary>
  const AcCmColor & byStdTextTrueColor() const;
  double textHeight() const;

  void setTextHeight(double height);
  ///<summary>Retrieves the by standard state for the corresponding property.</summary>
  bool textHeightByStandard() const;
  ///<summary>Retrieves the by standard state for the corresponding property.</summary>
  ///<param name="byStandard">New state to set to.</param>
  void setTextHeightByStandard(bool byStandard);
  ///<summary>Retrieves the by standard state for the corresponding property.</summary>
  double byStdTextHeight() const;

  ///<summary>Gets the setting for the default balloon service's scale factor.</summary>
  double sizeFactor() const;
  ///<summary>Sets the setting for the default balloon service's scale factor.</summary>
  void setSizeFactor(double sizeFactor);
  ///<summary>Gets the setting for the default balloon service.</summary>
  double horizDistance() const;
  ///<summary>Sets the setting for the default balloon service.</summary>
  void setHorizDistance(double horDist);
  ///<summary>Gets the setting for the default balloon service.</summary>
  double vertDistance() const;
  ///<summary>Sets the setting for the default balloon service.</summary>
  void setVertDistance(double verDist);
  double arrowInset() const;
  void setArrowInset(double inset);
  ///<summary>Gets the setting for the default balloon service.</summary>
  LPCTSTR pattern() const;
  ///<summary>Sets the setting for the default balloon service.</summary>
  void setPattern(LPCTSTR pattern);
  ///<summary>Gets the setting for the default balloon service, if it has two display fields. 
  ///The behavior is same as the member function: setPattern.</summary>
  LPCTSTR pattern2() const;
  ///<summary>Sets the setting for the default balloon service, if it has two display fields. 
  ///The behavior is same as the member function: setPattern.</summary>
  void setPattern2(LPCTSTR pattern);
  Adesk::Boolean registerService(AcmCBalloonService* pNewServ);
  AcmCBalloonService* getService(Acm::BalloonType type) const;
  AcmCBalloonService* serviceAt(Adesk::UInt32 at) const;
  Adesk::UInt32 numOfServices() const;
  Adesk::Boolean removeService(Acm::BalloonType type);
  Adesk::Boolean removeServiceAt(Adesk::UInt32 at);
  ///<summary>Obtains the baloon's sub-entities.</summary>
  virtual void getSubEnts(const AcmCBalloon* pSymb,
                          AcmCAuxEntArray& subents) const;
  
  virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler* filer, Adesk::UInt16 ver);       
  virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* filer) const;
  virtual Acad::ErrorStatus dxfInFields(AcDbDxfFiler* filer);       
  virtual Acad::ErrorStatus dxfOutFields(AcDbDxfFiler* filer) const;

  virtual bool setUserType(LPCTSTR blkName);
  virtual bool setUserTypeId(const AcDbObjectId& btrId);
  virtual LPCTSTR userType() const;
  virtual AcDbObjectId userTypeId() const;
  virtual Acm::BalloonAttachType attachType() const;

  virtual void setAttachType(Acm::BalloonAttachType type);
  ///<summary>Specify the default collection type for balloons. The default implementation uses
  ///BalloonCollectionType::kHorizontal.</summary>
  virtual Acm::BalloonCollectionType collectionType() const; 

protected:
  ///<summary>This is a protected member function that is used to properly synchronize the balloon 
  ///standard if the standard changes units.</summary>
  virtual Acm::ErrorStatus onChangeUnits(Adesk::Boolean isMetric);

private:
  AcmBOMStd* mpOwner;
  AcmCBalloonStdImp *mpImp;
};

///<summary>This class is responsible for parts list symbols. It contains no special services for the class,
///but it may contain some filters. The class has the following successors: AcmCPartListStdANSI, AcmCPartListStdBS, 
///AcmCPartListStdDIN, AcmCPartListStdISO, and AcmCPartListStdJIS, which implement standard-specific variations.</summary>
class ACMSYMBB_CRX_DLLSHARE AcmCPartListStd
{
  friend class AcmSymbbInternals;
public:
  ///<summary>This is record AcmCPartListStd::AttachmentPoint.</summary>
  enum AttachmentPoint {
    kTopLeft = 0,
    kBottomLeft,
    kBottomRight,
    kTopRight
  };
  ///<summary>Indicates the Parts List text type.</summary>
  enum TextType {
    ///<summary>Both the Header and Data text.</summary>
    kAll = 0,
    ///<summary>Header text.</summary>
    kHeading,
    ///<summary>Data text.</summary>
    kData
  };
  ///<summary>Indicates the Parts List text margin type.</summary>
  enum MarginType {
      ///<summary>Top margin.</summary>
    kTop = 0,
    ///<summary>Left margin.</summary>
    kLeft,
    ///<summary>Bottom margin.</summary>
    kBottom,
    ///<summary>Right margin.</summary>
    kRight
  };
  ///<summary>Indicates the Parts List column split wrap.</summary>
  enum ColumnSplitWrap {
    ///<summary>Wrap left.</summary>
    kSplitLeft = 0,
    ///<summary>Wrap right.</summary>
    kSplitRight
  };
  ///<summary>Indicates the Parts List column splitting style.</summary>
  enum ColumnSplitStyle {
      ///<summary>Split by rows.</summary>
    kSplitRows = 0,
    ///<summary>Split by sections.</summary>
    kSplitSections
  };
  ///<summary>Enumerates all available text controls for a Parts List.</summary>
  enum TextControl {
    ///<summary>Specifies that a Parts List text is not controlled. 
	///The text overruns the column width when the length of the text exceeds the column width.</summary>
    kNone = 0,
    ///<summary>Specifies that a Parts List text fits within the column when the length of the text exceeds the column width.</summary>
    kFit,
    ///<summary>Specifies that a Parts List text wraps to the next line when the length of the text exceeds the column width.</summary>
    kWrap
  };
  ///<summary>Constructs the parts list standard class. The constructor is protected.</summary>
  AcmCPartListStd(AcmBOMStd *std, bool bCreateImpl = true);
  ///<summary>Destructs the parts list standard class.</summary>
  virtual ~AcmCPartListStd();
  ///<summary>Gets the access to the parent class.</summary>
  AcmBOMStd* getBOMStandard() const;
  ///<summary>Obtains the parts lists sub-entities.</summary>
  virtual void getSubEnts(const AcmCPartList* pSymb,
                          AcmCAuxEntArray& subents) const;
  ///<summary>Initialization member function. It will prepare the symbol standard to be edited as the original 
  ///or non-original standard.</summary>
  virtual void initToEdit();
  ///<summary>Initialization member function. It will prepare the symbol standard to be edited as the original 
  ///or non-original standard.</summary>
  virtual void initToEditOriginal();
  ///<param name="bSettingsOnly">Indicates if the Parts List settings are to be edited only. If bSettingsOnly 
  ///is true, the Parts List settings are edited using the Parts List Settings dialog. If bSettingsOnly is false,
  ///the Parts List configuration is edited using the BOM Settings dialog. Default is to edit the Parts List configuration (false).</param>
  virtual Adesk::Boolean edit(CWnd* parentWindow = NULL, bool bSettingsOnly = false);
  ///<summary>You may overload this method in their classes to initialize the parts list standard.</summary>
  virtual Acm::ErrorStatus cInit();
  ///<summary>This member function will forward the call to the parts list standard and balloon standard objects, 
  ///if they are defined.</summary>
  virtual Adesk::Boolean setFactoryDefaults();
  ///<summary>This member function is implemented for the AcmSymbolStd interface. It is necessary to be able to 
  ///properly edit the standard.</summary>
  virtual Acm::ErrorStatus getRevision(CString& rev, Adesk::UInt16& year) const;
  ///<summary>Checks whether the parts list is visible or not.</summary>
  virtual Acm::ErrorStatus checkVisibility(AcmCPartList* pData) const;
  ///<summary>Initializes the parts list standard.</summary>
  virtual Acm::ErrorStatus initFields(AcmCPartList* pData) const;
  ///<summary>Sets the suggested values for any value in the parts list standard.</summary>
  virtual Acm::ErrorStatus setSuggested(AcmCPartList* pData) const;  
  
  virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler* filer, Adesk::UInt16 ver);
  virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* filer) const;
  virtual Acad::ErrorStatus dxfInFields(AcDbDxfFiler* filer);
  virtual Acad::ErrorStatus dxfOutFields(AcDbDxfFiler* filer) const;

  ///<summary>Returns the recalculated height of the heading, including the gap.</summary>
  double                   headingHeight() const;
  ///<summary>Returns the recalculated height of one row, including gap and line spacing.</summary>
  double                   rowHeight() const;
  ///<summary>Returns the recalculated height of one row.</summary>
  double                   realRowTextHeight() const;
  ///<summary>Gets the default value for the parts list heading. If the heading is not enabled, the title is 
  ///disabled as well.</summary>
  bool                     isHeadingEnabled() const;
  ///<summary>Sets the default value for the parts list heading. If the heading is not enabled, the title is 
  ///disabled as well.</summary>
  void                     setIsHeadingEnabled(bool isUse);
  ///<summary>Gets the default attachment point for new parts lists.</summary>
  ///<returns>Possible values are kTopLeft, kBottomLeft, kBottomRight or kTopRight.</returns>
  AttachmentPoint          attachPoint() const;
  ///<summary>Sets the default attachment point for new parts lists.</summary>
  ///<returns>Possible values are kTopLeft, kBottomLeft, kBottomRight or kTopRight.</returns>
  void                     setAttachPoint(AttachmentPoint aPoint);
  bool                     attachPointByStandard() const;
  void                     setAttachPointByStandard(bool byStandard);
  ///<summary>Gets the default value for visibility of the grip frame.</summary>
  bool                     isGripFrameEnabled() const;
  ///<summary>Sets the default value for visibility of the grip frame.</summary>
  void                     setIsGripFrameEnabled(bool isUse);
  ///<summary>Gets the line spacing.</summary>
  ///<returns>Possible values are kSingle, kDouble or kTriple.</returns>
  Acm::PartListMultipleRow multipleRow() const;
  ///<summary>Sets the line spacing. Possible values are kSingle, kDouble or kTriple.</summary>
  void                     setMultipleRow(Acm::PartListMultipleRow multiple);
  ///<summary>Gets the color for the text used to display the heading and title.</summary>
  Adesk::UInt16            headTextColor() const;
  ///<summary>Sets the color for the text used to display the heading and title.</summary>
  void                     setHeadTextColor(Adesk::UInt16 color);  
  const AcCmColor&         headTextTrueColor() const;
  void                     setHeadTextTrueColor(const AcCmColor & col);
  bool                     headTextColorByStandard() const;
  void                     setHeadTextColorByStandard(bool byStandard);
  ///<summary>Gets the height for the text used to display the heading and title.</summary>
  double                   headTextHeight() const;
  ///<summary>Sets the height for the text used to display the heading and title.</summary>
  void                     setHeadTextHeight(double height);
  bool                     headTextHeightByStandard() const;
  void                     setHeadTextHeightByStandard(bool byStandard);
  ///<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(TextType enText = kData) const;
  ///<summary>Sets the default value for the word wrap feature.</summary>
  ///<param name="enText">Indicates the text type information to set. Default is to set both the header and 
  ///the data text information (kAll)</param>
  void                     setOverFlow(int overflow, TextType enText = kAll);
  ///<param name="enText">Indicates the text type information to retrieve. Default is to retrieve the data 
  ///text information.</param>
  int                      textInOneLine(TextType enText = kData) const;
  ///<param name="enText">Indicates the text type information to set. Default is to set both the header and
  ///data text information.</param>
  void                     setTextInOneLine(const int textiol, TextType enText = kAll);

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

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

  ///<summary>Gets the color for the frame. All other lines in the table use the symbol color.</summary>
  Adesk::UInt16            frameColor() const;
  ///<summary>Sets the color for the frame. All other lines in the table use the symbol color.</summary>
  void                     setFrameColor(Adesk::UInt16 color);
  const AcCmColor&         frameTrueColor() const;
  void                     setFrameTrueColor(const AcCmColor & color);
  ///<summary>Sets the list of currently displayed columns.</summary>
  void                     setColumnList(const AcDbIntArray& list);
  ///<summary>Gets the list of currently displayed columns.</summary>
  void                     getColumnList(AcDbIntArray& list) const;
  ///<summary>This is the callback from the AcmBOMStd. It informs the parts list it is going to remove the column
  ///of this index. The part list standard should remove the index from its list.</summary>
  Adesk::Boolean           removeColumnByIdx(Adesk::Int16 idx);
  ///<summary>Gets the gap for the text used to display the heading and title. The title uses the same text 
  ///properties as the heading, including the gap.</summary>
  double                   headingGap() const;
  ///<summary>Gets the row gap. All lines in the table keep the same distance from the text.</summary>
  double                   rowGap() const;

  ///<summary>Sets the gap for the text used to display the heading and title. The title uses the same text 
  ///properties as the heading, including the gap. The API now supports wrap state, heading gap and row gap
  ///settings for part list header text and data text.</summary>
  ///<param name="bUpdateMargin">Indicates if the header margins are to be updated with the header gap. The 
  ///header margins are the top, left, bottom and right margins. Default is to update the header margins with 
  ///the header gap (True).</param>
  void                     setHeadingGap(double hGap, bool bUpdateMargin = true);

  ///<summary>Sets the row gap. All lines in the table keep the same distance from the text. The API now supports 
  ///wrap state, heading gap and row gap settings for part list header text and data text.</summary>
  ///<param name="bUpdateMargin">Indicates if the data margins are to be updated with the row gap. The data margins
  ///are the top, left, bottom and right margins. Default is to update the data margins with the row gap (True).</param>
  void                     setRowGap(double rGap, bool bUpdateMargin = true);

  ///<summary>Retrieves the Parts List text margin for a specified text type.</summary>
  ///<param name="enText">Indicates the text type information to retrieve.</param>
  ///<param name="enMargin">Indicates the margin type information to retrieve.</param>
  double                   textMargin(TextType enText, MarginType enMargin) const;

  ///<summary>Sets the Parts List text margin for a specified text type.</summary>
  ///<param name="nMargin">The text margin value to set.</param>
  ///<param name="enText">Indicates the text type information to set.</param>
  ///<param name="enMargin">Indicates the margin type information to set.</param>
  ///<param name="bUpdateGap">Indicates if the text type gap is to be updated with the text top margin value. 
  ///Default is not to update the text type gap with the text top margin value.</param>
  void                     setTextMargin(double nMargin, TextType enText, MarginType enMargin, bool bUpdateGap = false);

  ///<summary>Gets the default value for displaying the title string in the parts list entity.</summary>
  int                      title() const;
  ///<summary>Sets the default value for displaying the title string in the parts list entity.</summary>
  void                     setTitle(int title);
  ///<summary>Gets the text size for data in a parts list independently of symbol text size.</summary>
  double                   dataTextHeight() const;
  ///<summary>Sets the text size for data in a parts list independently of symbol text size.</summary>
  void                     setDataTextHeight(double height);
  bool                     dataTextHeightByStandard() const;
  void                     setDataTextHeightByStandard(bool byStandard);

  ///<summary>Gets the text style for data in a parts list independent of symbol text style.</summary>
  AcDbObjectId             textStyleId(TextType enText = kData) const;
  ///<summary>Sets the text style for data in a parts list independent of symbol text style.</summary>
  ///<param name="enText">Indicates the text type information to set. Default is to set both the header and 
  ///data text information (kAll).</param>
  void                     setTextStyleId(AcDbObjectId& textId, TextType enText = kAll);
  bool                     textStyleByStandard(TextType enText = kData) const;
  void                     setTextStyleByStandard(bool byStandard, TextType enText = kAll);

  ///<summary>Gets the text color for data in a parts list independently of symbol text color.</summary>
  Adesk::UInt16            dataTextColor() const;
  ///<summary>Sets the text color for data in a parts list independently of symbol text color.</summary>
  void                     setDataTextColor(Adesk::UInt16 color);  
  const AcCmColor&         dataTextTrueColor() const;
  void                     setDataTextTrueColor(const AcCmColor & color);
  bool                     dataTextColorByStandard() const;
  void                     setDataTextColorByStandard(bool byStandard);
  AcDb::LineWeight         verticalLineWeight(const AcDbObjectId& layerId) const;  
  bool                     isBoldVerticalLine() const;
  void                     setIsBoldVerticalLine(bool isBold);
  ///<summary>Sets the name of the scheme being used to display the parts list.</summary>
  bool setCustomBlock(LPCTSTR blName);
  ///<summary>Gets the name of the scheme being used to display the parts list.</summary>
  LPCTSTR customBlock() const;
  ///<summary>Sets the switch that determines whether to display even blocks that don't contain any evaluated value.</summary>
  void setFilterEmpty(bool useFilter);
  ///<summary>Gets the switch that determines whether to display even blocks that don't contain any evaluated value.</summary>
  bool filterEmpty() const;
  ///<summary>In case you have migrated the parts list and want to use an old DSK mask file to generate a parts list, 
  ///this member function gets the status. The evaluation may be slower this way.</summary>
  bool isDSK() const;
  ///<summary>In case you have migrated the parts list and want to use an old DSK mask file to generate a parts list, 
  ///this member function can switch this on. The evaluation may be slower this way.</summary>
  void setDSK(bool use);
  ///<summary>Return a list of AcDbBlockTableRecords objects, which are used to display the part list.</summary>
  Acad::ErrorStatus getBlocksIds(AcDbObjectIdArray& blocksIds) const;
  ///<summary>Gets the default width of the parts list</summary>
  double partListWidth() const;
  ///<summary>Indicates if the Parts List column splitting is enabled.</summary>
  bool             isColumnSplitEnable() const;
  ///<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>
  ColumnSplitWrap  columnSplitWrap() const;
  ///<param name="enWrap">Indicates the column split wrap to set.</param>
  void             setColumnSplitWrap(ColumnSplitWrap enWrap);
  ///<summary>Retrieves the Parts List column splitting style.</summary>
  ColumnSplitStyle columnSplitStyle() const;
  ///<param name="enStyle">Indicates the column split style to set.</param>
  void             setColumnSplitStyle(ColumnSplitStyle enStyle);
  ///<summary>Retrieves the Parts List column split rows.</summary>
  int              columnSplitRows() const;
  ///<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;
  ///<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's setting is wrapped around title block.</summary>
  bool             isColumnSplitWrapAroundTitle() const;
  ///<summary>This new member function sets whether or not the part list's setting is wrapped around the title block.</summary>
  void             setColumnSplitWrapAroundTitle(bool bEnable);

protected:
  ///<summary>This is a protected member function that is used to properly synchronize the parts list
  ///standard if the standard changes units.</summary>
  virtual Acm::ErrorStatus onChangeUnits(Adesk::Boolean isMetric);
  ///<summary>This member function is used for easier evaluation of the standard support. It is protected
  ///and may be used from inherited classes only.</summary>
  void getSubEntsHeading(const AcmCPartList* pSymb, AcmCAuxEntArray& subents) const;
  ///<summary>This member function is used for easier evaluation of the standard support. It is protected 
  ///and may be used from inherited classes only.</summary>
  void getSubEntsRow(const CStringArray& dataAr,
                     const AcmCPartList* pSymb,
                     Adesk::Boolean forData,
                     AcmCAuxEntArray& subents,
                     AcDbExtents &geomExtend,
                     int row) const; //PL-peck
  ///<summary>This member function is protected. It is called from getSubEnts, in case the parts list is 
  ///based on the custom block scheme.</summary>
  void getSubEntsBlock(const AcmCPartList*, AcmCAuxEntArray&) const; 


  AcmBOMStd* mpOwner;
  AcmCPartListStdImp *mpImp;
};


///<summary>This sub-symbol does not have an extended interface implemented. It is inherited from AcmCSubSymbol.</summary>
class ACMSYMBB_CRX_DLLSHARE AcmCPartList : public AcmCSubSymbol
{

protected:
  AcmCPartList() {}

public:
  AcmCPartList(AcmPartList* pSym);
  virtual ~AcmCPartList();

  virtual AcmCPartList* clone()const;
  virtual void clear();

  AcmCPartListImp* getImp() const { return mpImp; }

  ///<summary>Gets the associated BOM Id.</summary>
  virtual AcDbObjectId bomId() const;
  ///<summary>Sets the associated BOM Id.</summary>
  virtual void setBomId(const AcDbObjectId& bomId);
  ///<summary>Returns the setting for heading.</summary>
  virtual bool isHeadingEnabled() const;
  ///<summary>Sets the setting for heading.</summary>
  virtual void setIsHeadingEnabled(bool isUse);
  ///<summary>Returns the visibility of the grip frame.</summary>
  virtual bool isGripFrameEnabled() const;
  ///<summary>Sets the visibility of the grip frame.</summary>
  virtual void setIsGripFrameEnabled(bool isUse);
  ///<summary>Returns the visibility of the result bar for the current parts list.</summary>
  virtual bool isResultBarEnabled() const;
  ///<summary>Sets the visibility of the result bar for the current parts list.</summary>
  virtual void setIsResultBarEnabled(bool isUse);
  ///<summary>Returns the visibility of the formula bar for the parts list. This is persistent data.</summary>
  virtual bool isFormulaBarEnabled() const;
  ///<summary>Sets the visibility of the formula bar for the parts list. This is persistent data.</summary>
  virtual void setIsFormulaBarEnabled(bool isUse);
  ///<summary>Gets the attachment point type.</summary>
  virtual AcmCPartListStd::AttachmentPoint attachPoint() const;
  ///<summary>Sets the attachment point type.</summary>
  ///<param name="aPoint">Input Only, specify the attachment point type.</param>
  virtual Acm::ErrorStatus setAttachPoint(AcmCPartListStd::AttachmentPoint aPoint);
  ///<summary>Gets the default parts list width.</summary>
  virtual double width() const;
  ///<summary>Sets default parts list width.</summary>
  virtual void setWidth(double width);
  ///<summary>Gets the default parts list height.</summary>
  virtual double height() const;
  ///<summary>Sets default parts list height.</summary>
  virtual void setHeight(double height);
  ///<summary>Gets the setting for title.</summary>
  virtual int title() const;
  ///<summary>Sets the setting for title.</summary>
  virtual void setTitle(const int title);
  ///<summary>Returns the title text, typically used as the parts list name.</summary>
  virtual LPCTSTR titleText() const;
  ///<summary>Sets the title text, typically used as the parts list name.</summary>
  virtual void setTitleText(const LPCTSTR titleText);

  ///<summary>Gets whether to use word wrap.</summary>
  ///<param name="enText">Indicates the text type information to retrieve. Default is to retrieve the data
  ///text information.</param>
  virtual 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>
  virtual void setOverFlow(const int overflow, AcmCPartListStd::TextType enText = AcmCPartListStd::kAll); 
  
  virtual int textInOneLine(AcmCPartListStd::TextType enText = AcmCPartListStd::kData) const;

  ///<param name="enText">Indicates the text type information to set. Default is to set both the header and
  ///data text information.</param>
  virtual void setTextInOneLine(const int textiol, AcmCPartListStd::TextType enText = AcmCPartListStd::kAll);

  ///<summary>Retrieves the Parts List heading and row text controls.</summary>
  ///<param name="enText">Input parameter. Specifies whether the heading or the row text control is retrieved.
  ///Input parameter. Refer to the AcmCPartListStd::TextType enumerated type for the available text types.
  ///Input parameter. 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>
  virtual AcmCPartListStd::TextControl textControl(AcmCPartListStd::TextType enText) const;

  ///<summary>Sets the Parts List heading and row text controls.</summary>
  ///<param name="enControl ">Input parameter. Specifies the text control to set. 
  ///Refer to the AcmCPartListStd::TextControl enumerated type for the available text controls.</param>
  ///<param name="enText">Input parameter. 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>
  virtual void setTextControl(AcmCPartListStd::TextControl enControl, AcmCPartListStd::TextType enText);

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

  ///<summary>Gets a list of AcDbBlockTableRecords objects, which are used to display the part list.</summary>
  virtual bool getCustomBlockIds(AcDbObjectIdArray&) const;
  ///<summary>Sets the name of the scheme being used to display the parts list.</summary>
  virtual bool setCustomBlock(LPCTSTR blName);
  ///<summary>Gets the name of the custom block scheme.</summary>
  virtual LPCTSTR customBlock() const;
  ///<summary>Sets the switch that determines whether to display blocks that do not contain any evaluated value.</summary>
  virtual void setFilterEmpty(bool useFilter);
  ///<summary>Gets the switch that determines whether to display blocks that do not contain any evaluated value.</summary>
  virtual bool filterEmpty() const;
  ///<summary>Sets the name of the DSK mask file, which may be used for evaluating.</summary>
  virtual bool setDSKName(LPCTSTR blName);
  ///<summary>Gets the name of the DSK mask file, which may be used for evaluating.</summary>
  virtual LPCTSTR dskName() const;

  ///<summary>Creates a filter of a specified type and adds it to the Parts List.</summary>
  ///<param name="filt">Input parameter.</param>
  ///<param name="oId">Output parameter. Returns the object ID of the filter object if successfully created and added.</param>
  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">Input parameter. Specifies the filter type to create and add to the Parts List.</param>
  ///<param name="oId">Output parameter. Returns the object ID of the filter object if successfully created and added.</param>
  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>Gets the values from the result bar.</summary>
  virtual Acm::ErrorStatus getValue(LPCTSTR valueName, CString& value) const;
  ///<summary>Sets the values from the result bar.</summary>
  virtual Acm::ErrorStatus setValue(LPCTSTR valueName, LPCTSTR value);
  ///<summary>Indicates if the Parts List column splitting is enabled.</summary>
  virtual 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>
  virtual void setColumnSplitEnable(bool bEnable);
  ///<summary>Retrieves the Parts List column split wrap.</summary>
  virtual AcmCPartListStd::ColumnSplitWrap  columnSplitWrap() const;
  virtual void                              setColumnSplitWrap(AcmCPartListStd::ColumnSplitWrap enWrap);
  ///<summary>Retrieves the Parts List column splitting style.</summary>
  virtual AcmCPartListStd::ColumnSplitStyle columnSplitStyle() const;
  ///<summary>Sets the Parts List column splitting style.</summary>
  ///<param name="enStyle">Indicates the column split style to set.</param>
  virtual void                              setColumnSplitStyle(AcmCPartListStd::ColumnSplitStyle enStyle);
  ///<summary>Retrieves the Parts List column split rows.</summary>
  virtual int  columnSplitRows() const;
  ///<summary>Sets the Parts List column split rows.</summary>
  ///<param name="nRows">Indicates the column split rows to set.</param>
  virtual void setColumnSplitRows(int nRows);
  ///<summary>Retrieves the Parts List column split sections.</summary>
  virtual int  columnSplitSections() const;
  ///<summary>Sets the Parts List column split sections.</summary>
  ///<param name="nSections">Indicates the column split sections to set.</param>
  virtual void setColumnSplitSections(int nSections);

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

  ///<summary>This new member function returns the Id of the title block which the partlist wrapped.</summary>
  virtual 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>
  virtual void setTitleId(const AcDbObjectId& titleId) ;

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

  ///<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>
  virtual Acm::ErrorStatus setWrapPListAttachPoint();

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

  virtual AcGePoint3d origin() const override;
  ///<summary>Sets the origin of the symbol in WCS.</summary>
  virtual void setOrigin(const AcGePoint3d& origin) override;
  ///<summary>Gets the value of any symbol variable.</summary>
  virtual LPCTSTR value(Acm::Variable var) const override;
  ///<summary>Gets the value of any symbol variable.</summary>
  virtual Acm::ErrorStatus getValue(Acm::Variable var, CString& value) const override;
  ///<summary>Sets the value of any symbol variable.</summary>
  virtual Acm::ErrorStatus setValue(Acm::Variable var, LPCTSTR value) override;
  ///<summary>Gets the visibility status of the editing controls.</summary>
  virtual Acm::Visibility  variableStatus(Acm::Variable var) const override;
  ///<summary>Sets the visibility status of the editing controls.</summary>
  virtual Acm::ErrorStatus setVariableStatus(Acm::Variable var, Acm::Visibility status) override;
  ///<summary>Gets the variable support data, such as the help index, dialog index, tooltip string, and label string.</summary>
  virtual Acm::ErrorStatus getVarDlgInfo(Acm::Variable var, CVarDlgInfo& v) const override;
  ///<summary>Sets the variable support data, such as the help index, dialog index, tooltip string, and label string.</summary>
  virtual Acm::ErrorStatus setVarDlgInfo(Acm::Variable var, const CVarDlgInfo& v) override;


  virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler* filer, Adesk::UInt16 ver) override;
  virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* filer) const override;

  Acad::ErrorStatus varInFields(const AcmVariant* pVar, AcRxObject* pFiler = nullptr) override;
  Acad::ErrorStatus varOutFields(AcmVariant* pVar, AcRxObject* pFiler = nullptr) const override;


  virtual Acad::ErrorStatus dxfInFields(AcDbDxfFiler* filer) override;
  virtual Acad::ErrorStatus dxfOutFields(AcDbDxfFiler* filer) const override;

  protected:
      AcmCPartListImp* mpImp{ nullptr };

};

class ACMSYMBB_CRX_DLLSHARE AcmCPartListRange : public AcmCPartList
{
public:
    AcmCPartListRange(AcmPartList* pSym);
};

class ACMSYMBB_CRX_DLLSHARE AcmCPartListArray : public AcmCPartList
{
public:
    AcmCPartListArray(AcmPartList* pSym);
};

class ACMSYMBB_CRX_DLLSHARE AcmCPartListView : public AcmCPartList
{
public:
    AcmCPartListView(AcmPartList* pSym);
};

class ACMSYMBB_CRX_DLLSHARE AcmCPartListGOST : public AcmCPartList
{
public:
    AcmCPartListGOST(AcmPartList* pSym);
};

#endif // __BOMSTD_H
