#ifndef __SYMBOL_H
#define __SYMBOL_H
/////////////////////////////////////////////////////////////////////
// (C) Copyright 1993-2008 by Autodesk, Inc. 
//
// 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.
//
// Symbol.h
//
/////////////////////////////////////////////////////////////////////
class AcGiWorldDraw;
class AcGiViewportDraw;
class AcDbDwgFiler;
class AcDbDxfFiler;
class AcmStandard;
class AcmCSubSymbol;
class AcmCLeader;
class AcRfGeom;
class AcRfPickObj;
class AcmRefReactor;
class AcmDwgMgrSymbolXProtocol;
class AcmSymbolImp;
class AcmWelding;

class DllImpExp AcmSymbol : public AcDbEntity
{
  friend class AcmSymbbInternals;
public:
  ACRX_DECLARE_MEMBERS(AcmSymbol);
  virtual ~AcmSymbol();

  virtual Acm::ErrorStatus setSymbolDefaults(AcDbDatabase* pDb = NULL);

  //Ask symbol and leader for geomrefs. If is found any, then returns true.
  bool isAttached() const;
  virtual Acm::ErrorStatus detachGeomRef();
  virtual Acm::ErrorStatus attachGeomRef(const void* pGeomRef,
                                         const AcDbObjectId &viewId,
                                         const AcGePoint3d &arrowheadLocation);

  virtual Acm::ErrorStatus attachGeomRef(const void* pGeomRef,
                                         const AcGePoint3d &arrowheadLocation);
  virtual Acad::ErrorStatus eraseGeomRefs();

  virtual INT_PTR numOfGsMarkers() const;
  virtual int numGripPoints() const;

  virtual Adesk::Boolean isKnownGrip(int indice) const;

  virtual void setCoordSystem(const AcGePoint3d&  origin,
                              const AcGeVector3d& xDir,
                              const AcGeVector3d& normal);

  virtual void getCoordSystem(AcGePoint3d&  origin,
                              AcGeVector3d& xDir,
                              AcGeVector3d& normal) const;

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

  AcGeVector3d xDir() const;
  AcGeVector3d yDir() const;
  AcGeVector3d normal() const;

  virtual void setScale(double scale);
  virtual double scale() const;


  AcDbObjectId standardId() const;
  void setStandardId(const AcDbObjectId& id);

  AcDbObjectId serverId() const;
  void setServerId(const AcDbObjectId& newServerId);

  AcmCLeader* getLeader(Adesk::UInt16 index) const;
  virtual Acm::ErrorStatus addLeader(const AcGePoint3dArray &ptrArray);
  virtual Acm::ErrorStatus removeLeader(Adesk::UInt16 index);
  int numOfLeaders() const;

  virtual void leaderTipPointChanged(const AcGeVector3d& offset,
                                     const AcmCLeader* leader);

  virtual void leaderLandingChanged(const AcGeVector3d& offset,
                                    const AcmCLeader* leader);

  AcGeVector3d projectedVector(const AcGeVector3d& vec) const;
  AcGePoint3d  projectedPoint(const AcGePoint3d& pt) const;

  virtual void regen();

  using AcDbEntity::transformBy;
  // This second version is for scaling in 2DS annotation view
  //
  virtual Acad::ErrorStatus transformBy(const AcGeMatrix3d& xform,
												 double symbolScale);

  //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); 
                                                                                  
  // we use this instead of decomposeForSave because we want to control when it gets called and we don't 
  // want AutoCAD calling it when we don't want it.
  Acad::ErrorStatus convertToBlock(AcDbObject*& replaceObj,
                                   AcDbObjectId& replaceId);

  virtual Acad::ErrorStatus subHandOverTo(AcDbObject* pNewObject);

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

  static void convertSymbolToBlock(AcmSymbol *pSym);
  
  virtual Acad::ErrorStatus getGeomRefArcRadius(double & radius, Adesk::Boolean & isCirArc) const;
    
  // Update symbols according to LEAD/MSYM line properties
  virtual void setForceLineWeight(AcDb::LineWeight& lnWgt);
  virtual AcDb::LineWeight getForceLineWeight() const;

  virtual Acm::ErrorStatus updateToAttachedObject();
	virtual void mirrorCoordSys(const AcGeMatrix3d& xMirrorForm,
                              AcGeVector3d& XAxis,
                              AcGeVector3d& YAxis,
                              AcGeVector3d& normal) const;

protected:
  AcmSymbol();
 
  virtual Adesk::Boolean    subWorldDraw(AcGiWorldDraw* pMode);
  
  virtual Acad::ErrorStatus subExplode(AcDbVoidPtrArray& entitySet) const;
  virtual Acad::ErrorStatus subGetGeomExtents(AcDbExtents& extents) const;

  virtual Acad::ErrorStatus subTransformBy(const AcGeMatrix3d& xform);

  virtual Acad::ErrorStatus subDeepClone(AcDbObject* pOwnerObject,
                                      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;

  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 subGetStretchPoints(AcGePoint3dArray&) const;

  virtual Acad::ErrorStatus subMoveStretchPointsAt(const AcDbIntArray& indices,
                                                const AcGeVector3d& offset);
  
  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 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 subGetGsMarkersAtSubentPath(const AcDbFullSubentPath& subPath, 
                                                     AcArray<INT_PTR>& gsMarkers) const;
  virtual void subList() const;
  virtual Acad::ErrorStatus   subGetClassID(CLSID* pClsid) const;

  void releaseGeomRef();
  Adesk::UInt16 classVersion() const;

  Acm::ErrorStatus insertLeader(Adesk::UInt16 index,const AcGePoint3dArray &ptrArray);
  
private:
  AcmSymbolImp *mpImp;

protected:
  // We are making this constructor and destructor protected to try and
  // ensure that they are not used.  The Tahoe team has discovered a 
  // bug with the destructor so has made it private in AcDbObject.
  // This doesn't allow us to compile unless we declare it on our classes
  // that are exported.  No implementation is supplied so that link
  // errors are encountered if either of these are used.
  // See Tahoe subdoc t39dca1.txt for more details.
  //
  void *operator new[](size_t nSize) { UNREFERENCED_PARAMETER(nSize);assert(0); return NULL; }
  void operator delete[](void *p) { UNREFERENCED_PARAMETER(p);assert(0); }
};

MAKE_ACDBOPENOBJECT_FUNCTION(AcmSymbol);
DBREF_DECLARE(AcmSymbol);

#endif
