#ifndef _LEADER_H
#define _LEADER_H

#ifndef __ACMDEF_H
	#error include 'acmdef.h' before including this file
#endif

/////////////////////////////////////////////////////////////////////
// (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.
//
// Description: 
//
// This abstract class is very important for proper symbol behavior. 
// It defines interface for all possible leader implementation. 
// If particular symbol class doesn’t override addLeader member 
// function of the AcmSymbol class, the general symbol leader is used. 
// Otherwise more specialized type of leader could be used. 
// There are also supplementary class AcmCLeaderNodeIterator. 
//
/////////////////////////////////////////////////////////////////////

class AcmCLeaderNodeIterator;
class AcmCAuxEntity;
class AcmCLeaderNode;
class AcmSymbol;

class DllImpExp AcmCLeader
{
  public :
  virtual ~AcmCLeader();
  // Setting and querying general leader properties
  // All leader data are primarily set according to standard. 
  // Those values are used to override the standard setting.
  //
  virtual Acm::ArrowType arrowType() const = 0;
  //virtual Acm::ErrorStatus getArrowType (Acm::ArrowType& arrowType) const = 0;
  virtual Acm::ErrorStatus setArrowType (Acm::ArrowType arrowType) = 0;

  virtual Acm::ErrorStatus getLineTypeId (AcDbObjectId& linetypeId) const = 0;
  virtual Acm::ErrorStatus setLineTypeId (const AcDbObjectId& linetypeId) = 0;

  // Update symbols according to LEAD/MSYM line properties
  virtual Acm::ErrorStatus getLineWeight (AcDb::LineWeight& lineweight) const = 0;

  //virtual Acm::ErrorStatus getArrowScale (double& scale) const = 0;
  //virtual Acm::ErrorStatus setArrowScale(double v) = 0;
  virtual double symbolScale() const = 0;

  virtual Acm::ErrorStatus getColor (Adesk::Int16& color) const = 0;     
  virtual Acm::ErrorStatus setColor(Adesk::Int16 v) = 0;

  virtual void getCoordSystem(AcGePoint3d&, AcGeVector3d&, AcGeVector3d&, AcGeVector3d&) const = 0;

  // Setting & Querying geometry
  //
  virtual AcGePoint3d tipPoint () const = 0;
  virtual Acm::ErrorStatus setTipPoint (const AcGePoint3d& newPt) = 0;
  //following function returns normal to the leader plane
  virtual AcGeVector3d normal() const = 0;

  virtual AcGeVector3d landing() const = 0;
  //virtual Acm::ErrorStatus getLanding (AcGeVector3d& landing) const = 0;
  virtual Acm::ErrorStatus setLanding (const AcGeVector3d &landing) = 0;

  virtual Acm::ErrorStatus appendPoint (const AcGePoint3d &endPoint) = 0;
  virtual Acm::ErrorStatus appendPoints (const AcGePoint3dArray &endPoint) =0;
  virtual Acm::ErrorStatus removePoint () = 0;

  virtual Acm::ErrorStatus getNonDrawingDistance (double& v) const = 0;
  virtual Acm::ErrorStatus setNonDrawingDistance (double v) = 0;

  // geometry change notification sent to owner
  // change a value of tip point.
  //
  //virtual void tipPointChanged() const = 0;
  // change a value of landing
  //
  //virtual void landingChanged() const = 0;
  // point has been added to laeder
  // 
  //virtual void pointAppended() const = 0;

  // Access interna leader structure
  //
  virtual AcmCLeaderNodeIterator* newNodeIterator() const = 0;
  //virtual const AcmCLeaderNodeIterator* newNodeIteratorConst() const = 0;

  //Osnap Points support
  //
  virtual Acad::ErrorStatus   getOsnapPoints(
				 AcDb::OsnapMode     osnapMode,
				 INT_PTR             gsSelectionMark,
				 const AcGePoint3d&  pickPoint,
				 const AcGePoint3d&  lastPoint,
				 const AcGeMatrix3d& viewXform,
				 AcGePoint3dArray&   snapPoints,
				 AcDbIntArray&       geomIds) const = 0;

  // Grip Points support
  //
  virtual int numOfGripPoints() const = 0;
  virtual Acad::ErrorStatus getGripPoints(AcGePoint3dArray& gripPoints,
			AcDbIntArray& osnapModes,
			AcDbIntArray& geomIds) const = 0;
  virtual Acad::ErrorStatus moveGripPointsAt(const AcDbIntArray& indices,
			const AcGeVector3d& offset) = 0; 
  virtual Acad::ErrorStatus moveStretchPointsAt(const AcDbIntArray& indices,
                                                const AcGeVector3d& offset) = 0;
  
  virtual Acad::ErrorStatus transformBy(const AcGeMatrix3d& trans) = 0;

  // GS Marker support
  //
  virtual INT_PTR numOfGsMarkers() const = 0;
  //creates a new AcmCAuxEntity. Caller is responsible for free memory
  virtual Acm::ErrorStatus getSegFromGSMarker(INT_PTR marker, AcmCAuxEntity*&) const = 0;

  // Geometry reference Support
  // 
  virtual Acm::ErrorStatus attachGeomRef(const void* pGeometry,
                                         const AcDbObjectId& view,
                                         const AcGePoint3d& prevLocation , // this parameter is used as arrowhead location
                                         Adesk::Boolean hasReactor = Adesk::kFalse) = 0;
  virtual Acm::ErrorStatus attachGeomRef(const void* pGeometry,
                                         const AcGePoint3d& prevLocation , // this parameter is used as arrowhead location
                                         Adesk::Boolean hasReactor = Adesk::kFalse) = 0;
  virtual Acm::ErrorStatus detachGeomRef() = 0;
  virtual void releaseGeomRef() = 0;

  // I/O support
  //
  virtual Acad::ErrorStatus dwgInFields (AcDbDwgFiler* filer, Adesk::UInt16) = 0;
  virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* filer) const = 0;
  virtual Acad::ErrorStatus dxfInFields (AcDbDxfFiler* filer) = 0;
  virtual Acad::ErrorStatus dxfOutFields(AcDbDxfFiler* filer) const = 0;

  virtual Acm::ErrorStatus getTrueColor (AcCmColor & color) const = 0;     
  virtual Acm::ErrorStatus setTrueColor(const AcCmColor & v) = 0;
  
  virtual void setArrowheadDir(const AcGeVector3d& vec) = 0;
  virtual AcGeVector3d arrowheadDir() const = 0;

  virtual double arrowScale() const = 0;
  virtual void setArrowScale(double scale) = 0;

  virtual AcmSymbol* getOwner() const = 0;
};

inline
AcmCLeader::~AcmCLeader()
{
}

class DllImpExp AcmCLeaderNodeIterator
{
  public :

  virtual ~AcmCLeaderNodeIterator();
  // Walking through
  //
  virtual void start(Adesk::Boolean onlyLeafNodes = Adesk::kFalse) = 0;
  virtual void step( Adesk::Boolean backwards = Adesk::kFalse) = 0;
  virtual Adesk::Boolean parent() = 0;
  virtual Adesk::Boolean done() const = 0;

  // Finding node
  //
  virtual Acm::ErrorStatus find(const AcGePoint3d& pt, bool fromTipPoint = true)=0;
  virtual Acm::ErrorStatus findClosest(const AcGePoint3d& pt)=0;
  virtual Acm::ErrorStatus findByGrip(int indice)=0;

  // Setting & Querying Current Node
  // 
  virtual Adesk::Boolean isLeafNode() const = 0;
  virtual AcmCLeaderNodeIterator* newNodeIterator(int branch) const = 0;
  virtual int numOfBranches() const = 0;
  virtual Acm::ErrorStatus trim() = 0;
  
  virtual Acm::ErrorStatus addLeader(const AcGePoint3dArray &ptrArray) = 0;
  virtual Acm::ErrorStatus removeLeader() = 0;
  virtual Acm::ErrorStatus insertBefore(const AcGePoint3d &pt) = 0;
  virtual Acm::ErrorStatus remove() = 0;

  virtual AcGePoint3d vertex() const = 0;
  virtual Acm::ErrorStatus setVertex(const AcGePoint3d& newPoint) =0;
  virtual Acad::ErrorStatus transformBy(const AcGeMatrix3d& trans) = 0;

  // Geometry reference Support
  // 
  virtual Adesk::Boolean isAttachedToView(AcDbObjectId& viewId) const = 0;
  virtual Adesk::Boolean isAttachedNoView() const = 0;
  virtual AcDbObjectId viewId() const = 0;
 
  virtual Acm::ErrorStatus attachGeomRef(const void* pGeometry,
                                         const AcDbObjectId& view,
                                         const AcGePoint3d& prevLocation, //this parameter is used as arrowhead location,
                                         Adesk::Boolean hasReactor = Adesk::kFalse) = 0;
  virtual Acm::ErrorStatus attachGeomRef(const void* pGeometry,
                                         const AcGePoint3d& prevLocation, //this parameter is used as arrowhead location,
                                         Adesk::Boolean hasReactor = Adesk::kFalse) = 0;
  virtual Acm::ErrorStatus detachGeomRef() = 0;
  virtual void releaseGeomRef() = 0;
};

inline
AcmCLeaderNodeIterator::~AcmCLeaderNodeIterator()
{
}

#endif // _LEADER_H
