//////////////////////////////////////////////////////////////////////////////
//
//  Copyright 2025 by Autodesk, Inc.  All rights reserved.
//
// This computer source code and related instructions and comments 
// are the unpublished confidential and proprietary information of 
// Autodesk, Inc. and are protected under applicable copyright and 
// trade secret law.  They may not be disclosed to, copied or used 
// by any third party without the prior written consent of Autodesk, Inc.
//
//////////////////////////////////////////////////////////////////////////////

#ifndef __SYMSTD_H
#define __SYMSTD_H

#ifndef __ACMDEF_H
	#error include 'acmdef.h' before including this file
#endif
#ifndef __CAUXENT_H
	#error include 'cauxent.h' before including this file
#endif

class AcmStandardImp;
class AcmCArrowService;
class AcmCLeaderNodeIterator;
class AcmSymbolStd;
class AcmCLeader;
class AcmSymbolStdImp;
class AcmValue;
class AcmValuesTable;
class AcmSymbol;
class AcmVariant;
class AcmCSubSymbolsListImp;
class AcmStdRev;
class AcmSymbolStdAgent;
class AcmStandardOptionCommand;

///<summary>This is the base class for all standard classes in AutoCAD/M. This class is a container, holding
///objects for all symbol-specific classes. There is two-way ownership between AcmStandard and each symbol 
///standard class. There are several classes contained in the AcmStandard class - AcmCArrowService classes and
///other symbol-related classes.</summary>
class ACMSYMBB_CRX_DLLSHARE AcmStandard : public AcDbObject
{
  friend class AcmSymbbInternals;

public:
  ACRX_DECLARE_MEMBERS(AcmStandard);
  ///<summary>Destructure the standard class.</summary>
  virtual ~AcmStandard();
  ///<summary>Gets the name of the standard saved in the drawing.</summary>
  LPCTSTR name() const;
  ///<summary>Sets a new name for the standard.</summary>
  Acm::ErrorStatus setName(LPCTSTR newName);
  ///<summary>Gets the original name of the standard.</summary>
  virtual LPCTSTR originalName() const;
  ///<summary>Gets the string to be used as the separator of the fractional part of the number.</summary>
  LPCTSTR separator() const;
  ///<summary>Sets the string to be used as the separator of the fractional part of the number.</summary>
  void setSeparator(LPCTSTR separator);
  ///<summary>Gets the scale for any newly created symbol.</summary>
  double scale() const;
  ///<summary>Sets the scale for any newly created symbol.</summary>
  void setScale(double scale);
  ///<summary>Gets the arrowhead scale.</summary>
  double arwScale() const;
  ///<summary>Sets the arrowhead scale.</summary>
  void setArwScale(double scale);
  ///<summary>Return the list of arrow sizes for the standard.</summary>
  ///<param name="lst">Array of arrow size for this standard.</param>
  virtual void getArrowSizeList(AcGeDoubleArray& lst) const;
  const AcCmColor & symbolTrueColor() const;
  void setSymbolTrueColor(const AcCmColor & color);  
  ///<summary>Gets the symbol color.</summary>
  Adesk::UInt16 symbolColor() const;
  ///<summary>Sets the symbol color.</summary>
  void setSymbolColor(Adesk::UInt16 color);

  ///LEAD/MSYM line properties</summary>
  const AcDbObjectId & symbolLT() const;
  void setSymbolLT(const AcDbObjectId& lineType);  
  const AcDb::LineWeight & symbolLW() const;
  void setSymbolLW(const AcDb::LineWeight& lineWgt);  
  const AcDbObjectId & leaderLT() const;
  void setLeaderLT(const AcDbObjectId& lineType);  
  const AcDb::LineWeight & leaderLW() const;
  void setLeaderLW(const AcDb::LineWeight& lineWgt);  
  bool isLgOff() const;
  const AcCmColor & leaderTrueColor() const;
  void setLeaderTrueColor(const AcCmColor & color);
  ///<summary>Gets the symbol color.</summary>
  Adesk::UInt16 leaderColor() const;
  ///<summary>Sets the leader color.</summary>
  void setLeaderColor(Adesk::UInt16 color);
  const AcCmColor & textTrueColor() const;
  void setTextTrueColor(const AcCmColor & color);
  ///<summary>Gets the color used to draw any text in the symbol.</summary>
  Adesk::UInt16 textColor() const;
  ///<summary>Sets the color used to draw any text in the symbol.</summary>
  void setTextColor(Adesk::UInt16 color);
  ///<summary>Gets the arrowhead type.</summary>
  Acm::ArrowType arrowType() const;
  ///<summary>Sets the arrowhead type.</summary>
  Adesk::Boolean setArrowType(Acm::ArrowType type);
  ///<summary>Gets the height of the text used in all symbols by default.</summary>
  double textHeight() const;
  ///<summary>Sets the height of the text used in all symbols by default.</summary>
  void setTextHeight(double);
  ///<summary>Returns a list of all supported text heights that conform to the standard setting.</summary>
  virtual void getTextHeightList(AcGeDoubleArray& lst) const;
  ///<summary>Returns the next text height value for the standard.</summary>
  double nextTextHeight() const;
  ///<summary>Gets the status of the standard, specifying whether the standard should be considered inch-based or
  ///metric-based.</summary>
  Adesk::Boolean isMetric() const;
  ///<summary>Sets the status of the standard, specifying whether the standard should be considered inch-based 
  ///or metric-based.</summary>
  Acm::ErrorStatus setIsMetric(Adesk::Boolean m);


  enum StringCase {
    kNoChange = 0,  // for most standards
    kAllUpperCase,  // for ANSI
    kFirstLetterUpperCase 
  };     // used for translating strings in various standards
  virtual StringCase supportedStringCase() const;
  ///<summary>Gets the list of all arrowheads or all standard-supported arrowheads.</summary>
  virtual Adesk::Boolean getArrowDesc(AcmCObjArray<AcmCArrowDesc>& list,
                                      Adesk::Boolean allSrv = Adesk::kTrue,
                                      Adesk::Boolean bDarkTheme = Adesk::kFalse) const;
  int getAcadArrowDescs(AcmCObjArray<AcmCArrowDesc>& list, Adesk::Boolean bDarkTheme = Adesk::kFalse) const;
  ///<summary>Obtains the arrow service object.</summary>
  AcmCArrowService* getArrowService(Acm::ArrowType type) const;
  ///<summary>Gets the name of this text style.</summary>
  LPCTSTR textStyleName() const;
  ///<summary>Sets the name of this text style.</summary>
  Acad::ErrorStatus setTextStyleName(LPCTSTR pName);
  ///<summary>Gets the AcDbObjectId of text style used to draw all text in the each symbol by default.</summary>
  AcDbObjectId textStyleId() const;
  ///<summary>Sets the AcDbObjectId of text style used to draw all text in the each symbol by default.</summary>
  void setTextStyleId(const AcDbObjectId& id);
  void getMTextProperties(AcDbMText& text) const;

private:
    //////////////////////////////////////////////////////////////////////////
    // Deprecated methods that will be removed from SDK API.
    // Now we let them as private methods

      ///<summary>Adds support for a new symbol.</summary>
      ///<param name="parentClassName">Specifies the class name to be used to find common classes for all supporting 
      ///symbol standards. For example, for the welding standard, the parameter is "AcmWeldingStd." If the same class 
      ///descriptor has already been added, this function returns the error code eDuplicateEntry.</param>
      Acad::ErrorStatus newSymbolSupport(LPCTSTR baseClassName);

      ///<summary>Adds a new symbol standard.</summary>
      Acad::ErrorStatus addSymbolStd(AcmSymbolStd* pStd,
                                     AcDbObjectId& symbolStdId,
                                     Adesk::Boolean setCurrent = Adesk::kTrue);
      Acad::ErrorStatus addSymbolStd(AcmSymbolStd* pStd,                            //New RevSys
                                     const ACHAR* revClassName,
                                     AcDbObjectId& symbolStdId,
                                     Adesk::Boolean setCurrent = Adesk::kTrue);
   //////////////////////////////////////////////////////////////////////////
public:
  Acad::ErrorStatus addSymbolStdAgent(AcmSymbolStd* pStd,
                                      AcDbObjectId& stdAgentId,
                                      Adesk::Boolean setCurrent = Adesk::kTrue);
  Acad::ErrorStatus addSymbolStdAgent(AcmSymbolStd* pStd,                       //New RevSys
                                      const ACHAR* revClassName,
                                      AcDbObjectId& stdAgentId,
                                      Adesk::Boolean setCurrent = Adesk::kTrue);
  Acad::ErrorStatus addAgent(AcmSymbolStdAgent* pAgent,                   //New RevSys
                             const ACHAR* baseClassName,
                             Adesk::Boolean setCurrent = Adesk::kTrue);

  Acad::ErrorStatus cloneSymbolStdAgent(const AcDbObjectId& oldStdAgentId,
                                        AcDbObjectId&  newStdAgentId,
                                        Adesk::Boolean setCurrent = Adesk::kTrue);

  ///<summary>Gets the standard which is going to be the default for newly created symbols, used by the standard
  ///preference dialog.</summary>
  Acm::ErrorStatus getCurrentSymbolStd(LPCTSTR className,
                                       AcDbObjectId& symbolStdId) const;
  Acad::ErrorStatus getCurrentStdAgent(LPCTSTR className,
                                      AcDbObjectId& stdAgentId) const;

  ///<summary>Sets the standard which is going to be the default for newly created symbols, used by the standard
  ///preference dialog.</summary>
  ///<param name="className">It must be the same as the one used to add symbol support.symbolStdId :</param>
  Acm::ErrorStatus setCurrentSymbolStd(const AcDbObjectId& symbolStdId);
  Acad::ErrorStatus setCurrentStdAgent(const AcDbObjectId& stdAgentId);

  ///<summary>Returns the list of all current symbol standards.</summary>
  Acm::ErrorStatus getCurrentStandards(AcDbObjectIdArray& idArray) const;

  ///<summary>Fills names with the list of all base class names of symbol standards, which are currently registered
  ///with the standard. For example it will contain "AcmWeldStd", "AcmSurfTextStd".</summary>
  Acm::ErrorStatus getAllSymbolSupport(CStringArray& names) const;

  ///<summary>Fills idArray with the list of all registered symbol standards. It may contain more items than the 
  ///currently existing symbol set because some of the symbols may have registered multiple standard supports.</summary>
  Acm::ErrorStatus getAllSymbolStd(AcDbObjectIdArray& idArray) const;

  ///<summary>Erases the symbol standard and if it was the last support. I will also remove the symbol support 
  ///itself so the symbol will not be no longer instantiable.</summary>
  Acm::ErrorStatus removeSymbolStd(const AcDbObjectId& stdId);

  ///<summary>Erases the list of unreferenced symbol standards.
  /// Note: Symbol will no longer be instantiable if symbol standard revision list is empty.</summary>
  Acm::ErrorStatus removeSymbolsStd(const AcDbObjectIdArray& stdIds);

  ///<summary>Erases the list of agents and coresponding symbol standards. 
  /// We do not check if the objects for deleting are referenced or no
  /// Note: Symbol will no longer be instantiable if symbol standard revision list is empty.</summary>
  Acm::ErrorStatus removeAgents(const AcDbObjectIdArray& agentIds, bool bForceRemove = true);

  ///<summary>Erases the list of agents and also erase agent objects
  /// This is operation only for downgrade save to version where the system of standard agents is not exist.
  /// Note: References on the symbol standard will be available only for the downgrade save process.
  /// Any other access to the symbol standards will be prohibited.</summary>
  Acm::ErrorStatus removeAgents(); ///do not use it  - internal functionality

  ///<summary>Checks whether the symbol standard revision can be erased from database. Function return Acm::eOk if
  ///the symbol can be erased using 'removeSymbolStd' method, Acm::eStandardIsReferenced when symbol
  ///is being referenced or other error code.</summary>
  Acm::ErrorStatus isSymbolStdEraseable(const AcDbObjectId& stdId) const;
  ///<summary>Checks whether the whole symbol standard can be erased from database. Function return Acm::eOk if
  ///the symbol can be erased using 'removeSymbolStd' method, Acm::eStandardIsReferenced when symbol
  ///is being referenced or other error code.</summary>
  Acm::ErrorStatus isSymbolStdEraseable(LPCTSTR className) const;

  ///<summary>Gets a list of standards, which can be servers.</summary>
  ///<param name="className">Specifies the name of the class from which the standard should be inherited. It 
  ///must be the same as the one used to add symbol support. If the className is NULL, then all symbol 
  ///standards will be returned.symbolStdId :</param>
  Acm::ErrorStatus getSymbolStd(LPCTSTR className, AcDbObjectIdArray& idStdArray) const;

  ///<summary>Gets a list of symbol standard agent , which can be servers.</summary>
///<param name="className">Specifies the name of the class from which the standard should be inherited. It 
///must be the same as the one used to add symbol support. If the className is NULL, then all symbol 
///standards agent will be returned.symbolStdId :</param>
  Acm::ErrorStatus getAgents(LPCTSTR className, AcDbObjectIdArray& idAgentArray) const;

  ///<summary>Gets the specified symbol standard by its exact class name.</summary>
  ///<param name="className">Specifies the symbol standard class name.</param>
  ///<param name="symStdId">Return the symbol standard id if found.</param>
  Acm::ErrorStatus getSymbolStd(LPCTSTR className, AcDbObjectId& symStdId) const;

  ///<summary>This is the main interface to leader support. It is the way that the standard supplies leader graphics.</summary>
  virtual void getSubEnts(const AcmCLeader* pLeader, 
    AcmCAuxEntArray& entArray, Adesk::Boolean cutLastLines =Adesk::kTrue) const;
  ///<summary>This function initializes the internal structure of the standard.</summary>
  virtual Adesk::Boolean acmInit();
  void initToEditOriginal() const;
  void initToEdit() const;
  ///<summary>This function is used to initialize the standard.</summary>
  virtual Adesk::Boolean setFactoryDefaults();
  virtual Adesk::Boolean setDimDefaults();
  ///<summary>Gets the visibility status of metric-based or inch-based controls on the general page.</summary>
  virtual Acm::Visibility statusIsMetric() const;
  ///<summary>Get the visibility status of text style controls on the general page.</summary>
  virtual Acm::Visibility statusTextStyle() const;
  ///<summary>Get the visibility status of text height controls on the general page.</summary>
  virtual Acm::Visibility statusTextHeight() const;
  ///<summary>Returns True if the standard isn't a user standard.</summary>
  virtual Adesk::Boolean  isOriginal() const;
  ///<summary>Gets the projection type used for creating drawing views.</summary>
  Acm::ProjectionType projectionType() const;
  void setProjectionType(Acm::ProjectionType);
  ///<summary>Gets the attachment type for several lists: parts lists, revision lists, hole charts, and so on.</summary>
  Acm::ListInsertionPoint listInsertPoint() const;
  ///<summary>Controls the attachment type for several lists: parts lists, revision lists, hole charts, and so on.</summary>
  void setListInsertPoint(Acm::ListInsertionPoint);
  virtual Acad::ErrorStatus decomposeForSave(AcDb::AcDbDwgVersion ver,
                                              AcDbObject*& replaceObj,
                                              AcDbObjectId& replaceId,
                                              Adesk::Boolean& exchangeXData);
  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 subErase(Adesk::Boolean erasing);
  ///<summary>Overridden virtual function necessary to properly support AutoCAD's swapIdWith.</summary>
  virtual Acad::ErrorStatus subSwapIdWith(AcDbObjectId otherId,
                                          Adesk::Boolean swapXdata = false,
                                          Adesk::Boolean swapExtDict = false);
  ///<summary>Replaces one standard with another.</summary>
  Acad::ErrorStatus replaceWith(AcDbObjectId otherStdId);
  bool              useDimStyle() const;       // Just returns a bool if the dimstyle link is active
  AcDbObjectId      dimStyleId() const;
  CString           dimStyleName() const;
  Acad::ErrorStatus setDimStyleName(CString pName);
  AcDbObjectId      arrowBlock() const; 
  void              setArrowBlock(const AcDbObjectId& id);
  void              setDimStyleMode(Acm::DimStyleMode mode);
  Acm::DimStyleMode dimStyleMode() const;
  bool              arrowTypeVaries() const;
  bool              dimColorVaries() const;
  void              updateFromDimStyle();
  void              updateSubStandardsFromDimStyle();
  void              synchronizeDimstyles();
  AcDbObjectIdArray getAssociatedDimstyles() const;

  virtual void modified(const AcDbObject* pObj);
  virtual void objectClosed(const AcDbObjectId objId);
  
  Acad::ErrorStatus getAgentForStd(const AcDbObjectId& stdId, AcDbObjectId& agetId) const;

  virtual Acad::ErrorStatus registerSymbolStd(AcmSymbolStd* pSymStd, const ACHAR* className,
                                              Adesk::Boolean setCurrent = Adesk::kTrue,
                                              Adesk::Boolean bAddToTrans = Adesk::kTrue,
                                              Adesk::Boolean bForceAdd = Adesk::kFalse);

  virtual Acad::ErrorStatus registerSymbolRev(AcmSymbolStd* pSymStd, const ACHAR* revClassName,
                                              Adesk::Boolean setCurrent = Adesk::kTrue,
                                              Adesk::Boolean bAddToTrans = Adesk::kTrue,
                                              Adesk::Boolean bForceAdd = Adesk::kFalse);

  virtual Acad::ErrorStatus registerSymbolRev(const ACHAR* revClassName,
                                              Adesk::Boolean setCurrent = Adesk::kTrue,
                                              Adesk::Boolean bAddToTrans = Adesk::kTrue,
                                              Adesk::Boolean bForceAdd = Adesk::kFalse);

  virtual Acad::ErrorStatus convertForSave(AcDb::AcDbDwgVersion ver);

  //helper functions

  static bool getBaseClassName(const AcRxClass* pClass, AcString& className);
  static Acad::ErrorStatus createNewStandardRevision(AcmStandard* pStd,
                                                     const ACHAR* revClassName,
                                                     AcDbObjectId& revObjId,
                                                     Adesk::Boolean setCurrent = Adesk::kTrue,
                                                     Adesk::Boolean bAddToTrans = Adesk::kTrue,
                                                     Adesk::Boolean bForceAdd = Adesk::kFalse);
protected:
  AcmStandardImp*  mpImp;
  ///<summary>Constructs the standard class. The constructor is protected.</summary>
  AcmStandard();
  ///<summary>This member function returns the class version, which is used to identify the versions of loaded classes.</summary>
  Adesk::UInt16  classVersion() const;
  ///<summary>Registers the service with the current standard.</summary>
  Adesk::Boolean registerArrowService(AcmCArrowService* pNewSrv);
  Adesk::Boolean registerUserArrowService(AcmCArrowService* pNewSrv);
  Adesk::Boolean registerAutocadArrowService(AcmCArrowService* pNewSrv);
  ///<summary>Sets the the unit of the standard, dependent on whether the standard is inch-based or metric-based.</summary>
  virtual Acm::ErrorStatus onChangeUnits(Adesk::Boolean isMetric);
  ///<summary>Constructs arrow services objects.</summary>
  virtual void   initArrowServices();
  void walkThroughLeaderSeg(const AcmCLeaderNodeIterator* pIter,
                            AcmCAuxEntArray& entArray,
                            const AcmCLeader* pLeader,
                            Adesk::Boolean cutLastLines =Adesk::kTrue, bool makeNdd = false) const;
  void makeArrowHeadAndCutLines(const AcmCLeader* pLeader, Adesk::Boolean cutLastLines, AcmCAuxEntArray&) const;
  void makeNDD(const AcmCLeader* pLeader, AcmCAuxEntArray&) const;
  virtual Acad::ErrorStatus   subGetClassID(CLSID* pClsid) const;
  virtual Acad::ErrorStatus subDeepClone(AcDbObject*    pOwnerObject,
                                      AcDbObject*&   pClonedObject,
                                      AcDbIdMapping& idMap,
                                      Adesk::Boolean isPrimary = Adesk::kTrue) const;
  virtual Acad::ErrorStatus subWblockClone(AcRxObject* pOwnerObject,
                                        AcDbObject*& pClonedObject,
                                        AcDbIdMapping& idMap,
                                        Adesk::Boolean isPrimary = Adesk::kTrue) const;

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

DBREF_DECLARE(AcmStandard);

// Macros to define the default operator new/delete for ACDB_DECLARE_MEMBERS
#define ACM_DEFINE_HEAP_OPERATORS_DEFAULT(CLASS) \
void* CLASS::operator new(std::size_t sz) { \
    return ::operator new(sz); \
} \
void CLASS::operator delete(void* p) { \
    ::operator delete(p); \
}

///<summary>This class defines the common interface for any symbol standard. All its virtual member functions 
///need to be overloaded to produce symbol-specific behavior. This class is not instantiable.</summary>
class ACMSYMBB_CRX_DLLSHARE AcmSymbolStd : public AcDbObject
{
  friend class AcmSymbbInternals;
  friend class AcmStdRev;
  friend class AcmSymbolStdAgent;

protected:
  AcmSymbolStd (AcmSymbolStdImp* pImpObj);

public:
  ACRX_DECLARE_MEMBERS(AcmSymbolStd);
  ///<summary>Destructure the symbol standard class.</summary>
  virtual ~AcmSymbolStd();

  AcDbObjectId standardId() const;
  AcDbObjectId agentId() const;

  ///<summary>This class implementation doesn't do anything and returns eNotImplemented if it is not overloaded 
  ///in the child class.</summary>
  virtual Acm::ErrorStatus cInit();
  virtual Acm::ErrorStatus getDescription(CString& desc,
                                          CBitmap*& pBmpLoaded,
                                          CBitmap*& pBmpReg,
                                          Adesk::Boolean& enablePref) const;
  virtual Acm::ErrorStatus getCLIDesc(AcString& desc,
                                      AcString& keyword,
                                      Adesk::Boolean& enablePref) const;
  virtual Adesk::Boolean getPrefDefault() const {return Adesk::kTrue;}
  ///<summary>Gets the information about the standard name and revision.</summary>
  virtual Acm::ErrorStatus getRevision(CString& rev, Adesk::UInt16& year) const;
  ///<summary>Gets the name to be displayed in UI.information Default implementation is using string
  /// returned by 'getRevision'.</summary>
  virtual Acm::ErrorStatus getDisplayName(CString& rev) const;
  virtual const ACHAR* getBaseSymStdClassName() const;
  ///<summary>Sets the factory default values.</summary>
  virtual Adesk::Boolean   setFactoryDefaults();
  ///<summary>Provides the basic interface for the AcmStandardManager and hence determines whether AcmSymbolSTD 
  ///can be used for a particular standard.</summary>
  virtual Adesk::Boolean   isCompatibleTo(const AcmStandard* pStd) const;
  ///<summary>Returns true if the symbol standard is created for a particular draft standard.</summary>
  ///<param name="pStd">The draft standard.</param>
  virtual Adesk::Boolean   isCreatedFor(const AcmStandard* pStd) const;
  virtual void initToEdit() const;
  virtual void initToEditOriginal() const;
  ///<summary>Creates tree items, which are then used to initialize the user interface for editing this object. 
  ///The object returned is then asked to provide services.</summary>
  virtual Adesk::Boolean getTreeItems(AcmCObjPtrArray<CSymStdTreeItemDesc>& descArray) const;
  ///<summary>Provides access to the parent standard.</summary>
  AcmStandard* standard(AcDb::OpenMode mode = AcDb::kForRead) const;
  const AcmStandard* constStandard() 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;
  ///<summary>Set default values for text height, text color, arrow size, arrow type and leader color to the same
  ///as that in master standard.</summary>
  virtual void setDefaultTextLeader();
  virtual double textHeight() const;
  virtual void setTextHeight(double txtHeight);
  ///<summary>Retrieves the by standard state for the corresponding property.</summary>
  virtual bool textHeightByStandard() const;
  ///<summary>Sets the by standard state for the corresponding property.</summary>
  ///<param name="byStandard">New state to set to.</param>
  virtual void setTextHeightByStandard(bool byStandard);
  ///<summary>Returns the value of the text height associated to the by standard state for this symbol std.</summary>
  virtual double byStdTextHeight() const;
  virtual const AcCmColor & textTrueColor() const;
  virtual void setTextTrueColor(const AcCmColor & color);    
  ///<summary>Retrieves the by standard state for the corresponding property.</summary>
  virtual bool textColorByStandard() const;
  ///<summary>Sets the by standard state for the corresponding property.</summary>
  ///<param name="byStandard">New state to set to.</param>
  virtual void setTextColorByStandard(bool byStandard);
  ///<summary>Returns the text color associated to the by standard state for this symbol std.</summary>
  virtual const AcCmColor & byStdTextTrueColor() const;
  virtual double arwScale() const;
  virtual void setArwScale(double scale);
  virtual bool arwScaleByStandard() const;
  ///<summary>Sets the by standard state for the corresponding property.</summary>
  ///<param name="byStandard">New state to set to.</param>
  virtual void setArwScaleByStandard(bool byStandard);
  virtual Acm::ArrowType arrowType() const;
  virtual Adesk::Boolean setArrowType(Acm::ArrowType type);
  ///<summary>Retrieves the by standard state for the corresponding property.</summary>
  virtual bool arrowTypeByStandard() const;
  ///<summary>Sets the by standard state for the corresponding property.</summary>
  ///<param name="byStandard">New state to set to.</param>
  virtual void setArrowTypeByStandard(bool byStandard);
  ///<summary>Get the true color of leader in symbol that belongs to this symbol standard.</summary>
  virtual const AcCmColor & leaderTrueColor() const;
  ///<summary>Set the true color of leader in symbol that belongs to this symbol standard.</summary>
  virtual void setLeaderTrueColor(const AcCmColor & color);  
  ///<summary>Retrieves the by standard state for the corresponding property.</summary>
  virtual bool leaderColorByStandard() const;
  ///<summary>Sets the by standard state for the corresponding property.</summary>
  ///<param name="byStandard">New state to set to.</param>
  virtual void setLeaderColorByStandard(bool byStandard);
  ///<summary>Set height, color and text style of the specified text to that in the symbol standard.</summary>
  virtual void getMTextProperties(AcDbMText& text) const;
  ///<summary>Allows the SymStandard to override the default logic on when an item in the SymStandard dialog is 
  ///expandable. GOST uses this setting to allow the Edge SymStandards to be expanded even though none of the 
  ///optional standards are enabled by default.</summary>
  virtual bool isExpandable() const;
  virtual Adesk::Boolean getArrowDesc(AcmCObjArray<AcmCArrowDesc>& list,
                                      Adesk::Boolean allSrv = Adesk::kTrue,
                                      Adesk::Boolean bDarkTheme = Adesk::kFalse) const;
  ///<summary>Returns true if the text height associated to the by standard state for this symbol std is a size 
  ///up from the text height of the owning AcmStandard. Otherwise, returns false.</summary>
  virtual bool isHeightSizedUp() const;
  ///<summary>Returns true if the symbol standard is a custom standard. Otherwise, returns false.</summary>
  virtual bool isCustom() const;
  ///<summary>Method to query a symbol standard to find out if objects referencing
  ///that style should be updated</summary>
  virtual bool isModifiedForRecompute() const;

  ///<summary>Returns true if this symbol standard supports surface indication leader. 
  ///Otherwise, returns false.</summary>
  virtual Adesk::Boolean isSurfIndLeaderSupported() const;

  ///<summary>Gets the surface indication leader's arrow scale.</summary>
  virtual double surfIndLeaderArwScale() const;
  ///<summary>Sets the surface indication leader's arrow scale.</summary>
  ///<param name="scale">New arrow scale to set. It should be above zero.</param>
  virtual Acm::ErrorStatus  setSurfIndLeaderArwScale(double scale);
  ///<summary>Gets the surface indication leader's arrow scale ByStandard status.</summary>
  virtual Adesk::Boolean    surfIndLeaderArwScaleByStandard() const;
  ///<summary>Sets the surface indication leader's arrow scale ByStandard status.</summary>
  ///<param name="byStandard">New ByStandard state to set.</param>
  virtual Acm::ErrorStatus  setSurfIndLeaderArwScaleByStandard(Adesk::Boolean byStandard);
  ///<summary>Gets the surface indication leader's arrow type.</summary>
  virtual Acm::ArrowType    surfIndLeaderArwType() const;
  ///<summary>Sets the surface indication leader's arrow type.</summary>
  ///<param name="type">New arrow type to set.</param>
  virtual Acm::ErrorStatus  setSurfIndLeaderArwType(Acm::ArrowType type);
  ///<summary>Gets the surface indication leader's arrow type ByStandard status.</summary>
  virtual Adesk::Boolean    surfIndLeaderArwTypeByStandard() const;
  ///<summary>Sets the surface indication leader's arrow type ByStandard status.</summary>
  ///<param name="byStandard">New ByStandard state to set.</param>
  virtual Acm::ErrorStatus  setSurfIndLeaderArwTypeByStandard(Adesk::Boolean byStandard);

  virtual Adesk::Boolean setSurfIndLeaderFactoryDefaults();

  //////////////////////////////////////////////////////////////////////////
  // Symbol auto-incrementing label name interface

  /// <summary>
  /// Method returns state if the corresponding symbol of will support the Symbol counter mechanism.
  /// </summary>
  /// <returns>
  /// Return Adesk::kTrue if the Symbol counter mechanism is supported
  /// </returns>
  virtual Adesk::Boolean isSymbolCounterSupported() const;

  /// <summary>
  /// Gets string of characters that are to be excluded or invalid for the symbol identifier.
  /// </summary>
  ///<param name="value"> output parameter as AcString which contains excluded characters. The characters are separated by comma in the string.</param>
  /// <returns>
  /// Return Acme::eOk if the standard support this functionality
  /// </returns>
  virtual Acm::ErrorStatus getExcludeCharacters(AcString& value) const;

  /// <summary>
  /// Method generate the default name for symbol label according to counter.
  /// </summary>
  ///<param name="name"> output parameter as AcString for name. </param>
  ///<param name="count"> input parameter defines order number in the name generator counter. We generate the name according this number .</param>
  /// <returns>
  /// Return Acme::eOk if the standard support this functionality
  /// </returns>
  virtual Acm::ErrorStatus getDefaultName(AcString& name, int& count) const;

  enum DowngradeOperation {
      kExplode = 0,  // default
      kDowngradeRevision
  };

  /// <summary>
  /// Get the downgrade operation which is of eith kExplod or kDowngradeRevision
  /// </summary>
  ///<param name="ver"> input parameter defines the target saveas version</param>
  /// <returns>
  /// Return enum value of DowngradeOperation
  /// </returns>
  virtual DowngradeOperation getDowngradeOperation(int ver) const;


  /// <summary>
  /// Get the downgraded revision class name
  /// </summary>
  /// Return class name of the downgraded standard revision
  /// </returns>
  virtual AcString getDowngradeRevisionClassName() const;

  /// <summary>
  /// Return state if the revision is compatible with the given revision 
  /// </summary>
  ///<param name="className">class name of the previous revision</param>
  /// Return true if case if previous revision is compatible
  /// </returns>
  virtual Adesk::Boolean isCompatibleWith(const AcString className) const;


  //
  //////////////////////////////////////////////////////////////////////////
  virtual const ACHAR* getDefaultRevClassName() const;
  virtual const ACHAR* getBaseRevClassName() const;
  const AcString&  getRevClassName() const;
  const AcRxClass* getRevClass() const;

  Acad::ErrorStatus copyFrom(const AcRxObject* other) override;

  Acad::ErrorStatus setOwnerId(AcDbObjectId objId) override;
  virtual Acad::ErrorStatus setOldOwnerId(AcDbObjectId objId);

private:
  ///<summary>It is a override of the non virtual AcDbObject function. We want to prevent 
  ///that function will not called from outside</summary>
  AcDbObjectId      ownerId() const;

protected:
  ///<summary>Constructs the symbol standard class. The constructor is protected.</summary>
  AcmSymbolStd();

  virtual Acad::ErrorStatus setRevisionObj(const ACHAR* className);
  virtual Acad::ErrorStatus setRevisionObj(AcmStdRev* pRevObj);

  ///<summary>This is the object version. It is tested during opening and if the number is bigger than the version 
  ///defined by ACMSYMBB.ARX, the object is turned to a proxy. All commands will then stop working.</summary>
  Adesk::UInt16 classVersion() const;
  ///<summary>This member function is called on all symbol standards when their owner, the AcmStandard object, 
  ///changes units from millimeters to inches or vice versa.</summary>
  virtual Acm::ErrorStatus onChangeUnits(Adesk::Boolean isMetric);
  double getTextHeightValue() const;
  const AcCmColor& getTextTrueColorValue() const;
  Acm::ArrowType getArrowTypeValue() const;
  double getArwScaleValue() const;
  const AcCmColor& getLeaderTrueColorValue() const; 
  virtual Acad::ErrorStatus subDeepClone(AcDbObject*    pOwnerObject,
                                      AcDbObject*&   pClonedObject,
                                      AcDbIdMapping& idMap,
                                      Adesk::Boolean isPrimary = Adesk::kTrue) const;
  virtual Acad::ErrorStatus subWblockClone(AcRxObject* pOwnerObject,
                                        AcDbObject*& pClonedObject,
                                        AcDbIdMapping& idMap,
                                        Adesk::Boolean isPrimary = Adesk::kTrue) const;
  virtual Acad::ErrorStatus subGetClassID(CLSID* pClsid) const;
  ///<summary>Name returned by getRevision can't be used as section style name
  /// if it contains characters not allowed for dictionary entry key.
  /// This function should return name derived from revision name valid
  /// for section view style name.</summary> 
  virtual Acm::ErrorStatus getRevisionAsStyleName(CString& name) const;

  ///<summary>Function to return ids that should be checked using AcDbDatabase::purge 
  /// </summary> 
  virtual Acm::ErrorStatus getIdsForPurgeChecking (AcDbObjectIdArray &idArr) const;

  ///<summary>Returns true if there are no references to this symbol standard
  /// and can be erased from database.</summary>
  static Acm::ErrorStatus isEraseable (const AcDbObjectId symStdId);

  ///<summary>Returns revision name of symbol standard with respect to it
  /// master standard to include a prefix in case of custom master standard.</summary>
  Acm::ErrorStatus getRevisionWithRespectToMasterStd(CString &rev, Adesk::UInt16& year);

  AcmSymbolStdImp* getImpl() const { return mpSymStdImp; }
  AcmStdRev* getRevisionObj() const { return mpSymStdRev; }

protected:
    AcmSymbolStdImp* mpSymStdImp{ nullptr };
    AcmStdRev* mpSymStdRev{ nullptr };

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

DBREF_DECLARE(AcmSymbolStd);


///<summary>This class is an abstract class. It defines the common interface for each sub-symbol class, which 
///needs to be implemented to provide the same interface.</summary>
class AcmCSubSymbol
{
public:
  virtual ~AcmCSubSymbol();
  ///<summary>Gets the origin of the symbol in WCS.</summary>
  virtual AcGePoint3d origin() const = 0;
  ///<summary>Sets the origin of the symbol in WCS.</summary>
  virtual void setOrigin(const AcGePoint3d& origin) = 0;
  ///<summary>Gets the value of any symbol variable.</summary>
  virtual LPCTSTR value(Acm::Variable var) const = 0;
  ///<summary>Gets the value of any symbol variable.</summary>
  virtual Acm::ErrorStatus getValue(Acm::Variable var, CString& value) const = 0;
  ///<summary>Sets the value of any symbol variable.</summary>
  virtual Acm::ErrorStatus setValue(Acm::Variable var, LPCTSTR value) = 0;
  ///<summary>Gets the visibility status of the editing controls.</summary>
  virtual Acm::Visibility  variableStatus(Acm::Variable var) const = 0;
  ///<summary>Sets the visibility status of the editing controls.</summary>
  virtual Acm::ErrorStatus setVariableStatus(Acm::Variable var, Acm::Visibility status) = 0;
  ///<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 = 0;
  ///<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) = 0;


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

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


  virtual Acad::ErrorStatus dxfInFields(AcDbDxfFiler* filer) = 0;
  virtual Acad::ErrorStatus dxfOutFields(AcDbDxfFiler* filer) const = 0;
};

inline
AcmCSubSymbol::~AcmCSubSymbol()
{}

#include <map>
typedef std::map< Acm::Variable, std::tuple<AcmValue*, AcString, Adesk::UInt64, Adesk::UInt64>> PropertiesMap;

//////////////////////////////////////////////////////////////////////////
///<summary>This class is an abstract class - not instantiable. 
/// It defines the common interface for each sub-symbol list class, which 
///needs to be implemented to provide the same interface.</summary>
/// 
class ACMSYMBB_CRX_DLLSHARE AcmCSubSymbolsList : public AcmCObjArray<AcmCSubSymbol>
{
    friend class AcmCSubSymbolsListImp;
public:
    virtual ~AcmCSubSymbolsList();

    AcmCSubSymbolsListImp* getImp() const { return mpImp; };

protected:
    AcmCSubSymbolsList(AcmCSubSymbolsListImp*);
    //pure virtual interface
    ///<summary>...</summary>
    virtual Acm::ErrorStatus initPropertyMap();
    //AcmValue interface
    ///<summary>...</summary>
    virtual Acm::Visibility variableVisibility(const AcmValue* var) const;
    ///<summary>...</summary>
    virtual LPCTSTR getVariableValue(const AcmValue* pVar)const;
    virtual Acm::ErrorStatus setVariableValue(AcmValue* pVar, LPCTSTR value)const;

    virtual AcString loadString(unsigned int nId) const;

public:
    //////////////////////////////////////////////////////////////////////////
    //Interface for sub-symbols list - support for multi sub-symbols functionality

    ///<summary> Return state if the symbol supports multi sub-symbols description.</summary>
    ///<returns>true if the symbol supports the multi -sub-symbols.description</returns>
    virtual bool isSupportMultiSubSymbolDesc() const;

    ///<summary> The funtion checks if the given index in the array is valid and
    /// returns valid pointer to sub-symbol.</summary>
    ///<returns>true if index is valid and pointer is valid </returns>
    virtual bool isValidIndex(Adesk::UInt16 idx) const;

    ///<summary> The funtion returns pointer to active sub-symbol.</summary>
    ///<returns>AcmCSubSymbol* pointer on active sub-symbol object</returns>
    virtual const AcmCSubSymbol* activeSubSymbol() const;
    virtual AcmCSubSymbol* activeSubSymbol();

    ///<summary> The funtion returns pointer to sub-symbol.defined by index in the array</summary>
    /// The index is a standard zero base indexer. </summary>
    ///<returns>AcmCSubSymbol* pointer on active sub-symbol object</returns>
    virtual const AcmCSubSymbol* subSymbol(Adesk::UInt16 value) const;
    virtual AcmCSubSymbol* subSymbol(Adesk::UInt16 value);

    ///<summary> Funtion returns the active sub-symbol is an integer value as an index in the array. 
    /// The index is a standard zero base indexer. </summary>
    ///<returns>return value as index of active Sub-symbol</returns>
    virtual Adesk::UInt16 activeSubSymbolIdx() const;

    ///<summary> Funtion sets the active sub-symbol is an integer value as an index in the array. 
    /// The index is a standard zero base indexer. If the object doesn't support the multi sub-symbols 
    /// storage system then the setter return errors. </summary>
    ///<param name="value"> unsigned integer value as index of active sub-symbol in the array</param>
    ///<returns>Acad::ErrorStatus of operation. Aced::eOK if operation passed.</returns>
    virtual Acad::ErrorStatus setActiveSubSymbol(Adesk::UInt16 value) const;

    ///<summary> The funtion creates new default sub-symbol nd returns pointer on it. 
    /// Default implementation is empty and return zero pointer.</summary>
    ///<returns>AcmCSubSymbol* pointer on newly created sub-symbol object</returns>
    virtual AcmCSubSymbol* newSubSymbol(AcmSymbol* pSymbol) const;

    ///<summary> The function adds a given sub-symbol to the end of an array. 
    /// The operation doesn't affects the index of the active sub-symbol. 
    /// The default implementation of the base class simply add the sub-symbol to the end of an array.</summary>
    ///<param name="pSubSymbol"> AcmCSubSymbol pointer to the sub-symbol object</param>
    ///<returns>Acad::ErrorStatus of operation. Aced::eOK if operation passed.</returns>
    virtual Acad::ErrorStatus appendSubSymbol(AcmCSubSymbol* pSubSymbol);

    ///<summary> The function adds a new default sub-symbol to the end of an array. 
    /// The operation affects the index of the active sub-symbol. 
    /// New active sub-symbol will be actually added sub-symbol.
    /// The default implementation of the base class is empty and returns an error.</summary>
    ///<returns>Acad::ErrorStatus of operation. Aced::eOK if operation passed.</returns>
    virtual Acad::ErrorStatus appendSubSymbol(AcmSymbol* pSymbol);

    ///<summary> The function adds a new default sub-symbol to the given position in an array. 
    /// The operation affects the index of the active sub-symbol.
    /// New active sub-symbol will be actually added sub-symbol.</summary>
    ///<param name="index"> unsigned integer value as index to insert new sub-symbol </param>
    ///<returns>Acad::ErrorStatus of operation. Aced::eOK if operation passed.</returns>
    virtual Acad::ErrorStatus insertSubSymbol(Adesk::UInt16 index, AcmSymbol* pSymbol);

    ///<summary> The function adds a given sub-symbol to the given position in an array. </summary>
    ///<param name="index"> unsigned integer value as index to insert new sub-symbol </param>
    ///<param name="pSubSymbol"> AcmCSubSymbol pointer to the sub-symbol object</param>
    ///<returns>Acad::ErrorStatus of operation. Aced::eOK if operation passed.</returns>
    virtual Acad::ErrorStatus insertSubSymbol(Adesk::UInt16 index, AcmCSubSymbol* pSubSymbol);

    ///<summary> The function removes the sub-symbol for a given index from an array. 
    ///The operation affects the index of the active sub-symbol. 
    /// We have the following cases of how the index will be changed:
     /// 1. removed sub-symbol is an active sub-symbol then the new active sub-symbol will be the first 
    /// lower sub-symbol or next sub-symbol if the index of an active sub-symbol is zero
    /// 2. removed sub-symbol is not an active sub-symbol then we recalculate it to preserve the original active sub-symbol.
    /// The function creates one new default sub-symbol if it removes the last sub-symbol - One sub-symbol must exist! </summary>
    ///<param name="index"> unsigned integer value as index to removed sub-symbol </param>
    ///<returns>Acad::ErrorStatus of operation. Aced::eOK if operation passed.</returns>
    virtual Acad::ErrorStatus removeSubSymbol(Adesk::UInt16 index, bool bDelete = true);

    ///<summary> The function removes all sub-symbols</summary>
    ///<returns>Acad::ErrorStatus of operation. Aced::eOK if operation passed.</returns>
    virtual Acad::ErrorStatus removeAllSubSymbols();

    ///<summary> The function returns number of sub-symbols. </summary>
    ///<returns>number of sub-symbols as integer value </returns>
    virtual int numberOfSubSymbols() const;

    ///<summary> The function checks if we have one or more sub-symbols in the symbol</summary>
    ///<returns>true if symbol contains only one sub-symbol</returns>
    virtual bool hasOneSubSymbol() const;

    ///<summary> The function checks if sub-symbol lists are same</summary>
    ///<returns>true if lists are same</returns>
    virtual bool operator== (const AcmCSubSymbolsList&) const;

    /*///<summary> The function checks if input sub-symbol list is same as curren</summary>
    ///<returns>true if list are same</returns>
    virtual bool isEqual(const AcmCSubSymbolsList& desc) const;*/

    /// <summary>
    /// Function for copy content of the AcmCSubSymbolsList object from source to current object. 
    /// Function allow also the partial copping of the sub-symbol data
    /// </summary>
    /// <param name="pSource">source object for reading dada</param>
    /// <param name="bAllSubSymbol">switch if we want to copy all sub-symbol or one</param>
    /// <param name="idx">Index of sub-symbol which we wan to copy in case if the bAllSubSymbol is false</param>
    /// <returns>return state of copy operation</returns>
    virtual Acad::ErrorStatus copyFrom(const AcmCSubSymbolsList* pSource, bool bAllSubSymbol, Adesk::UInt16 idx = 0);

    /// <summary>
    /// The function copies only one sub-symbol defined by the input index from the source object.
    ///  It replaces data of the active sub-symbol in the target. 
    /// If the target doesn't contain any sub-symbol then it creates it.
    /// The function doesn't replace data of the symbol
    /// </summary>
    /// <param name="pSource">sourge object </param>
    /// <param name="idx">Index of sub-symbol which we wan to copy from source object</param>
    /// <returns>return state of copy operation</returns>
    virtual Acad::ErrorStatus copySubSymbolFrom(const AcmCSubSymbolsList* pSource, Adesk::UInt16 idx = 0);

    virtual Acad::ErrorStatus clear();

    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 void setVerSchema(Adesk::UInt16 ver) const;

    //////////////////////////////////////////////////////////////////////////
    //common interface for properties
    ///<summary>...</summary>
    virtual Acm::ErrorStatus buildKeywordsAndPrompt(std::vector<std::pair<AcString, AcString>>& output, bool applyVisibility = true) const;
    ///<summary>...</summary>
    virtual Acm::ErrorStatus getVarFromKeyword(const AcString& keyword, Adesk::UInt32& var) const;

    ///<summary>Returns list of properties registered in the sub-symbol</summary>
    virtual Acm::ErrorStatus getVarlist(std::vector< Acm::Variable >& varList) const;

    ///<summary>Gets the visibility of the editing controls.</summary>
    ///<param name="var">Available options include kAllAround, kMajorityAllowed, kDeviationsAllowed, kFitCircle, kForceTail, or kProdMultiLine.</param>
    virtual Acm::Visibility  variableStatus(Acm::Variable var) const;

    ///<summary>Sets the visibility status of the editing controls.</summary>
    virtual Acm::ErrorStatus setVariableStatus(Acm::Variable var, Acm::Visibility status);

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

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

    ///<summary>Sets the value of any symbol variable.</summary>
    virtual Acm::ErrorStatus setValue(Acm::Variable var, LPCTSTR value);

    ///<summary>Gets the variable value for weld.</summary>
    ///<param name="var">Var can have following values: Acm::WeldNotes, Acm::WeldSize, Acm::WeldThickness, 
    ///Acm::WeldLength, Acm::WeldNumber, Acm::WeldSpacing, Acm::WeldAngle, Acm::WeldDepth, Acm::WeldPitch, 
    ///Acm::WeldGap, Acm::WeldClearance, Acm::WeldBrazing, Acm::WeldFinishing, Acm::WeldContour.</param>
    virtual LPCTSTR propertyValue(Acm::Variable var) const;

    ///<summary>Returns the pointer on the AcmValue object which hold data of variable</summary>
    virtual const AcmValue* property(Acm::Variable var) const;
    virtual AcmValue* property(Acm::Variable var);

    ///<summary>Returns the pointer on the AcmValue object which hold data of variable</summary>
    virtual bool hasProperty(Acm::Variable var) const;


    ///<summary>...</summary>
    virtual Acm::ErrorStatus setPrompt(Acm::Variable var, Adesk::UInt64 id);
    ///<summary>...</summary>
    virtual Acm::ErrorStatus prompt(Acm::Variable var, AcString& prompt) const;
    ///<summary>...</summary>
    virtual Acm::ErrorStatus promptID(Acm::Variable var, Adesk::UInt64& id) const;

    ///<summary>...</summary>
    virtual Acm::ErrorStatus setMessage(Acm::Variable var, Adesk::UInt64 id);
    ///<summary>...</summary>
    virtual AcString message(Acm::Variable var) const;

    ///<summary>...</summary>
    virtual Acm::ErrorStatus setKeyword(Acm::Variable var, const AcString& keyword);
    ///<summary>...</summary>
    virtual Acm::ErrorStatus keyword(Acm::Variable var, AcString& keyword) const;

    ///<summary>...</summary>
    virtual Acm::ErrorStatus setUQPrompt(Acm::Variable var, Adesk::UInt64 id);
    ///<summary>...</summary>
    virtual Acm::ErrorStatus UQpromptID(Acm::Variable var, Adesk::UInt64& id) const;

protected:

    Adesk::UInt16 verSchema() const;

private:
    AcmCSubSymbolsListImp* mpImp;
};


//////////////////////////////////////////////////////////////////////////
///<summary>This is an abstract class. It defines the necessary interface for creating new arrowheads.</summary>
class ACMSYMBB_CRX_DLLSHARE AcmCArrowService
{
public:
  virtual ~AcmCArrowService();
  ///<summary>Gets the service internal identifier, for example Acm::kClosed30.</summary>
  virtual Acm::ArrowType  serviceType() const = 0;
  ///<summary>Gets the group of the arrowhead services.</summary>
  virtual Acm::ArrowGroup group() const = 0;
  ///<summary>Sets the group of the arrowhead services.</summary>
  virtual void setGroup(Acm::ArrowGroup group) = 0;
  ///<summary>Gets whether the arrow is hidden for the current standard.</summary>
  virtual Adesk::Boolean hidden() const = 0;
  ///<summary>Sets whether the arrow is hidden for the current standard.</summary>
  virtual void setHidden(Adesk::Boolean newVal) = 0;
  ///<summary>Returns the descriptor object.</summary>
  virtual AcmCArrowDesc* getDesc() = 0;
  ///<summary>Returns the descriptor object.</summary>
  virtual AcmCArrowDesc* getDarkThemeDesc() = 0;
  ///<summary>Draws entities and transforms them by the specified matrix.</summary>
  ///<param name="entArray">Input only. Specifies an array of auxiliary entities to draw and transform.</param>
  virtual void getSubEnts(AcmCAuxEntArray& entArray) const = 0;

  ///<summary>Creates a block from the arrow service.</summary>
  virtual AcDbObjectId makeBlock() const = 0;
  ///<summary>Find out the block name this arrow service represents.</summary>
  ///<param name="name">Output only. Returns the result of the search.</param>
  virtual Adesk::Boolean getBlockName(CString& name) const = 0;
  ///<summary>Draws entities and transforms them by the specified matrix.</summary>
  ///<param name="entArray">Input only. Specifies an array of auxiliary entities to draw and transform.</param>
  ///<param name="xform">Input only. Specifies the matrix to position the specified entities in the WCS.</param>
  virtual void getSubEnts(AcmCAuxEntArray& entArray, const AcGeMatrix3d& xform) const = 0;  
  ///<summary>Sets the direction of the arrow.</summary>
  ///<param name="dir">Input only. Specifies the direction for the arrow.</param>
  virtual void setArrowheadDir(const AcGeVector3d& dir) = 0;

  ///<summary>Sets the color of the arrow.</summary>
  ///<param name="color">Input only. Specifies the color for the arrow.</param>
  virtual void setArrowheadColor(const AcCmColor & color) = 0;

  ///<summary>Returns ID of bitmap used for arrow preview .</summary>
  virtual UINT bitmapID() const = 0;
  ///<summary>Returns resource handle that will be used to load bitmap for arrwo preview.</summary>
  virtual HINSTANCE resourceHandle () const = 0;
};

inline 
AcmCArrowService::~AcmCArrowService()
{}


#endif // __SYMSTD_H
