#ifndef __ACMBALLOON_H
#define __ACMBALLOON_H
//////////////////////////////////////////////////////////////////////
//  (C) Copyright 1994-2008 by Autodesk, Inc.  All rights reserved.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted, 
// provided that the above copyright notice appears in all copies and 
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting 
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS. 
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.  AUTODESK, INC. 
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to 
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
//
// Balloon.h
//
// Description: AcmBalloon symbol
/////////////////////////////////////////////////////////////////////


class AcmSymbol;
class AcmCBalloon;
class AcmCBalloonImp;
class contourGeometry_t;

class DllImpExp 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)
   
  AcmBalloon();
  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);

  AcGePoint3d origin() const;
  void setOrigin(const AcGePoint3d& o);
  virtual void regen();

  using AcmSymbol::transformBy;
  virtual Acad::ErrorStatus transformBy(const AcGeMatrix3d& xform,
                                        double symbolScale);

  virtual void mirrorCoordSys(const AcGeMatrix3d& xMirrorForm,
                              AcGeVector3d& XAxis,
                              AcGeVector3d& YAxis,
                              AcGeVector3d& normal) const;

  //transformAssociatedSymbol calls transformBy, unless symbol type = AcmBalloon.  In that case transform arrowhead only.
  // called when object symbol is attached to has been transformed.
  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);


  // general implementation will change origin point for thefirst subsymbol
  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);

  // AcDbEntity interface

  void makeOrphan();  // make balloon an orphan
  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();

  //Custom Block interface
  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);

  // Get curve that arrowhead "points" to.  Caller's resposibility to delete!
  const AcGeCurve3d* getAttachCurve() const;
  const AcDbObjectId getAttachEntity() const;
  const AcDbObjectIdArray getAttachEntityList() const; //567388
  
  void endGripEdit(contourGeometry_t* pContourGeometry);    //  called by AcmInputContextReactor

  // associated comp view owner. it is the basic view id of an annotation view
  virtual AcDbObjectId compViewId() const;
  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);
  
  virtual void subList() const;
  virtual Acad::ErrorStatus subExplode(AcDbVoidPtrArray& entitySet) const;
  virtual Acad::ErrorStatus subGetGeomExtents(AcDbExtents& extents) const;
  virtual Acad::ErrorStatus subGetOsnapPoints(AcDb::OsnapMode     osnapMode,
                                           INT_PTR             gsSelectionMark,
                                           const AcGePoint3d&  pickPoint,
                                           const AcGePoint3d&  lastPoint,
                                           const AcGeMatrix3d& viewXform,
                                           AcGePoint3dArray&   snapPoints,
                                           AcDbIntArray&       geomIds) const;
  virtual Acad::ErrorStatus subGetGripPoints(AcGePoint3dArray&,
                                          AcDbIntArray&,
                                          AcDbIntArray&) const;
  virtual Acad::ErrorStatus	subGetGripPoints(AcDbGripDataPtrArray& grips,
											 const double curViewUnitSize, 
											 const int gripSize, 
											 const AcGeVector3d& curViewDir, 
											 const int bitflags) const;
  virtual Acad::ErrorStatus subMoveGripPointsAt(const AcDbIntArray&,
                                             const AcGeVector3d&);
  virtual Acad::ErrorStatus subIntersectWith(const AcDbEntity* ent,
	                            AcDb::Intersect intType,AcGePoint3dArray& points,
	                            INT_PTR thisGsMarker = 0,INT_PTR otherGsMarker = 0) const;
  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();
  AcmCBalloonImp *mpBalloon;
  bool  m_bDowngraded;


};

MAKE_ACDBOPENOBJECT_FUNCTION(AcmBalloon);
DBREF_DECLARE(AcmBalloon)

#endif
