//////////////////////////////////////////////////////////////////////////////
//
//  Copyright 2025 Autodesk, Inc.  All rights reserved.
//
//  Use of this software is subject to the terms of the Autodesk license 
//  agreement provided at the time of installation or download, or which 
//  otherwise accompanies this software in either electronic or hard copy form.   
//
//////////////////////////////////////////////////////////////////////////////
#ifndef __CAUXENT_H
#define __CAUXENT_H

class AcmCAuxImpEntity;
class AcmCAuxCommonTraits;
class AcmCAuxViewportDraw;
class AcmCAuxViewportDraw;
class AcmCAuxWorldDraw;

///<summary>This is the common base class for all sub-entities. The class defines the minimum common 
///interface for sub-entities to use it to fulfill their responsibilities. That means if you want to add
///another responsibility, you can just add another member function here with its default behavior.</summary>
class ACMSYMBB_CRX_DLLSHARE AcmCAuxEntity
{
public:
  ///<summary>Constructs the auxiliary class. The constructor is protected.</summary>
  AcmCAuxEntity();
  ///<summary>Constructs the auxiliary class. The constructor is protected.</summary>
  ///<param name="src">pDef :</param>
  AcmCAuxEntity(const AcmCAuxEntity& src);
  ///<summary>Constructs the auxiliary class. The constructor is protected.</summary>
  ///<param name="src">pDef :</param>
  AcmCAuxEntity(const AcDbEntity* pDef);
  ///<summary>Destructure the auxiliary class.</summary>
  virtual ~AcmCAuxEntity();
  virtual const AcmCAuxEntity& operator=(const AcmCAuxEntity& src);

  ///<summary>Gets a line Id of sub-entity.</summary>
  AcDbObjectId ltypeId() const;
  ///<summary>Sets a line Id of sub-entity.</summary>
  virtual void setLtypeId(const AcDbObjectId& id);  
  ///<summary>Gets a color number of sub-entity.</summary>
  Adesk::Int16 color() const; 
  ///<summary>Sets a color number of sub-entity.</summary>
  virtual void setColor(Adesk::Int16 col); 
  const AcCmColor & trueColor() const; 
  ///<summary>Sets a color number of sub-entity.</summary>
  virtual void setColor(const AcCmColor & color); 
  ///<summary>Gets the line weights for the display list entity.</summary>
  AcDb::LineWeight lineWeight() const;
  ///<summary>Sets the line weights for the display list entity.</summary>
  virtual void setLineWeight(const AcDb::LineWeight wgh);
  ///<summary>This is record AcmCAuxEntity::Type.</summary>
  enum Type {
    kLine = 0,
    kCircle,
    kArc,
    kText,
    kHatch,
    kPolygon,
    kAttribute,
    kEllipse,
    kSpline,
    kRasterImage,
    kAcDbText,
    kScaleText
  };

  
  virtual AcmCAuxEntity* clone() const;
  virtual AcmCAuxEntity::Type type() const = 0;  

  ///<summary>Sets the properties of this sub-entity.</summary>
  ///<param name="id "> </param>
  ///<param name="color ">The color of -1 means no color at all. The color of this sub-entity is then 
  ///controlled by the caller's Entity Traits.</param>
  virtual void setProperties(const AcDbObjectId& id,Adesk::Int16 color = -1); 

  ///<summary>Sets the properties of this sub-entity.</summary>
  ///<param name="id "> </param>
  ///<param name="col ">The color of -1 means no color at all. The color of this sub-entity is then 
  ///controlled by the caller's Entity Traits.</param>
  virtual void setProperties(const AcDbObjectId & id, const AcCmColor & col);


  virtual Acad::ErrorStatus getGeomExtents(AcDbExtents& extents) const = 0;
  virtual Acad::ErrorStatus transformBy(const AcGeMatrix3d& xform) = 0;
  virtual Acad::ErrorStatus explode(AcDbVoidPtrArray& entitySet,const AcDbEntity*) const = 0;
  virtual Adesk::Boolean    worldDraw(AcGiWorldDraw*        mode) = 0;
  virtual void              viewportDraw(AcGiViewportDraw*  mode) = 0;
  virtual Acad::ErrorStatus getOsnapPoints(AcDb::OsnapMode     osnapMode,
                                           const AcGePoint3d&  pickPoint,
                                           const AcGePoint3d&  lastPoint,
                                           const AcGeMatrix3d& viewXform,
                                           AcGePoint3dArray&   snapPoints,
                                           AcDbIntArray&       geomIds) const;
  virtual  Acad::ErrorStatus  intersectWith(const AcDbEntity* ent,
                                            AcDb::Intersect intType, 
                                            AcGePoint3dArray& points,
                                            INT_PTR entGsMarker = 0) const;
  virtual  Acad::ErrorStatus  intersectWith(const AcDbEntity* ent,
                                            AcDb::Intersect intType, 
                                            const AcGePlane& projPlane,
                                            AcGePoint3dArray& points, 
                                            INT_PTR entGsMarker = 0) const;
protected:
  AcmCAuxImpEntity* mpImp;
};

////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
///<summary>class used for holding array of AcmCAuxEntity</summary>
class ACMSYMBB_CRX_DLLSHARE AcmCAuxEntArray : public AcArray<void*>
{
public:
  AcmCAuxEntArray();
  AcmCAuxEntArray(const AcmCAuxEntArray& src);
  AcmCAuxEntArray(const AcmCAuxEntArray& src, Adesk::Boolean all);
  virtual const AcmCAuxEntArray& operator=(const AcmCAuxEntArray& src);
  ///<summary>the destructor function</summary>
  virtual ~AcmCAuxEntArray();
  void eraseAll();

  AcmCAuxEntity *&       operator [] (int i);
  const AcmCAuxEntity*   operator [] (int i) const;

  AcmCAuxEntity*        at(int i) const;
  AcmCAuxEntArray&   setAt(int i, AcmCAuxEntity* c);
  AcmCAuxEntity*        first       ();
  const AcmCAuxEntity*  first       () const;
  AcmCAuxEntity*        last        ();
  const AcmCAuxEntity*  last        () const;


  AcmCAuxEntArray&         removeAt    (int index);
  AcmCAuxEntArray&         removeFirst ();
  AcmCAuxEntArray&         removeLast  ();
  AcmCAuxEntArray&         removeAll   ();
  
  int  append   (AcmCAuxEntity *c);
  int  append   (AcmCAuxEntArray& src);
  int  moveFrom (AcmCAuxEntArray& src);

  void setProperties(const AcDbObjectId& id, const AcCmColor & color);    
  void setProperties(const AcDbObjectId& id, Adesk::Int16 color = -1);  
  void setProperties(const AcDb::LineWeight & lineWeight, Adesk::Boolean bExcludeTxt = Adesk::kTrue);

  ///<summary>Set the line type without changing the color property</summary>
  void setLineType(const AcDbObjectId& id);

  void consolidateProperties(const AcDbObjectId& id,Adesk::Int16 color);  
  void consolidateProperties(const AcDbObjectId& id, const AcCmColor & color);
  INT_PTR startGsMarker() const;
  void setStartGsMarker(INT_PTR start);
  
  Acad::ErrorStatus getGeomExtents(AcDbExtents& extents) const;
  Acad::ErrorStatus getGeomExtentsExceptTextAndAttr(AcDbExtents& extents) const;
  Acad::ErrorStatus transformBy(const AcGeMatrix3d& xform);
  Acad::ErrorStatus explode(AcDbVoidPtrArray& entitySet,const AcDbEntity*) const;
  Adesk::Boolean    worldDraw(AcGiWorldDraw*        mode);
  Adesk::Boolean    worldDraw(AcmCAuxWorldDraw &worldDraw) const;
  void              viewportDraw(AcGiViewportDraw*  mode);

  virtual Acad::ErrorStatus getOsnapPoints(AcDb::OsnapMode     osnapMode,
                                           INT_PTR             gsSelectionMark,
                                           const AcGePoint3d&  pickPoint,
                                           const AcGePoint3d&  lastPoint,
                                           const AcGeMatrix3d& viewXform,
                                           AcGePoint3dArray&   snapPoints,
                                           AcDbIntArray&       geomIds) const;
  virtual  Acad::ErrorStatus  intersectWith(const AcDbEntity* ent,
                                            AcDb::Intersect intType, 
                                            AcGePoint3dArray& points,
                                            INT_PTR thisGsMarker = 0,
                                            INT_PTR entGsMarker = 0) const;
  virtual  Acad::ErrorStatus  intersectWith(const AcDbEntity* ent,
                                            AcDb::Intersect intType, 
                                            const AcGePlane& projPlane,
                                            AcGePoint3dArray& points, 
                                            INT_PTR thisGsMarker = 0,
                                            INT_PTR entGsMarker = 0) const;
private:
  // default 0 means gsMarkers are not used, nor increment.
  INT_PTR mStartGsMarker;
};

#endif
