/***************************************************************************
 *                          Zanoza Modeler v2.x                            *
 *      This is unpublished propietary source code of Zanoza Software.     *
 *      The copyright notice does not evidence any actual or intended      *
 *                    publication of such source code.                     *
 *                                                                         *
 *                   Copyright (c) 2002 Zanoza Software.                   *
 *                                                                         *
 *                        All rights reserved.                             *
 ***************************************************************************
 *--------------------------------------------------------------------------
 * @author:   Oleg M.
 *--------------------------------------------------------------------------
 * @purpose:  ZModeler's native 3d line
 *--------------------------------------------------------------------------
 * @histroy: 05.06.2003. Created
 */
#ifndef zline3d_h_included
#define zline3d_h_included

#ifndef zsequence_h_included
# include "zsequence.h"
#endif


//------------------------------------------------------
//  ZLine3D - ZModeler's native 3D line
//------------------------------------------------------
class DLL_LINKAGE ZLine3D
{
public:
  //type of lines
  enum eLineType
  {
    LINE,       // infinite line (-inf, +inf)
    RAY,        // ray [0, +inf)
    SEGMENT     // section [0, 1]
  };
  //
  // constructors/destructors
  //
  ZLine3D();
  ZLine3D(const ZPoint3D pt1, const ZPoint3D pt2, const eLineType t = SEGMENT);
  ZLine3D(const ZLine3D& line);
  ~ZLine3D();

public:
  //
  // access grants
  //
  ZPoint3D& operator [] ( int npoint ); // npoint is 0 or 1
  ZPoint3D  operator [] ( int npoint ) const;


public:
  //
  // assignment operators
  //
  ZLine3D& operator =  ( const ZLine3D& l);



public:
  //
  // compare operators
  //
  bool operator == ( const ZLine3D& l) const;
  bool operator != ( const ZLine3D& l) const;

public:
  //
  // operations
  //
  inline eLineType   type() const { return m_type; }
  inline eLineType&  type() { return m_type; }
  ZVector       direction() const;
  void          direction(const ZVector v);
  float         length() const;
  float         length2() const;
  ZPoint3D      projectionPoint(const ZPoint3D& p) const;
  // calculates distance to point (in respect to line's type)
  inline float  distance(const ZPoint3D& p) const
    { return projectionPoint(p).distance(p); }

  // distance (to line), nearest, isIntersect and isParallel are based on an article
  // Distance Between Two Line Segments in 3D
  // by David Eberly, Magic Software, Inc., http://www.magic-software.com
  // March 2, 1999
  float         distance(const ZLine3D& line) const;
  ZPoint3D      nearest(const ZLine3D& line, ZPoint3D* pPtOnParamLine=NULL) const;
  bool          isIntersect(const ZLine3D& line) const;
  bool          isParallel(const ZLine3D& line) const;

  // calculates sphere intersection(s) (in respect to line's type
  // pPtFirst is felt with the first nearest intersection point (if any)
  // pPtSecond is felt with the second intersection point (if any)
  // amount of intersections (0, 1 or 2) is returned
  long          intersectSphere(const ZPoint3D& ptCenter, 
                                const float fRadius, 
                                ZPoint3D* pPtFirst, 
                                ZPoint3D* pPtSecond) const;

private:
  //
  // data members
  //
  ZPoint3D  m_ptStart;
  ZPoint3D  m_ptEnd;
  eLineType m_type;
};

//
// adjacent typedefs:
typedef ZSequence<ZLine3D>   ZLine3DSeq;


#endif //zline3d_h_included

