#ifndef __SECTIONSYM_H
#define __SECTIONSYM_H
//
//  (C) Copyright 1993-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.
//

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

class AcmSymbolStd;
class AmdtSectionSymC;
class AmdtSectionSymCImp;
class AmdtSectionSymStdImp;

// The two string constants are used for section label pattern
#define SECTION_LABEL_FIRST ACRX_T(/*MSG0*/"SECTION_LABEL_FIRST")
#define SECTION_LABEL_LAST  ACRX_T(/*MSG0*/"SECTION_LABEL_LAST")

class DllImpExp AmdtSectionSymStd : public AcmSymbolStd
{
  friend class AcmSymbbInternals;
  friend class AmdtSectionSymStdImp;
public:
  ACRX_DECLARE_MEMBERS(AmdtSectionSymStd);
  virtual ~AmdtSectionSymStd();

  enum LineVisibility {
    kContinuous = 0, // the whole cutting plane is marked with one linetype of one color
    kNoLines,       // only the breaks in cutting plane are marked
    kBetweenPlanes  // the break have one linetype and color, the lines between them have diff. color
  };

  void nextSectionNames(CStringArray& names, const int count) const;
  virtual CString defaultName(int count) const;

  LPCTSTR labelPattern() const;
  void setLabelPattern(const ACHAR* labelPattern);

  LineVisibility lineVisibility() const;
  void setLineVisibility(const LineVisibility lineVis);

  Adesk::Boolean showAnnot() const;
  void setShowAnnot(const Adesk::Boolean v);

  Adesk::Boolean showArrows() const;
  void setShowArrows(const Adesk::Boolean v);

  Adesk::Boolean labelAbove() const;
  void setLabelAbove(const Adesk::Boolean p);

  AcDbObjectId annotLineId() const;
  void setAnnotLineId(const AcDbObjectId& idType);

  LPCTSTR getAnnotLtypeName() const;
  Acad::ErrorStatus setAnnotLtypeName(LPCTSTR pName);

  AcDbObjectId textStyleId() const;
  void setTextStyleId(const AcDbObjectId& id);

  bool textStyleByStandard() const;
  void setTextStyleByStandard(bool byStandard);

  Adesk::UInt16 textColor() const;
  void setTextColor(Adesk::UInt16 color);  

  Adesk::Boolean showPlaneNames() const;
  void setShowPlaneNames(const Adesk::Boolean show);

  AcDb::LineWeight lineWeightOver() const;
  void setLineWeightOver(const AcDb::LineWeight weight);

  const AcCmColor & lineTrueColorOver() const;
  void setLineTrueColorOver(const AcCmColor & color);  

  Adesk::Int16 lineColorOver() const;
  void setLineColorOver(const Adesk::Int16 color);

  Adesk::Boolean multipleNamesSupported() const;
  void setMultipleNamesSupported(const Adesk::Boolean multiNames);

  virtual void setTextHeight(double txtHeight);
  virtual void setTextHeightByStandard(bool byStandard);

  virtual void setTextColorByStandard(bool byStandard);

  virtual double byStdTextHeight() const;
  virtual const AcCmColor & byStdTextTrueColor() const;

  // this method says whether the arrow is drawn as pointing towards the line (true)
  // or away from the line (false)
  virtual bool arrowToLine() const;

  Adesk::Boolean getLineWeightDesc(AcmCObjArray<AcmCDesc>& list);

  virtual void initToEdit();
  virtual void initToEditOriginal();

  virtual Adesk::Boolean setFactoryDefaults();
  virtual Acm::ErrorStatus onChangeUnits(Adesk::Boolean isMetric);
  virtual Acm::ErrorStatus getDescription(CString& desc,
                                          CBitmap*& pBmpLoaded,
                                          CBitmap*& pBmpReg,
                                          Adesk::Boolean& enablePref) const;

  virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler* filer);
  virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* filer) const;

  enum Variable {
    kLabelPattern = 0,
    kLabelAbove
  };

  virtual Acm::Visibility variableStatus(AmdtSectionSymStd::Variable var) const;
  virtual void setVariableStatus(AmdtSectionSymStd::Variable var, Acm::Visibility status);

  // sub ents for section annotation  
  virtual void getSubEnts(const AmdtSectionSymC* pSymb,AcmCAuxEntArray& subents) const;
  // sub ents for section view
  virtual void getSubEntsEnt(const AmdtSectionSymC* pSymb,AcmCAuxEntArray& subents) const;

  virtual void resetAnnotOffsets(AmdtSectionSymCImp* pSymb, bool allOffsets = true) const;

  virtual bool isHeightSizedUp() const;

  // avoid calling the APIs below
  double cornerSize() const;
  void setCornerSize(const double size);
  double arrowLineLength() const;
  void setArrowLineLength(const double size);
  double arrowLineOffset() const;
  void setArrowLineOffset(const double size);

protected:
  AmdtSectionSymStd();
  virtual Acad::ErrorStatus createDefaultLTypeAnnotLine(LPCTSTR pName);
  AcGeCircArc3d* getArcWithCenterPt(const AcGePoint3d& startPt, const AcGePoint3d& cent, const AcGePoint3d& endPt) const; 

  AmdtSectionSymStdImp* mpImp;

  virtual Acad::ErrorStatus subGetClassID(CLSID* pClsid) const;

};
MAKE_ACDBOPENOBJECT_FUNCTION(AmdtSectionSymStd);
DBREF_DECLARE(AmdtSectionSymStd)


class DllImpExp AmdtSectionSym : public AcmSymbol
{
public:
  ACRX_DECLARE_MEMBERS(AmdtSectionSym);
  AmdtSectionSym();
  virtual ~AmdtSectionSym();             

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

  AcGeVector3d sectionSide() const;
  void setSectionSide(const AcGeVector3d& side);

  int labelNamesCount() const;
  // set "at" to -1 for the last one
  LPCTSTR labelName(const int at = 0) const;
  bool setLabelName(const ACHAR* labelName, const int at = 0);
  void setLabelNames(const CStringArray& names);

  LPCTSTR labelPattern() const;
  void setLabelPattern(const ACHAR* labelPattern);
  // returns the evaluated pattern (with label name)
  CString labelText(/*const int at = 0*/) const;

  AcDbObjectId baseViewId() const;  
  AcDbObjectId sectionViewId() const;

  AcDbObjectId sectionEntId() const;
  void setSectionEntId(const AcDbObjectId& sectionEntId);

  AcGePoint3dArray sectionPoints() const;
  void setSectionPoints(const AcGePoint3dArray& sectionPoints);
  void addSectionPoint(const AcGePoint3d& point);
  void setSectionPointsAt(const int at, const AcGePoint3d& point);
  void eraseSectionPoints();

  void setSectionPoints(const AcGePoint3dArray& sectionPoints, const AcGePoint3dArray& arcPoints, const AcArray<Acm::SectionSymLineSegmentType>& lineSegmentType);  
  void setSectionArcPointsAt(const int at, const AcGePoint3d& arcPoint, Acm::SectionSymLineSegmentType segmentType=Acm::kArcSegmentCenter);
  Acm::SectionSymLineSegmentType sectionLineSegmentType(const int index, AcGePoint3d& arcPoint) const;

  AmdtSectionSymStd::LineVisibility lineVisibility() const;
  void setLineVisibility(const AmdtSectionSymStd::LineVisibility lineVis);
  Adesk::Boolean showAnnot() const;
  void setShowAnnot(const Adesk::Boolean v);
  Adesk::Boolean showArrows() const;
  void setShowArrows(const Adesk::Boolean v);
  Adesk::Boolean showPlaneNames() const;
  void setShowPlaneNames(const Adesk::Boolean v);

  LPCTSTR value(Acm::Variable var) const;
  Acm::ErrorStatus setValue(Acm::Variable var, LPCTSTR value);

  Acm::Visibility  variableStatus(Acm::Variable var) const;
  Acm::ErrorStatus setVariableStatus(Acm::Variable var, Acm::Visibility status);

  Acm::ErrorStatus getVarDlgInfo(Acm::Variable var,CVarDlgInfo& v) const;
  Acm::ErrorStatus setVarDlgInfo(Acm::Variable var,const CVarDlgInfo& v);

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

  virtual AmdtSectionSymC* subSymbol() const;

  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;

  virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler* filer);
  virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* filer) const;
  virtual Acad::ErrorStatus dxfOutFields(AcDbDxfFiler* filer) const;
  virtual Acad::ErrorStatus subErase(Adesk::Boolean pErasing);

  Acad::ErrorStatus makeSectionEnt(const AcGePoint3d& origin,
                                  const AcDbObjectId& detailViewId,  
                                  const AcDbObjectId& entOwnerId = NULL);

  void regen();
  
  virtual Acm::ErrorStatus addLeader(const AcGePoint3dArray &ptrArray);
  virtual Acm::ErrorStatus removeLeader(Adesk::UInt16 index);
  
  // avoid calling the APIs below
  AcGeVector3d labelOffset() const;
  void setLabelOffset(const AcGeVector3d& offset);
  double arrowLineLength() const;
  void setArrowLineLength(const double size);
  double arrowLineOffset() const;
  void setArrowLineOffset(const double size);
  AcGeVector3dArray annotOffsets() const;
  void setAnnotOffsets(const AcGeVector3dArray& offsets);
  void setAnnotOffsetsAt(const AcGeVector3d& offset, const int at);
  void resetAnnotOffsets();

protected:
  virtual Adesk::Boolean    subWorldDraw(AcGiWorldDraw* mode);

  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& indices,
                                             const AcGeVector3d& offset); 

  virtual Acad::ErrorStatus subExplode(AcDbVoidPtrArray& entitySet) const;

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

  virtual Acad::ErrorStatus subGetClassID(CLSID* pClsid) const;

  virtual Acad::ErrorStatus subDeepClone(AcDbObject* pOwner, 
                                      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 subIntersectWith(const AcDbEntity* ent,
                                        AcDb::Intersect intType,
                                        AcGePoint3dArray& points,
                                        INT_PTR thisGsMarker,
                                        INT_PTR otherGsMarker) const;

  virtual Acad::ErrorStatus subGetGeomExtents(AcDbExtents&) const;

  AmdtSectionSymCImp* mpSubSymbol;

private:
  Acad::ErrorStatus changeArrowLineOffset(const AcGePoint3dArray& pts, 
                                          const AcGeVector3d& offset,
                                          bool isFirstArrow = true);

  Acad::ErrorStatus changeArrowLineLength(const AcGePoint3dArray& pts, 
                                          const AcGeVector3d& offset,
                                          bool isFirstArrow = true);

};    
MAKE_ACDBOPENOBJECT_FUNCTION(AmdtSectionSym);
DBREF_DECLARE(AmdtSectionSym);

class AmdtSectionSymC : public AcmCSubSymbol
{
public:
  virtual AcGeVector3d labelOffset() const = 0;
  virtual void setLabelOffset(const AcGeVector3d& offset) = 0;

  virtual AcGeVector3d sectionSide() const = 0;
  virtual void setSectionSide(const AcGeVector3d& side) = 0;

  virtual double arrowLineLength() const = 0;
  virtual void setArrowLineLength(const double size) = 0;

  virtual double arrowLineOffset() const = 0;
  virtual void setArrowLineOffset(const double size) = 0;

  virtual AcGeVector3dArray annotOffsets() const = 0;
  virtual void setAnnotOffsets(const AcGeVector3dArray& offsets) = 0;
  virtual void setAnnotOffsetsAt(const AcGeVector3d& offset, const int at) = 0;
  virtual AcGeVector3d getAnnotOffsetsAt(const int at) = 0;

  // set "at" to -1 for the last one
  virtual LPCTSTR labelName(const int at = 0) const = 0;
  virtual bool setLabelName(const ACHAR* labelName, const int at = 0) = 0;
  virtual void setLabelNames(const CStringArray& names) = 0;
  virtual int labelNamesCount() const = 0;

  virtual LPCTSTR labelPattern() const = 0;
  virtual void setLabelPattern(const ACHAR* labelPattern) = 0;

  virtual CString labelText(/*const int at = 0*/) const = 0;

  virtual AcGePoint3dArray sectionPoints() const = 0;
  virtual void setSectionPoints(const AcGePoint3dArray& sectionPoints, const AcArray<bool>& isVertex) = 0;
  virtual void addSectionPoint(const AcGePoint3d& point, const bool isVertex = true) = 0;
  virtual void setSectionPointsAt(const int at, const AcGePoint3d& point, const bool isVertex = true) = 0;
  virtual void eraseSectionPoints() = 0;

  virtual bool isVertex(const int index) const = 0;

  virtual void setSectionPoints(const AcGePoint3dArray& sectionPoints, const AcArray<bool>& isVertex, const AcGePoint3dArray& arcPoints, const AcArray<Acm::SectionSymLineSegmentType>& lineSegmentType) = 0;  
  virtual void setSectionArcPointsAt(const int at, const AcGePoint3d& arcPoint, Acm::SectionSymLineSegmentType segmentType=Acm::kArcSegmentCenter) =  0;
  virtual Acm::SectionSymLineSegmentType sectionLineSegmentType(const int index, AcGePoint3d& arcPoint) const = 0;

  virtual AmdtSectionSymStd::LineVisibility lineVisibility() const = 0;
  virtual void setLineVisibility(const AmdtSectionSymStd::LineVisibility lineVis) = 0;
  virtual Adesk::Boolean showAnnot() const = 0;
  virtual void setShowAnnot(const Adesk::Boolean v) = 0;
  virtual Adesk::Boolean showArrows() const = 0;
  virtual void setShowArrows(const Adesk::Boolean v) = 0;
  virtual Adesk::Boolean showPlaneNames() const = 0;
  virtual void setShowPlaneNames(const Adesk::Boolean v) = 0;

  // some recalls to AcmSymbol needed for getSubEnts in AmdtSectionSymStd
  virtual double scale() const = 0;
  virtual AcGeVector3d normal() const = 0;
};

#endif // __SECTIONSYM_H
