#ifndef __CAUXENT_H
#define __CAUXENT_H
/////////////////////////////////////////////////////////////////////
// (C) Copyright 1993-2006 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.
//
// cauxent.h
//
// Description:
// These classe will implement drawing and geometry features for
// generic subentity as Line,Arc,Circle
//
// Notes:
// the color of -1 means no color at all. It is than controled be
// the caller entityTraits
//
/////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////
//Base class to define general interface
/////////////////////////////////////////////////////////////////////
class AcmCAuxImpEntity;

class DllImpExp AcmCAuxEntity
{
public:
  AcmCAuxEntity();
  AcmCAuxEntity(const AcmCAuxEntity& src);
  AcmCAuxEntity(const AcDbEntity* pDef);

  virtual ~AcmCAuxEntity();
  virtual const AcmCAuxEntity& operator=(const AcmCAuxEntity& src);

  // access to private data
  AcDbObjectId ltypeId() const;
  virtual void setLtypeId(const AcDbObjectId& id);  

  Adesk::Int16 color() const; 
  virtual void setColor(Adesk::Int16 col); 

  const AcCmColor & trueColor() const; 
  virtual void setColor(const AcCmColor & color); 

  AcDb::LineWeight lineWeight() const;
  virtual void setLineWeight(const AcDb::LineWeight wgh);

  enum Type {
    kLine = 0,
    kCircle,
    kArc,
    kText,
    kHatch,
    kPolygon,
    kAttribute,
    kEllipse,
    kSpline,
    kRasterImage,
    kAcDbText,
    kScaleText
  };

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

  virtual void setProperties(const AcDbObjectId& id,Adesk::Int16 color = -1);  
  virtual void setProperties(const AcDbObjectId & id, const AcCmColor & col);

  // forced interface
  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;
  // obligatory interface
  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;
};

////////////////////////////////////////////////////////////////
// class used for holding array of AcmCAuxEntity.
////////////////////////////////////////////////////////////////
class DllImpExp AcmCAuxEntArray : public AcDbVoidPtrArray
{
public:
  AcmCAuxEntArray();
  AcmCAuxEntArray(const AcmCAuxEntArray& src);
  AcmCAuxEntArray(const AcmCAuxEntArray& src, Adesk::Boolean all);
  virtual const AcmCAuxEntArray& operator=(const AcmCAuxEntArray& src);

  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;

  // Removing array-elements.
  //
  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);

  // Update symbols according to LEAD/MSYM line properties
  // Provide a function to allow setting the line type
  // without changing the color property
  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 transformBy(const AcGeMatrix3d& xform);
  Acad::ErrorStatus explode(AcDbVoidPtrArray& entitySet,const AcDbEntity*) const;
  Adesk::Boolean    worldDraw(AcGiWorldDraw*        mode);
  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
