
//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 2007-2009 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.
//

#pragma once
#include "AcGeomConstraint.h"
#pragma pack (push, 8)

/// <summary>
/// This class represents a dimensional constraint node in the owning AcDbAssoc2dConstraintGroup.
/// It is the base class for all the kind of dimensional constraints.
/// </summary>
///
class ACDB_PORT AcExplicitConstraint : public AcGeomConstraint
{
public:
  ACRX_DECLARE_MEMBERS(AcExplicitConstraint);

  /// <summary> 
  /// Returns AcDbObjectId of the AcDbAssocValueDependency object referenced
  /// by this dimensional constraint.
  /// </summary>
  /// <returns> AcDbObjectId. </returns>
  ///
  AcDbObjectId valueDependencyId() const;

  /// <summary> 
  /// Returns AcDbObjectId of the dimension dependency object referenced
  /// by this dimensional constraint.
  /// </summary>
  /// <returns> AcDbObjectId. </returns>
  ///
  AcDbObjectId dimDependencyId() const;

  /// <summary> 
  /// Set the dimension dependency object referenced
  /// by this dimensional constraint.
  /// </summary>
  /// <param name="dimDependencyId">
  /// Input AcDbObjectId of the new dimension dependency object
  /// </param>
  /// <returns> Acad::eOk if successful </returns>
  ///
  Acad::ErrorStatus setDimDependencyId(const AcDbObjectId& dimDependencyId);

  /// <summary>
  /// Returns the value of the dimensional constraint measured from the
  /// distances/angles/radii of the constained geometries. It the constraint 
  /// is satisfied, it is the same value as the dimension value obtained from 
  /// the AcDbAssocVariable.
  /// </summary>
  ///
  Acad::ErrorStatus getMeasuredValue(double&) const;

protected:

  /// <summary> 
  /// Protected default constructor. 
  /// </summary>
  /// 
  AcExplicitConstraint(){};
};

/// <summary>
/// This class represents a distance constraint node in the owning AcDbAssoc2dConstraintGroup.
/// It can be applied between two constrained geometries (normally two points).
/// </summary>
///
class ACDB_PORT AcDistanceConstraint: public AcExplicitConstraint
{ 
public:
  ACRX_DECLARE_MEMBERS(AcDistanceConstraint);

  /// <summary>
  /// The direction type of this distance constraint. It is mainly used to 
  /// indicate how the distance between the two geometries are measured.
  /// </summary>
  ///
  enum DirectionType
  {
    /// <summary>
    /// Not directed distance.
    /// The minimum distance between the two geometries is measured.
    /// </summary>
    ///
    kNotDirected         = 0,

    /// <summary>
    /// Directed distance with fixed direction.
    /// The distance between the two geometries is measured along the fixed direction.
    /// </summary>
    ///
    kFixedDirection         ,

    /// <summary>
    /// Directed distance with relative direction.
    /// The distance between the two geometries is measured along the direction
    /// which is perpendicular to an existing constraint line.
    /// </summary>
    ///
    kPerpendicularToLine    ,

    /// <summary>
    /// Directed distance with relative direction.
    /// The distance between the two geometries is measured along the direction
    /// which is parallel to an existing constraint line.
    /// </summary>
    ///
    kParallelToLine
  };

  /// <summary> 
  /// Default constructor.
  /// The direction type is set to kNotDirected.
  /// </summary>
  /// 
  AcDistanceConstraint();

  /// <summary> 
  /// Constructor.
  /// The direction type is set to kFixedDirection.
  /// </summary>
  /// <param name="direction">
  /// Input AcGeVector3d indicating the fixed direction which is used to
  /// measure the distance. The vector length must not be zero.
  /// </param>
  /// 
  AcDistanceConstraint(const AcGeVector3d& direction);

  /// <summary> 
  /// Constructor.
  /// The direction type is set to kPerpendicularToLine or kParallelToLine.
  /// </summary>
  /// <param name="consLineId">
  /// Input AcConstraintGroupNodeId indicating the constrained line whose direction
  /// is used to measure the distance.
  /// </param>
  /// <param name="type">
  /// Input DirectionType indicating the direction type which must be either
  /// kPerpendicularToLine or kParallelToLine.
  /// </param>
  /// 
  AcDistanceConstraint(const AcConstraintGroupNodeId consLineId, DirectionType type = kPerpendicularToLine);

  /// <summary>
  /// Returns the direction type of this distance constraint.
  /// </summary>
  /// <returns> Returns DirectionType. </returns>
  ///
  DirectionType directionType() const;

  /// <summary>
  /// Returns the fixed direction of this distance constraint.
  /// Only valid when the direction type is kFixedDirection.
  /// </summary>
  /// <returns> Returns AcGeVector3d. </returns>
  ///
  AcGeVector3d                    direction()           const;

  /// <summary>
  /// Returns the constrained line id.
  /// Only valid when the direction type is kPerpendicularToLine or kParallelToLine.
  /// </summary>
  /// <returns> Returns AcConstraintGroupNodeId. </returns>
  ///
  AcConstraintGroupNodeId         constrainedLineId()   const;
};

/// <summary>
/// This class represents a angle constraint node in the owning AcDbAssoc2dConstraintGroup.
/// It can be applied between two constrained lines.
/// </summary>
///
class ACDB_PORT AcAngleConstraint: public AcExplicitConstraint 
{ 
public:
  ACRX_DECLARE_MEMBERS(AcAngleConstraint);

  /// <summary>
  /// The angle sector type of this angle constraint. It is used to 
  /// indicate how the angle between the two lines is measured.
  /// </summary>
  ///
  enum SectorType
  {
    /// <summary>
    /// The angle measured from the forward direction of line 1 to 
    /// the forward direction of line 2 anticlockwise.
    /// </summary>
    ///
    kParallelAntiClockwise = 0,

    /// <summary>
    /// The angle measured from the forward direction of line 1 to 
    /// the non forward direction of line 2 clockwise.
    /// </summary>
    ///
    kAntiParallelClockwise    ,

    /// <summary>
    /// The angle measured from the forward direction of line 1 to 
    /// the forward direction of line 2 clockwise.
    /// </summary>
    ///
    kParallelClockwise        ,

    /// <summary>
    /// The angle measured from the forward direction of line 1 to 
    /// the non forward direction of line 2 anticlockwise.
    /// </summary>
    ///
    kAntiParallelAntiClockwise    
  };

  /// <summary> 
  /// Default constructor.
  /// The angle sector type is set to kParallelAntiClockwise.
  /// </summary>
  /// 
  AcAngleConstraint();

  /// <summary> 
  /// Constructor.
  /// </summary>
  /// <param name="type">
  /// Input SectorType indicating the angle sector which is used to
  /// measure the angle.
  /// </param>
  /// 
  AcAngleConstraint(AcAngleConstraint::SectorType type);

  /// <summary>
  /// Returns the angle sector type of this angle constraint.
  /// </summary>
  /// <returns> Returns SectorType. </returns>
  ///
  SectorType sectorType() const;

  /// <summary> <para>
  /// Sets a multiplier that is used to multiply angles obtained from 
  /// AcDbAssocValueDependencies that depend on AcDbAssocVariables to convert
  /// the angles to radians. It is needed because the expression evaluator used 
  /// by AcDbAssocVariables considers all angles to be in degrees. To convert
  /// from degrees to radians, the multiplier needs to be set to Pi/180.
  /// If no angle multiplier is set, the default is Pi/180.
  /// </para> <para>
  /// For now there is just one global multiplier so that AcDbAssocVariables 
  /// can store angles in degrees, not in radians.  It is just a stop gap 
  /// measure until we figure out how to handle units. 
  /// </para> </summary>
  /// <param name="multiplier"> The angle multiplication factor. </param>
  ///
  static void setAngleMultiplier(double multiplier);

  /// <summary> Returns the current angle multipiler. </summary>
  /// <returns> The current angle multipiler. The default is Pi/180.</returns>
  ///
  static double angleMultiplier();
};

/// <summary>
/// This class represents a angle constraint node in the owning AcDbAssoc2dConstraintGroup.
/// It can be applied between 3 constrained points.
/// </summary>
///
class ACDB_PORT Ac3PointAngleConstraint: public AcAngleConstraint 
{ 
public:
  ACRX_DECLARE_MEMBERS(Ac3PointAngleConstraint);

  /// <summary> 
  /// Default constructor.
  /// The angle sector type is set to kParallelAntiClockwise.
  /// </summary>
  /// 
  Ac3PointAngleConstraint();

  /// <summary> 
  /// Constructor.
  /// </summary>
  /// <param name="type">
  /// Input SectorType indicating the angle sector which is used to
  /// measure the angle.
  /// </param>
  /// 
  Ac3PointAngleConstraint(AcAngleConstraint::SectorType type);
};

/// <summary>
/// This class represents a radius or diameter constraint node in the owning AcDbAssoc2dConstraintGroup.
/// It can be applied on one circle(arc) or ellipse(bounded ellipse).
/// </summary>
///
class ACDB_PORT AcRadiusDiameterConstraint : public AcExplicitConstraint
{
public:
  ACRX_DECLARE_MEMBERS(AcRadiusDiameterConstraint);

  /// <summary>
  /// The constraint type of this constraint. It is used to 
  /// indicate whether radius or diameter is measured.
  /// </summary>
  ///
  enum RadiusDiameterConstrType
  { 
    /// <summary>
    /// The radius of a constrained circle or arc is measured.
    /// </summary>
    ///
    kCircleRadius   = 0,

    /// <summary>
    /// The diameter of a constrained circle or arc is measured.
    /// </summary>
    ///
    kCircleDiameter    ,

    /// <summary>
    /// The minor radius of a constrained (bounded) ellipse is measured.
    /// </summary>
    ///
    kMinorRadius       ,

    /// <summary>
    /// The major radius of a constrained (bounded) ellipse is measured.
    /// </summary>
    ///
    kMajorRadius
  }; 

  /// <summary> 
  /// Default constructor.
  /// The constraint type is set to kCircleRadius.
  /// </summary>
  /// 
  AcRadiusDiameterConstraint();

  /// <summary> 
  /// Constructor.
  /// </summary>
  /// <param name="type">
  /// Input RadiusDiameterConstrType indicating the constraint type.
  /// </param>
  /// 
  AcRadiusDiameterConstraint(RadiusDiameterConstrType type);

  /// <summary>
  /// Returns the constraint type of this constraint.
  /// </summary>
  /// <returns> Returns RadiusDiameterConstrType. </returns>
  ///
  RadiusDiameterConstrType constrType() const;
};

#pragma pack (pop)
