//////////////////////////////////////////////////////////////////////////////
//
//  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 __SECTIONSYM_H
#define __SECTIONSYM_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

#include "dbSectionViewStyle.h"
#include "symbol.h"

class AcmSymbolStd;
class AmdtSectionSymC;
class AmdtSectionSymCImp;
class AmdtSectionSymStdImp;
class AmdtSectionSymStdLegacyImp;
class AcDbSectionViewStyle;

#define SECTION_LABEL_FIRST ACRX_T(/*MSG0*/"SECTION_LABEL_FIRST")
#define SECTION_LABEL_LAST  ACRX_T(/*MSG0*/"SECTION_LABEL_LAST")

///<summary>The section symbol standard class. Declared with ACMSYMBB_CRX_DLLSHARE.</summary>
class ACMSYMBB_CRX_DLLSHARE AmdtSectionSymStd : public AcmSymbolStd
{
  friend class AcmSymbbInternals;
  friend class AmdtSectionSymStdImp;
  friend class AmdtSectionSymStdLegacyImp;
  friend class AmdtSectionStdPreKastlePostRestore1;
  friend class AmdtSectionStdPreKastlePostRestore2;
public:
  ACRX_DECLARE_MEMBERS(AmdtSectionSymStd);
  ///<summary>The class destructor.</summary>
  virtual ~AmdtSectionSymStd();

  enum LineVisibility {
    ///<summary>the whole cutting plane is marked with one linetype of one color.</summary>
    kContinuous = 0, // the whole cutting plane is marked with one linetype of one color
    ///<summary>only the breaks in cutting plane are marked</summary>
    kNoLines,       // only the breaks in cutting plane are marked
    ///<summary>the break have one linetype and color, the lines between them have diff. color</summary>
    kBetweenPlanes  // the break have one linetype and color, the lines between them have diff. color
  };

  const ACHAR* getBaseSymStdClassName() const override;

  ///<summary>Override the function to erase associated AcDbSectionViewStyle.</summary>
  Acad::ErrorStatus subErase (Adesk::Boolean isErasing); 

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

  void nextSectionNames(CStringArray& names, const int count) const;
  virtual CString defaultName(int count) const;

  //////////////////////////////////////////////////////////////////////////
  // Symbol auto-incrementing label name interface overrides
  Acm::ErrorStatus getDefaultName(AcString& name, int& count) const override;
  Adesk::Boolean isSymbolCounterSupported() const override;
  virtual Acm::ErrorStatus getExcludeCharacters(AcString& value) const override;
  //////////////////////////////////////////////////////////////////////////

  ///<summary>Returns the label pattern used by the section view.</summary>
  LPCTSTR labelPattern() const;
  ///<summary>Sets the label pattern used by the section view.</summary>
  ///<param name="labelPattern">string for the pattern of the view. 
  ///This string can be set using the constant strings, S
  ///ECTION_LABEL_FIRST and SECTION_LABEL_LAST, and enclosed with "(" and ")", 
  ///such as "=(SECTION_LABEL_FIRST)-(SECTION_LABEL_LAST)".</param>
  void setLabelPattern(const ACHAR* labelPattern);
  ///<summary>Returns visibility style of the section line. The return value can be kContinuous,kNoLines, kBetweenPlanes.</summary>
  LineVisibility lineVisibility() const;
  ///<summary>Sets visibility style of the section line.</summary>
  void setLineVisibility(const LineVisibility lineVis);
  ///<summary>Gets whether section view label is visible or hidden.</summary>
  Adesk::Boolean showAnnot() const;
  ///<summary>Determines whether section view label is visible or hidden.</summary>
  void setShowAnnot(const Adesk::Boolean v);
  ///<summary>Gets whether arrow is visible or hidden at the end of the section line.</summary>
  Adesk::Boolean showArrows() const;
  ///<summary>Determines whether arrow is visible or hide at the end of the section line.</summary>
  void setShowArrows(const Adesk::Boolean v);
  ///<summary>Gets the position of the label text to the view.</summary>
  Adesk::Boolean labelAbove() const;
  ///<summary>Sets the position of the label text to the view.</summary>
  void setLabelAbove(const Adesk::Boolean p);
  AcDbObjectId annotLineId() const;
  void setAnnotLineId(const AcDbObjectId& idType);

  ///<summary>Determines whether bend and end line type follows the standard.</summary>
  bool annotLineIdByStandard() const;
  void setAnnotLineIdByStandard(bool byStandard);

  LPCTSTR getAnnotLtypeName() const;
  Acad::ErrorStatus setAnnotLtypeName(LPCTSTR pName);
  AcDbObjectId textStyleId() const;
  void setTextStyleId(const AcDbObjectId& id);
  ///<summary>Retrieves the text style by standard state for the corresponding property.</summary>
  bool textStyleByStandard() const;
  ///<summary>Set the text style by standard state for the corresponding property.</summary>
  void setTextStyleByStandard(bool byStandard); 
  Adesk::UInt16 textColor() const;
  void setTextColor(Adesk::UInt16 color);  
  ///<summary>Gets whether annotation is to be showed at each vertex.</summary>
  Adesk::Boolean showPlaneNames() const;
  ///<summary>Determines whether annotation is to be showed at each vertex.</summary>
  void setShowPlaneNames(const Adesk::Boolean show);
  ///<summary>Returns the default line weight of section line.</summary>
  AcDb::LineWeight lineWeightOver() const;
  ///<summary>Sets the default line weight of section line.</summary>
  void setLineWeightOver(const AcDb::LineWeight weight);

  /// <summary>
  /// Gets if the lineweight of end and bend lines follow the lineweight of Section Line object in standard.
  /// </summary>
  ///
  /// <returns>
  /// Return true if lineweight follow the standard; otherwise, returns false.
  /// </returns>
  bool lineWeightOverByStandard() const;

  /// <summary>
  /// Sets if the lineweight of end and bend lines follow the lineweight of Section Line object in standard.
  /// </summary>
  ///
  /// <param name="byStandard">
  /// true if lineweight is to be set to the lineweight of Section Line object; false otherwise.
  /// </param>
  void setLineWeightOverByStandard(bool byStandard);

  ///<summary>Gets the true color of section line.</summary>
  const AcCmColor & lineTrueColorOver() const;
  ///<summary>Sets the true color of section line.</summary>
  void setLineTrueColorOver(const AcCmColor & color);  

  /// <summary>
  /// Gets if the color of end and bend lines follow the color of Section Line object in standard.
  /// </summary>
  ///
  /// <returns>
  /// Return true if color follow the standard; otherwise, returns false.
  /// </returns>
  bool lineColorOverByStandard() const;

  /// <summary>
  /// Sets if the color of end and bend lines follow the color of Section Line object in standard.
  /// </summary>
  ///
  /// <param name="byStandard">
  /// true if color is to be set to the color of Section Line object; false otherwise.
  /// </param>
  void setLineColorOverByStandard(bool byStandard);

  ///<summary>Gets the color of section line.</summary>
  Adesk::Int16 lineColorOver() const;
  ///<summary>Sets the color of section line.</summary>
  void setLineColorOver(const Adesk::Int16 color);
  ///<summary>Gets whether is to use continuous names for plane symbols.</summary>
  Adesk::Boolean multipleNamesSupported() const;
  ///<summary>Determines whether is to use continuous names for plane symbols.</summary>
  void setMultipleNamesSupported(const Adesk::Boolean multiNames);
  virtual void setTextHeight(double txtHeight);
  ///<summary>Sets the text height by standard state for the corresponding property.</summary>
  virtual void setTextHeightByStandard(bool byStandard);

  ///<summary>Gets whether arrow is drawn as pointing towards or away from the line.</summary>
  virtual bool arrowToLine() const;

  ///<summary>
  /// Sets the arrow direction.
  /// </summary>
  ///
  /// <param name="bValue">
  /// true when the arrow is drawn towards cutting plane and false when it is drawn away from cutting plane.
  /// </param>
  virtual void setArrowToLine(bool bValue);
  
  Adesk::Boolean getLineWeightDesc(AcmCObjArray<AcmCDesc>& list);
  
  void initToEdit()const override;
  void initToEditOriginal()const override;
  
  /// <summary>
  /// Sets the factory default values. This function will create associated AcDbSectionViewStyle if it is not created yet.
  /// DO NOT override this function.
  /// </summary>
  virtual Adesk::Boolean setFactoryDefaults();

  /// <summary>
  /// Sets the factory default values for the properties in the associated AcDbSectionViewStyle. 
  /// You should override this function for different default values.
  /// </summary>
  ///
  /// <returns>
  /// Return Adesk::kTrue if successful.
  /// </returns>
  virtual Adesk::Boolean subSetFactoryDefaults();
  
  /// <summary>
  /// Indicates whether properties in the associated AcDbSectionViewStyle are changed.
  /// </summary>
  ///
  /// <returns>
  /// Return true if properties are changed; otherwise, returns false.
  /// </returns>
  virtual bool isModifiedForRecompute() 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);
  virtual Acm::ErrorStatus getDescription(CString& desc,
                                          CBitmap*& pBmpLoaded,
                                          CBitmap*& pBmpReg,
                                          Adesk::Boolean& enablePref) const;

  ///<summary>This is record AmdtSectionSymStd::Variable.</summary>
  enum Variable {
    kLabelPattern = 0,
    kLabelAbove
  };
  virtual Acm::Visibility variableStatus(AmdtSectionSymStd::Variable var) const;
  virtual void setVariableStatus(AmdtSectionSymStd::Variable var, Acm::Visibility status) const;

  virtual void getSubEnts(const AmdtSectionSymC* pSymb,AcmCAuxEntArray& subents) const;
  virtual void getSubEntsEnt(const AmdtSectionSymC* pSymb,AcmCAuxEntArray& subents) const;
  virtual void resetAnnotOffsets(AmdtSectionSymC* pSymb, bool allOffsets = true) const;
  ///<summary>Returns whether 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.</summary>
  virtual bool isHeightSizedUp() const;

  double arrowLineLength() const;
  /// <summary>
  /// Sets the arrow line length.
  /// </summary>
  ///
  /// <param name="size">
  /// Value of the arrow line length.
  /// </param>
  /// <returns>
  /// Return Acad::eOk if Successful.
  /// </returns
  Acad::ErrorStatus setArrowLineLength(const double size);

  /// <summary>
  /// Gets the end line overshoot.
  /// </summary>
  ///
  /// <returns>
  /// Return double value of end line overshoot.
  /// </returns>
  double endLineOvershoot() const;

  /// <summary>
  /// Sets the end line overshoot.
  /// </summary>
  ///
  /// <param name="size">
  /// Value of end line overshoot.
  /// </param>
  /// <returns>
  /// Return Acad::eOk if Successful.
  /// </returns
  Acad::ErrorStatus setEndLineOvershoot(const double size);

  ///<summary>Set settings in AcDbSectionViewStyle to the same values as the corresponding settings in AmdtSectionSymStd.
  ///For example, it will call AcDbSectionViewStyle::setViewIdentifierPosition() to set to AcDbSectionViewStyle:: kEndCuttingPlane.</summary>
  ///<param name="pSectionViewStyle">section view style object.</param> 
  virtual void setSectionViewStyle(AcDbSectionViewStyle* pSectionViewStyle) const;

  /// <summary>
  /// Gets string of characters that are to be excluded or invalid for the identifier of section view.
  /// </summary>
  ///
  /// <returns>
  /// Return excluded characters, which is separated by comma in the string.
  /// </returns>
  const ACHAR* identifierExcludeCharacters() const;

  /// <summary>
  /// Sets the string of characters that are to be excluded or invalid for the identifier of section view.
  /// </summary>
  ///
  /// <returns>
  /// String of excluded characters, which is separated by comma.
  /// </returns>
  void setIdentifierExcludeCharacters (const ACHAR* str);
  
  /// <summary>
  /// Gets arrow type of the end arrow.
  /// </summary>
  ///
  /// <returns>
  /// Return arrow type of the end arrow.
  /// </returns>
  Acm::ArrowType endArrowType() const;

  /// <summary>
  /// Sets arrow type of the end arrow.
  /// </summary>
  ///
  /// <param name="type">
  /// Arrow type of the end arrow.
  /// </param>
  Adesk::Boolean setEndArrowType(Acm::ArrowType type);

  /// <summary>
  /// Gets if the end arrow type follow the arrow type in standard.
  /// </summary>
  ///
  /// <returns>
  /// Return true if end arrow type follow the standard; otherwise, returns false.
  /// </returns>
  bool endArrowTypeByStandard() const;

  /// <summary>
  /// Sets if the end arrow type follow the arrow type in standard.
  /// </summary>
  ///
  /// <param name="byStandard">
  /// true if the end arrow type is to be set to the arrow type in standard; false otherwise.
  /// </param>
  void setEndArrowTypeByStandard(bool byStandard);

  /// <summary>
  /// Gets the identifier offset.
  /// </summary>
  ///
  /// <returns>
  /// Return double value of identifier offset.
  /// </returns>
  double identifierOffset() const;

  /// <summary>
  /// Sets the identifier offset.
  /// </summary>
  ///
  /// <param name="offset">
  /// Value of identifier offset.
  /// </param>
  /// <returns>
  /// Return Acad::eOk if Successful.
  /// </returns
  Acad::ErrorStatus setIdentifierOffset(double offset);

  /// <summary>
  /// Gets the identifier position.
  /// </summary>
  ///
  /// <returns>
  /// Return identifier position.
  /// </returns>
  AcDbSectionViewStyle::IdentifierPosition identifierPosition() const;

  /// <summary>
  /// Sets the identifier position.
  /// </summary>
  ///
  /// <param name="type">
  /// Identifier position.
  /// </param>
  void setIdentifierPosition (AcDbSectionViewStyle::IdentifierPosition type);

  /// <summary>
  /// Gets the bend line length.
  /// </summary>
  ///
  /// <returns>
  /// Return double value of bend line length.
  /// </returns>
  double bendLineLength() const;

  /// <summary>
  /// Sets the bend line length.
  /// </summary>
  ///
  /// <param name="length">
  /// Value of bend line length.
  /// </param>
  /// <returns>
  /// Return Acad::eOk if Successful.
  /// </returns
  Acad::ErrorStatus setBendLineLength (double length);

  /// <summary>
  /// Gets the end line length.
  /// </summary>
  ///
  /// <returns>
  /// Return double value of end line length.
  /// </returns>
  double endLineLength() const;

  /// <summary>
  /// Sets the end line length.
  /// </summary>
  ///
  /// <param name="length">
  /// Value of end line length.
  /// </param>
  /// <returns>
  /// Return Acad::eOk if Successful.
  /// </returns
  Acad::ErrorStatus setEndLineLength (double length);

  /// <summary>
  /// Gets the color of the cutting plane lines.
  /// </summary>
  ///
  /// <returns>
  /// Return color of the cutting plane lines.
  /// </returns>
  AcCmColor planeLineColor() const;

  /// <summary>
  /// Sets the color of the cutting plane lines.
  /// </summary>
  ///
  /// <param name="color">
  /// Color of the cutting plane lines.
  /// </param>
  void setPlaneLineColor (const AcCmColor& color);

  /// <summary>
  /// Gets if the plane line color follow the color of the Plane Line object in standard.
  /// </summary>
  ///
  /// <returns>
  /// Return true if color follow the standard; otherwise, returns false.
  /// </returns>
  bool planeLineColorByStandard() const;

  /// <summary>
  /// Sets if the plane line color follow the color of Plane Line object in standard.
  /// </summary>
  ///
  /// <param name="byStandard">
  /// true if color is to be set to the color of Plane Line object; false otherwise.
  /// </param>
  void setPlaneLineColorByStandard(bool byStandard);

  /// <summary>
  /// Gets the linetype of the cutting plane lines.
  /// </summary>
  ///
  /// <returns>
  /// Return object id of the linetype.
  /// </returns>
  AcDbObjectId planeLineTypeId() const;

  /// <summary>
  /// Sets the linetype of the cutting plane lines.
  /// </summary>
  ///
  /// <param name="objId">
  /// Object id of the linetype.
  /// </param>
  void setPlaneLineTypeId (const AcDbObjectId &objId);

  /// <summary>
  /// Gets if the linetype of the cutting plane lines follow the linetype of the Plane Line object in standard.
  /// </summary>
  ///
  /// <returns>
  /// Return true if linetype follow the standard; otherwise, returns false.
  /// </returns>
  bool planeLineTypeIdByStandard() const;

  /// <summary>
  /// Sets if the linetype of the cutting plane lines follow the linetype of Plane Line object in standard.
  /// </summary>
  ///
  /// <param name="byStandard">
  /// true if linetype is to be set to the linetype of Plane Line object; false otherwise.
  /// </param>
  void setPlaneLineTypeIdByStandard(bool byStandard);

  /// <summary>
  /// Gets the lineweight of the cutting plane lines.
  /// </summary>
  ///
  /// <returns>
  /// Return lineweight of the cutting plane lines.
  /// </returns>
  AcDb::LineWeight planeLineWeight() const;

  /// <summary>
  /// Sets the lineweight of the cutting plane lines.
  /// </summary>
  ///
  /// <param name="lineWeight">
  /// Lineweight of the cutting plane lines.
  /// </param>
  void setPlaneLineWeight(const AcDb::LineWeight& lineWeight);

  /// <summary>
  /// Gets if the lineweight of the cutting plane lines follow the linetype of the Plane Line object in standard.
  /// </summary>
  ///
  /// <returns>
  /// Return true if linetype follow the standard; otherwise, returns false.
  /// </returns>
  bool planeLineWeightByStandard() const;

  /// <summary>
  /// Sets if the lineweight of the cutting plane lines follow the lineweight of Plane Line object in standard.
  /// </summary>
  ///
  /// <param name="byStandard">
  /// true if lineweight is to be set to the lineweight of Plane Line object; false otherwise.
  /// </param>
  void setPlaneLineWeightByStandard(bool byStandard);

  /// <summary>
  /// Gets the text style of the label.
  /// </summary>
  ///
  /// <returns>
  /// Return object id of the text style.
  /// </returns>
  AcDbObjectId labelTextStyleId() const;

  /// <summary>
  /// Sets the text style of the label.
  /// </summary>
  ///
  /// <param name="objId">
  /// Object id of the text style.
  /// </param>
  void setLabelTextStyleId (const AcDbObjectId &objId);

  /// <summary>
  /// Gets if the text style of the label follow the text style of the text in standard.
  /// </summary>
  ///
  /// <returns>
  /// Return true if text style follow the standard; otherwise, returns false.
  /// </returns>
  bool labelTextStyleByStandard() const;

  /// <summary>
  /// Sets if the text style of the label follow the text style of the text in standard.
  /// </summary>
  ///
  /// <param name="byStandard">
  /// true if text style of the label is to be set to the text style of the text in standard; false otherwise.
  /// </param>
  void setLabelTextStyleByStandard(bool byStandard);

  /// <summary>
  /// Gets the text color of the label.
  /// </summary>
  ///
  /// <returns>
  /// Return text color of the label.
  /// </returns>
  AcCmColor labelTextColor() const;

  /// <summary>
  /// Sets the text color of the label.
  /// </summary>
  ///
  /// <param name="color">
  /// Text color of the label.
  /// </param>
  void setLabelTextColor (const AcCmColor& color);

  /// <summary>
  /// Gets if the text color of the label follow the color of the text in standard.
  /// </summary>
  ///
  /// <returns>
  /// Return true if text color follow the standard; otherwise, returns false.
  /// </returns>
  bool labelTextColorByStandard() const;

  /// <summary>
  /// Sets if the text color of the label follow the color of the text in standard.
  /// </summary>
  ///
  /// <param name="byStandard">
  /// true if text color of the label is to be set to the color of the text in standard; false otherwise.
  /// </param>
  void setLabelTextColorByStandard(bool byStandard);

  /// <summary>
  /// Gets the text height of the label.
  /// </summary>
  ///
  /// <returns>
  /// Return text height of the label.
  /// </returns>
  double labelTextHeight() const;

  /// <summary>
  /// Sets the text height of the label.
  /// </summary>
  ///
  /// <param name="height">
  /// Text height of the label.
  /// </param>
  /// <returns>
  /// Return Acad::eOk if Successful.
  /// </returns
  Acad::ErrorStatus setLabelTextHeight (double height);

  /// <summary>
  /// Gets if the text height of the label follow the height of the text in standard.
  /// </summary>
  ///
  /// <returns>
  /// Return true if text height follow the standard; otherwise, returns false.
  /// </returns>
  bool labelTextHeightByStandard() const;

  /// <summary>
  /// Sets if the text height of the label follow the height of the text in standard.
  /// </summary>
  ///
  /// <param name="byStandard">
  /// true if text height of the label is to be set to the height of the text in standard; false otherwise.
  /// </param>
  void setLabelTextHeightByStandard(bool byStandard);

  /// <summary>
  /// Gets the label offset from the view.
  /// </summary>
  ///
  /// <returns>
  /// Return label offset from the view.
  /// </returns>
  double labelOffset() const;

  /// <summary>
  /// Sets the label offset from the view.
  /// </summary>
  ///
  /// <param name="offset">
  /// Label offset from the view.
  /// </param>
  /// <returns>
  /// Return Acad::eOk if Successful.
  /// </returns
  Acad::ErrorStatus setLabelOffset (double offset);

  /// <summary>
  /// Gets the text alignment of the label.
  /// </summary>
  ///
  /// <returns>
  /// Return text alignment of the label.
  /// </returns>
  AcDbModelDocViewStyle::TextAlignment labelAlignment() const;

  /// <summary>
  /// Sets the text alignment of the label.
  /// </summary>
  ///
  /// <param name="alignment">
  /// Text alignment of the label.
  /// </param>
  void setLabelAlignment (AcDbModelDocViewStyle::TextAlignment alignment);

protected:
  ///<summary>The class constructor.</summary>
  AmdtSectionSymStd();
  virtual Acad::ErrorStatus createDefaultLTypeAnnotLine(LPCTSTR pName);
  Acad::ErrorStatus preMigratePreKastle();
  Acad::ErrorStatus migratePreKastle(AmdtSectionSymStdLegacyImp *pLegacySectionStd);
  AcGeCircArc3d* getArcWithCenterPt(const AcGePoint3d& startPt, const AcGePoint3d& cent, const AcGePoint3d& endPt) const; 
  AcDbObjectId sectionViewStyleId () const;
  Acad::ErrorStatus setSectionViewStyleId (const AcDbObjectId &viewStyleId);

  const AmdtSectionSymStdImp* constImp() const;
  AmdtSectionSymStdImp*       imp();

  virtual Acad::ErrorStatus subGetClassID(CLSID* pClsid) const;

  // PKA 01/22/2013: Bugfix DID 1490557
  virtual Acad::ErrorStatus subDeepClone(AcDbObject*    pOwnerObject,
                                      AcDbObject*&   pClonedObject,
                                      AcDbIdMapping& idMap,
                                      Adesk::Boolean isPrimary = Adesk::kTrue) const;
  Adesk::Boolean setFactoryDefaultsOnDerivativeSettings();

  virtual void setFactoryDefaultsOnNewSettings();

  //Due to Jira bug ACADV-9740, add getPrefixToLt and wrapper func getArrowLtFromSideDb to get correct arrow line type id from sidedb

  // Get prefix from linetype
  AcString getPrefixToLt(AcDbObjectId& ltId) const;

  // Get Arrow Linetype ID from side database by using the plane linetype name
  void getArrowLtFromSideDb(AcDbObjectId& arrowLtId, AcDbObjectId& planeLtId, const ACHAR* arrowLtStr, const AcDbLinetypeTable* LTT) const;
};

inline
const AmdtSectionSymStdImp* AmdtSectionSymStd::constImp() const
{
  ASSERT(mpSymStdImp);
  return (const AmdtSectionSymStdImp*)mpSymStdImp;
}

inline
AmdtSectionSymStdImp* AmdtSectionSymStd::imp()
{
  ASSERT(mpSymStdImp);
  return (AmdtSectionSymStdImp*)mpSymStdImp;
}

DBREF_DECLARE(AmdtSectionSymStd)


///<summary>This is an existing class for Section Line. Declared with ACMSYMBB_CRX_DLLSHARE.</summary>
class ACMSYMBB_CRX_DLLSHARE AmdtSectionSym : public AcmSymbol
{
public:
  ACRX_DECLARE_MEMBERS(AmdtSectionSym);
  ///<summary>The class constructor.</summary>
  AmdtSectionSym();
  ///<summary>The class destructor.</summary>
  virtual ~AmdtSectionSym();             
  ///<summary>Returns the origin of the defining plane.</summary>
  virtual AcGePoint3d origin() const;
  ///<summary>Sets the origin of the defining plane.</summary>
  virtual void setOrigin(const AcGePoint3d& origin);
  ///<summary>Gets the direction side of section line.</summary>
  AcGeVector3d sectionSide() const;
  ///<summary>Sets the direction side of section line.</summary>
  void setSectionSide(const AcGeVector3d& side);
  ///<summary>Returns the number of label names.</summary>
  int labelNamesCount() const;
  ///<summary>Returns label name at specified index.</summary>
  LPCTSTR labelName(const int at = 0) const;
  ///<summary>Sets label name at specified index.</summary>
  bool setLabelName(const ACHAR* labelName, const int at = 0);
  ///<summary>Sets label names for section line.names should have the same length with section points.</summary>
  void setLabelNames(const CStringArray& names);
  Acm::ErrorStatus getLabelNames(AcStringArray& label) const override;
  ///<summary>Returns label pattern of section line.</summary>
  LPCTSTR labelPattern() const;
  ///<summary>Sets label pattern for section line.</summary>
  
  void setLabelPattern(const ACHAR* labelPattern);
  CString labelText(/*const int at = 0*/) const;
  AcDbObjectId baseViewId() const; 
  AcDbObjectId sectionViewId() const;
  AcDbObjectId sectionEntId() const;
  void setSectionEntId(const AcDbObjectId& sectionEntId);
  ///<summary>Returns the array of section point</summary>
  AcGePoint3dArray sectionPoints() const;
  ///<summary>Adds the array of section vertex to section line.</summary>
  void setSectionPoints(const AcGePoint3dArray& sectionPoints);
  ///<summary>Adds section vertex to section line.</summary>
  void addSectionPoint(const AcGePoint3d& point);
  ///<summary>Sets section vertex at specified index.</summary>
  void setSectionPointsAt(const int at, const AcGePoint3d& point);
  void eraseSectionPoints();
  ///<summary>Adds vertexes to section line.The length of arcPoints should be same to the length of array which element type is not Acm::kLineSegment in lineSegmentType.</summary>
  void setSectionPoints(const AcGePoint3dArray& sectionPoints, const AcGePoint3dArray& arcPoints, const AcArray<Acm::SectionSymLineSegmentType>& lineSegmentType);  
  ///<summary>Sets arc vertex to section line at specific position.</summary>
  void setSectionArcPointsAt(const int at, const AcGePoint3d& arcPoint, Acm::SectionSymLineSegmentType segmentType=Acm::kArcSegmentCenter);
  Acm::SectionSymLineSegmentType sectionLineSegmentType(const int index, AcGePoint3d& arcPoint) const;
  ///<summary>Gets visibility style of section line.</summary>
  AmdtSectionSymStd::LineVisibility lineVisibility() const;
  ///<summary>Sets visibility style of section line.</summary>
  void setLineVisibility(const AmdtSectionSymStd::LineVisibility lineVis);
  ///<summary>Gets whether section view label is visible or hidden.</summary>
  Adesk::Boolean showAnnot() const;
  ///<summary>Determines whether section view label is visible or hidden.</summary>
  void setShowAnnot(const Adesk::Boolean v);
  ///<summary>Gets whether arrow is visible or hidden at the end of the section line.</summary>
  Adesk::Boolean showArrows() const;
  ///<summary>Determines whether arrow is visible or hide at the end of the section line.</summary>
  void setShowArrows(const Adesk::Boolean v);

  Adesk::Boolean showPlaneNames() const;
  ///<summary>Determines whether annotation is to be showed at each vertex.</summary>
  void setShowPlaneNames(const Adesk::Boolean v);

  LPCTSTR value(Acm::Variable var) const;

  Acm::ErrorStatus setValue(Acm::Variable var, LPCTSTR value);

  Acm::Visibility  variableStatus(Acm::Variable var) const;

  Acm::ErrorStatus setVariableStatus(Acm::Variable var, Acm::Visibility status);
  Acm::ErrorStatus getVarDlgInfo(Acm::Variable var,CVarDlgInfo& v) const;
  Acm::ErrorStatus setVarDlgInfo(Acm::Variable var,const CVarDlgInfo& v);
  ///<summary>Uses this overloaded member function to set up a symbol properly.</summary>
  ///<param name="pDb">Pointer to database. Default is NULL, and host databse will be used.</param>
  ///<returns>If successful then Acm::eOk is returned. If the symbol standard is not valid, then Acm::eNotSupported is returned.</returns>
  virtual Acm::ErrorStatus setSymbolDefaults(AcDbDatabase* pDb = NULL);

  virtual AmdtSectionSymC* subSymbol() const;

  using AcmSymbol::transformBy;
  ///<summary>Transforms all leaders. Default implementation doesn't cover any smart behavior.</summary>
  virtual Acad::ErrorStatus transformBy(const AcGeMatrix3d& xform, double symbolScale);
  ///<summary>This method mirrors AcmSymbol entity.</summary>
  ///<param name="xMirrorForm">Transformation matrix with MIRROR element</param>
  ///<param name="XAxis">Returns mirrored X-Axis of the entity coordinate system</param>
  ///<param name="YAxis">Returns mirrored Y-Axis of the entity coordinate system</param>
  ///<param name="normal">Returns mirrored Normal of the entity coordinate system</param>
  virtual void mirrorCoordSys(const AcGeMatrix3d& xMirrorForm,
                              AcGeVector3d& XAxis,
                              AcGeVector3d& YAxis,
                              AcGeVector3d& normal) const;

  virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler* filer);
  virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* filer) const;
  virtual Acad::ErrorStatus dxfOutFields(AcDbDxfFiler* filer) const;
  virtual Acad::ErrorStatus subErase(Adesk::Boolean pErasing);
  ///<summary>Set section view origin in the section line.detailViewId should be NULL.
  ///This function should be invoked after posting section line object to database.</summary>
  Acad::ErrorStatus makeSectionEnt(const AcGePoint3d& origin,
                                  const AcDbObjectId& detailViewId,  
                                  const AcDbObjectId& entOwnerId = NULL);
  ///<summary>This function is called during the updating of symbols that takes place when the standard is changed.</summary>
  void regen();
  
  virtual Acm::ErrorStatus addLeader(const AcGePoint3dArray &ptrArray);
  virtual Acm::ErrorStatus removeLeader(Adesk::UInt16 index);
  
  AcGeVector3d labelOffset() const;
  void setLabelOffset(const AcGeVector3d& offset);
  double arrowLineLength() const;
  void setArrowLineLength(const double size);
  double arrowLineOffset() const;
  void setArrowLineOffset(const double size);
  AcGeVector3dArray annotOffsets() const;
  void setAnnotOffsets(const AcGeVector3dArray& offsets);
  void setAnnotOffsetsAt(const AcGeVector3d& offset, const int at);
  void resetAnnotOffsets();

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

  virtual Adesk::Boolean    subWorldDraw(AcGiWorldDraw* mode);
  ///<summary>Queries all leaders for their grip points.</summary>
  virtual Acad::ErrorStatus subGetGripPoints(AcGePoint3dArray&,
                                          AcDbIntArray&,
                                          AcDbIntArray&) const;
  ///<summary>Queries all leaders for their grip points.</summary>
  virtual Acad::ErrorStatus   subGetGripPoints(AcDbGripDataPtrArray& grips,
														  const double curViewUnitSize, 
														  const int gripSize, 
														  const AcGeVector3d& curViewDir,
														  const int bitflags) const;
  ///<summary>Determines the leaders to which indices belong and apply moveGripPointsAt to them. 
  ///If the tip point is being edited, then the leaderTipPointChanged() member function of the symbol will be called. 
  ///If the leader contains a landing and it is changed, then the leaderLanding() member function of the symbol is called.</summary>
  virtual Acad::ErrorStatus subMoveGripPointsAt(const AcDbIntArray& indices,
                                             const AcGeVector3d& offset); 
  ///<summary>Queries the standard for sub-entities for all leaders and then the server for all sub-entities for all sub-symbols. 
  ///All sub-entities are then exploded.</summary>
  virtual Acad::ErrorStatus subExplode(AcDbVoidPtrArray& entitySet) const;
  virtual Acad::ErrorStatus subTransformBy(const AcGeMatrix3d& xform);
  virtual Acad::ErrorStatus subGetClassID(CLSID* pClsid) const;
  virtual Acad::ErrorStatus subDeepClone(AcDbObject* pOwner, 
                                      AcDbObject*& pClonedObject,
                                      AcDbIdMapping& idMap, 
                                      Adesk::Boolean isPrimary = Adesk::kTrue) const;
  virtual Acad::ErrorStatus subWblockClone(AcRxObject* pOwner, 
                                      AcDbObject*& pClonedObject,
                                      AcDbIdMapping& idMap, 
                                      Adesk::Boolean isPrimary = Adesk::kTrue) const;
  ///<summary>Queries all leaders to get their intersections with the specified entity. 
  ///If it is a user-defined entity, it will be exploded first, 
  ///and created entities will be resolved using the same member function.</summary>
  virtual Acad::ErrorStatus subIntersectWith(const AcDbEntity* ent,
                                        AcDb::Intersect intType,
                                        AcGePoint3dArray& points,
                                        INT_PTR thisGsMarker,
                                        INT_PTR otherGsMarker) const;
  ///<summary>Sums geometry extents for a leader.</summary>
  virtual Acad::ErrorStatus subGetGeomExtents(AcDbExtents&) const;

  AmdtSectionSymC* mpSubSymbol;

private:

  Acad::ErrorStatus changeArrowLineOffset(const AcGePoint3dArray& pts, 
                                          const AcGeVector3d& offset,
                                          bool isFirstArrow = true);

  Acad::ErrorStatus changeArrowLineLength(const AcGePoint3dArray& pts, 
                                          const AcGeVector3d& offset,
                                          bool isFirstArrow = true);

};    
DBREF_DECLARE(AmdtSectionSym);

///<summary>This is class AmdtSectionSymC.</summary>
class AmdtSectionSymC : public AcmCSubSymbol
{
public:

  AmdtSectionSymC(AmdtSectionSym* pSym);
  virtual ~AmdtSectionSymC();

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

  Adesk::Boolean operator==(const AmdtSectionSymC&) const;
  virtual AmdtSectionSymC& operator=(const AmdtSectionSymC&);
  virtual AmdtSectionSymC* clone()const;

  AmdtSectionSymCImp* getImp() const { return mpImp; }

  virtual AcGeVector3d labelOffset() const;
  virtual void setLabelOffset(const AcGeVector3d& offset);
  virtual AcGeVector3d sectionSide() const;
  virtual void setSectionSide(const AcGeVector3d& side);
  virtual double arrowLineLength() const;
  virtual void setArrowLineLength(const double size);
  virtual double arrowLineOffset() const;
  virtual void setArrowLineOffset(const double size);
  virtual AcGeVector3dArray annotOffsets() const;
  virtual void setAnnotOffsets(const AcGeVector3dArray& offsets);
  virtual void setAnnotOffsetsAt(const AcGeVector3d& offset, const int at);
  virtual AcGeVector3d getAnnotOffsetsAt(const int at);

  virtual LPCTSTR labelName(const int at = 0) const;
  virtual bool setLabelName(const ACHAR* labelName, const int at = 0);
  virtual void setLabelNames(const CStringArray& names);
  virtual int labelNamesCount() const;
  virtual LPCTSTR labelPattern() const;
  virtual void setLabelPattern(const ACHAR* labelPattern);
  virtual CString labelText(/*const int at = 0*/) const;
  virtual AcGePoint3dArray sectionPoints() const;
  virtual void setSectionPoints(const AcGePoint3dArray& sectionPoints, const AcArray<bool>& isVertex);
  virtual void addSectionPoint(const AcGePoint3d& point, const bool isVertex = true);
  virtual void setSectionPointsAt(const int at, const AcGePoint3d& point, const bool isVertex = true);
  virtual void eraseSectionPoints();
  virtual bool isVertex(const int index) const;
  virtual void setSectionPoints(const AcGePoint3dArray& sectionPoints, const AcArray<bool>& isVertex, const AcGePoint3dArray& arcPoints, const AcArray<Acm::SectionSymLineSegmentType>& lineSegmentType);  
  virtual void setSectionArcPointsAt(const int at, const AcGePoint3d& arcPoint, Acm::SectionSymLineSegmentType segmentType=Acm::kArcSegmentCenter);
  virtual Acm::SectionSymLineSegmentType sectionLineSegmentType(const int index, AcGePoint3d& arcPoint) const;
  virtual AmdtSectionSymStd::LineVisibility lineVisibility() const;
  virtual void setLineVisibility(const AmdtSectionSymStd::LineVisibility lineVis);
  virtual Adesk::Boolean showAnnot() const;
  virtual void setShowAnnot(const Adesk::Boolean v);
  virtual Adesk::Boolean showArrows() const;
  virtual void setShowArrows(const Adesk::Boolean v);
  virtual Adesk::Boolean showPlaneNames() const;
  virtual void setShowPlaneNames(const Adesk::Boolean v);

  virtual double scale() const;
  virtual AcGeVector3d normal() const;

  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:
    AmdtSectionSymCImp* mpImp{ nullptr };
};

#endif // __SECTIONSYM_H
