//////////////////////////////////////////////////////////////////////////////
//
//  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 __ACMBALLOON_H
#define __ACMBALLOON_H
class AcmSymbol;
class AcmCBalloon;
class AcmCBalloonImp;
class contourGeometry_t;

///<summary>The AcmBalloon symbol.</summary>
class ACMSYMBB_CRX_DLLSHARE AcmBalloon : public AcmSymbol
{
public:
  ACRX_DECLARE_MEMBERS(AcmBalloon);
  Acad::ErrorStatus erase(Adesk::Boolean erasing = true); //Ryan 22August, to catch balloon erased moment
  virtual Acad::ErrorStatus createBlock();//duplicate a block for the balloon(without erasing the balloon)
   
  ///<summary>Class constructor.Default constructor is not recommended to use for it may result in corrupted balloon 
  ///if you don�t set part ref later on.</summary>
  AcmBalloon();
  AcmBalloon(const AcDbObjectIdArray& rowIds);
  ///<summary>Class destructor.</summary>
  virtual ~AcmBalloon();
    
  virtual Acm::ErrorStatus setSymbolDefaults(AcDbDatabase* pDb = NULL);
  AcmCBalloon *subSymbol() const;
  AcDbObjectIdArray rowIds() const;
  
  void getRowIds(AcDbObjectIdArray& rowIds) const;

  void setRowIds(const AcDbObjectIdArray& rowIds);

  void removeItem(const AcDbObjectId& rowId, bool allowErase=true);  //allowErase -> erase balloon if no associated rows 
  void appendItem(const AcDbObjectId& rowId);
  
  Acad::ErrorStatus bomId(AcDbObjectId&) const;
  Acm::BalloonType type() const;

  void setType(const Acm::BalloonType type);
  Acm::BalloonCollectionType collectionType() const;

  void setCollectionType(const Acm::BalloonCollectionType dir);
  ///<summary>Returns the origin of the defining plane.</summary>
  AcGePoint3d origin() const;

  void setOrigin(const AcGePoint3d& o);
  ///<summary>This function is called during the updating of symbols that takes place when the standard is changed.</summary>
  virtual void regen();
  
  using AcmSymbol::transformBy;
  
  ///<param name="xform"> </param>
  ///<param name="symbolScale"></param>
  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 transformAssociatedSymbol(const AcGeMatrix3d& xform, bool MDTViewMoveCxt); 
                                                                                  
  
  void setArrowInset(double inset);   // Added DPT 10/30/02
  double arrowInset() const;
  AcGeVector3d arrowInsetVector() const;

  void setArrowInsetVector(const AcGeVector3d&);
  AcGeVector3d computeArrowInset(const AcGeVector3d& curveNormal);



  virtual Acm::ErrorStatus addLeader(const AcGePoint3dArray &ptrArray);
  virtual void leaderTipPointChanged(const AcGeVector3d& offset, const AcmCLeader* leader);
  virtual void leaderLandingChanged(const AcGeVector3d& offset, const AcmCLeader* leader);

  
  ///<summary>make balloon an orphan</summary>
  void makeOrphan();

  virtual Acm::ErrorStatus attachGeomRef(const void* pGeomRef,  const AcGePoint3d &arrowheadLocation);
  virtual Acm::ErrorStatus attachGeomRef(const void* pGeomRef, const AcDbObjectId &viewId,  const AcGePoint3d &arrowheadLocation);
  virtual Acm::ErrorStatus retargetBalloon(const void* pGeomRef);   // attach balloon to new target comp
  virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler* pFiler);
  virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* pFiler) const;
  virtual Acad::ErrorStatus dxfInFields(AcDbDxfFiler* pFiler);
  virtual Acad::ErrorStatus dxfOutFields(AcDbDxfFiler* pFiler) const;
  virtual Acad::ErrorStatus subClose();

  virtual bool setUserType(LPCTSTR blkName);
  virtual bool setUserTypeId(const AcDbObjectId& btrId);
  virtual LPCTSTR userType() const;
  virtual AcDbObjectId userTypeId() const;
  virtual Acm::BalloonAttachType attachType() const;
  virtual void setAttachType(Acm::BalloonAttachType type);
  virtual Acm::ErrorStatus removeLeader(Adesk::UInt16 index);

  const AcGeCurve3d* getAttachCurve() const;
  const AcDbObjectId getAttachEntity() const;
  const AcDbObjectIdArray getAttachEntityList() const; //567388
  
  void endGripEdit(contourGeometry_t* pContourGeometry);    //  called by AcmInputContextReactor

  ///<summary>Returns the comp view owner. This is the basic view id of an annotation view to which this balloon is associated to, if any.</summary>
  virtual AcDbObjectId compViewId() const;
  ///<summary>Sets the comp view owner. This is the basic view id of an annotation view to which this balloon is associated to, if any.</summary>
  ///<param name="compViewId">Id of component view. </param>
  virtual void setCompViewId(const AcDbObjectId& compViewId);

protected:
  virtual Adesk::Boolean subWorldDraw(AcGiWorldDraw* pMode);
  virtual Acad::ErrorStatus   subGetClassID(CLSID* pClsid) const;
  virtual Acad::ErrorStatus subTransformBy(const AcGeMatrix3d& xform);
  ///<summary>Lists all leaders including their vertices, standard name and original name, server name and version.</summary>
  virtual void subList() const;
  ///<summary>Queries the standard for sub-entities for all leaders and then the server for all sub-entities for all sub-symbols. 
  ///All sub-entities are then exploded.</summary>
  virtual Acad::ErrorStatus subExplode(AcDbVoidPtrArray& entitySet) const;
  ///<summary>Sums geometry extents for a leader.</summary>
  virtual Acad::ErrorStatus subGetGeomExtents(AcDbExtents& extents) const;

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

  ///<summary>Queries all leaders for their grip points.</summary>
  virtual Acad::ErrorStatus subGetGripPoints(AcGePoint3dArray&,
                                          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&,
                                             const AcGeVector3d&);

  ///<summary>Queries all leaders to get their intersections with the specified entity. 
  ///If it is a user-defined entity, it will be exploded first, 
  ///and created entities will be resolved using the same member function.</summary>
  virtual Acad::ErrorStatus subIntersectWith(const AcDbEntity* ent,
	                            AcDb::Intersect intType,AcGePoint3dArray& points,
	                            INT_PTR thisGsMarker = 0,INT_PTR otherGsMarker = 0) const;

  ///<summary>Queries all leaders to get their intersections with the specified entity. 
  ///If it is a user-defined entity, it will be exploded first, 
  ///and created entities will be resolved using the same member function.</summary>
  virtual Acad::ErrorStatus subIntersectWith(const AcDbEntity* ent,
	                            AcDb::Intersect intType,const AcGePlane& projPlane,
	                            AcGePoint3dArray& points,INT_PTR thisGsMarker = 0,INT_PTR otherGsMarker = 0) const;
  virtual Acad::ErrorStatus subWblockClone(AcRxObject* pOwnerObject,
                                        AcDbObject*& pClonedObject,
                                        AcDbIdMapping& idMap,
                                        Adesk::Boolean isPrimary = Adesk::kTrue) const;
  virtual Adesk::Boolean subCloneMeForDragging();

private:
  void getSubEnts(AcmCAuxEntArray& subents) const;
  void setNonDrawingDistance();
  AcmCBalloon *mpBalloon;
  bool  m_bDowngraded;


};

DBREF_DECLARE(AcmBalloon)

#endif
