//
#ifndef __SURFSYM_H
#define __SURFSYM_H

#ifndef __ACMDEF_H
	#error include 'acmdef.h' before including this file
#endif
#ifndef __CAUXENT_H
	#error include 'cauxent.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.
//
/////////////////////////////////////////////////////////////////////
class AcmSymbolStd;
class AcmCSurfText;
class AcmCSurfTextImp;
class AcmCAttach;
class AcmSurfTextStdImp;

class DllImpExp AcmSurfTextStd : public AcmSymbolStd
{
  friend class AcmSymbbInternals;
public:
  ACRX_DECLARE_MEMBERS(AcmSurfTextStd);

  virtual ~AcmSurfTextStd();

  Adesk::Boolean fitCircle() const;
  void setFitCircle(Adesk::Boolean val);

  Adesk::Boolean forceTail() const;
  void setForceTail(Adesk::Boolean val);

  Adesk::Boolean productionMultiline() const;
  void setProductionMultiline(Adesk::Boolean val);

  Adesk::Boolean allAroundAllowed() const;
  void setAllAroundAllowed(Adesk::Boolean val);

  Adesk::Boolean majorityAllowed() const;
  void setMajorityAllowed(Adesk::Boolean val);

  Adesk::Boolean fullList() const;
  void setFullList(Adesk::Boolean v);

  void getLaySymbols(AcDbIntArray& array) const;
  void setLaySymbols(const AcDbIntArray& array);

  virtual Adesk::Boolean setFactoryDefaults();
  virtual void setDefaultSubSymbol(AcmCSurfText* pData) const;

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

  virtual Adesk::Boolean getLaySymbolList(AcmCObjArray<AcmCSymbolDesc>& list,
                                          const AcmCSurfText* pSubSym =NULL) const;

  virtual Adesk::Boolean setLaySymbolList(AcmCObjArray<AcmCSymbolDesc>& list);
  
  virtual Acm::ErrorStatus checkVisibility(AcmCSurfText* pData) const;

  virtual Acm::ErrorStatus initFields(AcmCSurfText* pData) const;
  
  virtual Acm::ErrorStatus setSuggested(AcmCSurfText* pData) const;

  enum Variable {
    kAllAround = 0,
    kMajorityAllowed,
    kFitCircle,
    kForceTail,
    kProdMultiLine,
    kFullList
  };

  virtual Acad::ErrorStatus getSuggestedList(Acm::Variable var, CStringList& strList) const;

  virtual void setSuggestedList(Acm::Variable var, CStringList& strList);

  virtual void getSubEnts(const AcmCSurfText* pSymb,
                          AcmCAuxEntArray& subents) const;

  virtual bool getSubEntsProd1(const AcmCSurfText* pSubSym,
                               AcmCAuxEntArray& subents,
                               AcDbExtents& fullExtent,
                               double txtHeight,
                               double& commonWidth,
                               AcGePoint3d& refPoint) const;
  virtual bool getSubEntsSampLen(const AcmCSurfText* pSubSym,
                                 AcmCAuxEntArray& subents,
                                 AcDbExtents& fullExtent,
                                 double txtHeight,
                                 double& commonWidth,
                                 AcGePoint3d& refPoint) const;
  virtual bool getSubEntsOtherVal(const AcmCSurfText* pSubSym,
                                  AcmCAuxEntArray& subents,
                                  AcDbExtents& fullExtent,
                                  double txtHeight,
                                  double& commonWidth,
                                  AcGePoint3d& refPoint) const;
  virtual bool getSubEntsOtherMin(const AcmCSurfText* pSubSym,
                                  AcmCAuxEntArray& subents,
                                  AcDbExtents& fullExtent,
                                  double txtHeight,
                                  double& commonWidth,
                                  AcGePoint3d& refPoint) const;
  virtual bool getSubEntsComment(const AcmCSurfText* pSubSym,
                                 AcmCAuxEntArray& subents,
                                 AcDbExtents& fullExtent,
                                 double txtHeight,
                                 double& commonWidth,
                                 AcGePoint3d& refPoint) const;
  virtual bool getSubEntsReference(const AcmCSurfText* pSubSym,
                                   AcmCAuxEntArray& subents,
                                   AcDbExtents& fullExtent,
                                   double txtHeight,
                                   double& commonWidth,
                                   AcGePoint3d& refPoint) const;
  virtual bool getSubEntsWaviness(const AcmCSurfText* pSubSym,
                                  AcmCAuxEntArray& subents,
                                  AcDbExtents& fullExtent,
                                  double txtHeight,
                                  double& commonWidth,
                                  AcGePoint3d& refPoint) const;
  virtual bool getSubEntsCutoff(const AcmCSurfText* pSubSym,
                                AcmCAuxEntArray& subents,
                                AcDbExtents& fullExtent,
                                double txtHeight,
                                double& commonWidth,
                                AcGePoint3d& refPoint) const;
  virtual bool getSubEntsDirLay(const AcmCSurfText* pSubSym,
                                AcmCAuxEntArray& subents,
                                AcDbExtents& fullExtent,
                                double txtHeight,
                                const AcCmColor & txtColor,
                                AcGePoint3d& refPoint) const;
  virtual bool getSubEntsAllowance(const AcmCSurfText* pSubSym,
                                   AcmCAuxEntArray& subents,
                                   AcDbExtents& fullExtent,
                                   double txtHeight,
                                   double& commonWidth,
                                   AcGePoint3d& refPoint) const;
  virtual bool getSubEntsRaMax(const AcmCSurfText* pSubSym,
                               AcmCAuxEntArray& subents,
                               AcDbExtents& fullExtent,
                               double txtHeight,
                               double& commonWidth,
                               AcGePoint3d& refPoint,
                               Adesk::Boolean isOnlyRaValue) const;
  virtual bool getSubEntsRaMin(const AcmCSurfText* pSubSym,
                               AcmCAuxEntArray& subents,
                               AcDbExtents& fullExtent,
                               double txtHeight,
                               double& commonWidth,
                               AcGePoint3d& refPoint,
                               Adesk::Boolean isOnlyRaValue) const;
  virtual bool getSubEntsFirstReq(const AcmCSurfText* pSubSym,
                                  AcmCAuxEntArray& subents,
                                  AcDbExtents& fullExtent,
                                  double txtHeight,
                                  double& commonWidth,
                                  AcGePoint3d& refPoint) const;
  virtual bool getSubEntsSecondReq(const AcmCSurfText* pSubSym,
                                   AcmCAuxEntArray& subents,
                                   AcDbExtents& fullExtent,
                                   double txtHeight,
                                   double& commonWidth,
                                   AcGePoint3d& refPoint) const;
  virtual bool getSubEntsThirdReq(const AcmCSurfText* pSubSym,
                                  AcmCAuxEntArray& subents,
                                  AcDbExtents& fullExtent,
                                  double txtHeight,
                                  double& commonWidth,
                                  AcGePoint3d& refPoint) const;
  virtual bool getSubEntsFourthReq(const AcmCSurfText* pSubSym,
                                   AcmCAuxEntArray& subents,
                                   AcDbExtents& fullExtent,
                                   double txtHeight,
                                   double& commonWidth,
                                   AcGePoint3d& refPoint) const;

  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 Acm::Visibility variableStatus(AcmSurfTextStd::Variable var) const;
  virtual void setVariableStatus(AcmSurfTextStd::Variable var,
                                 Acm::Visibility status);

  enum ConfigListState  {
    kHidden,
    kDisplayOnly,
    kEditable
  };

  virtual Acad::ErrorStatus getDlgIndexFromVar(Acm::Variable var, Adesk::UInt8& dlgIndex) const;
  virtual Acad::ErrorStatus getVarFromDlgIndex(Adesk::UInt8 dlgIndex, Acm::Variable& var) const;
  virtual AcmSurfTextStd::ConfigListState checkConfigListState(Acm::Variable var, CVarDlgInfo& varDlgInfo) const;
  virtual void getPropertiesDlgLabel(Acm::Variable var, CString& label) const;
  virtual void restoreAllSuggestedList();
  virtual void restoreSuggestedList(Acm::Variable var);
  virtual void getDefaultLaySymbols(AcDbIntArray& symArray) const;
  virtual void getDefaultVarSuggestList(Acm::Variable var, CStringList& list) const;
  virtual void getDefaultCutOffList(CStringList& list) const;
  virtual void getDefaultWavinessList(CStringList& list) const;
  virtual void getDefaultRoughnessList(CStringList& list) const;
  virtual void getDefaultProductionNoteList(CStringList& list) const;
  virtual void getDefaultBaseLengthsList(CStringList& list)const;

protected:
  AcmSurfTextStd();

  virtual void getBasicSymbol(const AcmCSurfText* pSymb,
                              double H1, double H2,Adesk::UInt16 symColor,
                              double txtHeight, double tailLength,
                              AcmCAuxEntArray& subents) const;

  virtual void getBasicSymbol(const AcmCSurfText* pSymb,
                              double H1, double H2,const AcCmColor & symColor,
                              double txtHeight, double tailLength,
                              AcmCAuxEntArray& subents) const;

  virtual void getMajoritySymbol(const AcmCSurfText* pSubSym,
                                 AcmCAuxEntArray& subents) const;

  virtual void getHeights(const AcmCSurfText*,
                          AcGeDoubleArray&) const;

  virtual void getHeights(const AcmCSurfText* pSymb,
                          double& H1,
                          double& H2) const;
  
  virtual void getBasicArray(const AcGeDoubleArray heights,
                             AcGePoint3dArray& basicpoints) const;

  virtual double getHeightCorrect(const AcmCSurfText* pSubSym) const;

  virtual double getTailLength(const AcmCSurfText* pSubSym,
                               AcDbExtents& fullExtent,
                               AcGePoint3d& refPoint) const;

  virtual void getLaySymbol(int type,
                      const AcCmColor & textColor, double txtHeight,
                      AcmCAuxEntArray& subents) const;

  virtual void getLaySymbol(int type,
                      Adesk::UInt16 textColor, double txtHeight,
                      AcmCAuxEntArray& subents) const;

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

  AcmSurfTextStdImp* mpImp;
};
MAKE_ACDBOPENOBJECT_FUNCTION(AcmSurfTextStd);
DBREF_DECLARE(AcmSurfTextStd)

class AcmCSurfText : public AcmCSubSymbol
{
public:
  virtual void setAngle(double angle) = 0;
  virtual double angle() const = 0;

  virtual Adesk::Boolean hasLeader() const = 0;

  virtual Acm::SurfTextType subType() const = 0;
  virtual Acm::ErrorStatus setSubType(Acm::SurfTextType flag) = 0;

  virtual Adesk::Boolean autoAdjustment() const = 0;
  virtual Acm::ErrorStatus setAutoAdjustment(Adesk::Boolean adjust) = 0;
          
  virtual Adesk::Boolean isAllAround() const = 0;
  virtual Acm::ErrorStatus setAllAround(Adesk::Boolean flag) = 0;
          
  virtual Adesk::Boolean isMajority() const = 0;
  virtual Acm::ErrorStatus setMajority(Adesk::Boolean val) = 0;

  virtual Adesk::Boolean isForcedTail() const = 0;
  virtual Acm::ErrorStatus setForcedTail(Adesk::Boolean val) = 0;

  virtual Acm::DirectionLayType directionLay() const = 0;
  virtual Acm::ErrorStatus setDirectionLay(Acm::DirectionLayType type) = 0;
  virtual void getDirectionLayRange(int& minValue, int& maxValue) const = 0;
  virtual void setDirectionLayRange(int minValue, int maxValue) = 0;

  virtual void setLayFromCurve(const Adesk::Boolean lay) = 0;
  virtual Adesk::Boolean layFromCurve() const = 0;

  // Update symbols according to LEAD/MSYM line properties
  virtual AcDb::LineWeight getForceLineWeight() const = 0;

  // Get symbol's layer id
  virtual AcDbObjectId layerId() const = 0;
};  


class DllImpExp AcmSurfaceTexture: public AcmSymbol
{
public:
  ACRX_DECLARE_MEMBERS(AcmSurfaceTexture);

  AcmSurfaceTexture();
  virtual ~AcmSurfaceTexture();

  double angle() const;
  void setAngle(double angle);

  AcmCSurfText* subSymbol() const;

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

  Acm::SurfTextType subType() const;
  Acm::ErrorStatus setSubType(Acm::SurfTextType flag);

  Adesk::Boolean isAllAround() const;
  Acm::ErrorStatus setAllAround(Adesk::Boolean flag);
  
  Adesk::Boolean isMajority() const;
  Acm::ErrorStatus setMajority(Adesk::Boolean val);

  Adesk::Boolean isForcedTail() const;
  Acm::ErrorStatus setForcedTail(Adesk::Boolean val);

  Acm::DirectionLayType directionLay() const;
  Acm::ErrorStatus setDirectionLay(Acm::DirectionLayType type);
  
  void getDirectionLayRange(int& minValue, int& maxValue) const;
  void setDirectionLayRange(int minValue, int maxValue);

  void enableAutoAdjustment();
  void disableAutoAdjustment();
  Adesk::Boolean isAutoAdjustmentEnabled() const;
  virtual Acad::ErrorStatus autoAdjust();

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

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

  virtual Acm::ErrorStatus addLeader(const AcGePoint3dArray &ptrArray);
  virtual Acm::ErrorStatus removeLeader(Adesk::UInt16 index);

  virtual void regen();

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

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

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

  virtual Acad::ErrorStatus dwgInFields(AcDbDwgFiler*);
  virtual Acad::ErrorStatus dwgOutFields(AcDbDwgFiler*) const;
  virtual Acad::ErrorStatus dxfInFields(AcDbDxfFiler*);
  virtual Acad::ErrorStatus dxfOutFields(AcDbDxfFiler*) const;

  virtual Acad::ErrorStatus subErase(Adesk::Boolean erasing);
  virtual void modified(const AcDbObject* pDbObj);
  virtual void erased(const AcDbObject* pDbObj, 
    Adesk::Boolean erasing = Adesk::kTrue);

  // For scaling of individual surface texture symbols
  // While keeping the lineweight at 1/10 of the text height
  virtual void changeLineWeight(bool bIncLnWght);
  virtual AcDb::LineWeight getNearestLnWgt(int lnWgtVal) const;
	virtual void mirrorCoordSys(const AcGeMatrix3d& xMirrorForm,
                              AcGeVector3d& XAxis,
                              AcGeVector3d& YAxis,
                              AcGeVector3d& normal) const;

protected:
  virtual Adesk::Boolean    subWorldDraw(AcGiWorldDraw*);
  
  virtual void subList() const;

  virtual Acad::ErrorStatus subGetOsnapPoints(AcDb::OsnapMode, INT_PTR,
                                      const AcGePoint3d&, const AcGePoint3d&,
                                      const AcGeMatrix3d&, AcGePoint3dArray&,
                                      AcDbIntArray&) 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& indices,
                                             const AcGeVector3d& offset); 

  virtual Acad::ErrorStatus subGetStretchPoints(AcGePoint3dArray&) const;

  virtual Acad::ErrorStatus subMoveStretchPointsAt(const AcDbIntArray& indices,
                                                const AcGeVector3d& offset);

  virtual Acad::ErrorStatus subExplode(AcDbVoidPtrArray& entitySet) const;
  virtual Acad::ErrorStatus subGetGeomExtents(AcDbExtents&) const;
  virtual Acad::ErrorStatus subTransformBy(const AcGeMatrix3d& xform); 

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

private:
  AcmCSurfTextImp *mpSubSymbol;
};
MAKE_ACDBOPENOBJECT_FUNCTION(AcmSurfaceTexture);
DBREF_DECLARE(AcmSurfaceTexture)

#endif // __SURFSYM_H
