/***************************************************************************
**
**  This file is part of QGpCoreMath.
**
**  This library is free software; you can redistribute it and/or
**  modify it under the terms of the GNU Lesser General Public
**  License as published by the Free Software Foundation; either
**  version 2.1 of the License, or (at your option) any later version.
**
**  This file is distributed in the hope that it will be useful, but WITHOUT
**  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
**  FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
**  License for more details.
**
**  You should have received a copy of the GNU Lesser General Public
**  License along with this library; if not, write to the Free Software
**  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
**
**  See http://www.geopsy.org for more information.
**
**  Created: 2012-04-16
**  Copyright: 2012-2019
**    Marc Wathelet (ISTerre, Grenoble, France)
**
***************************************************************************/

#ifndef SEGMENT_H
#define SEGMENT_H

#include "Point.h"
#include "Plane.h"
#include "Parallelepiped.h"
#include "QGpCoreMathDLLExport.h"

namespace QGpCoreMath {

  class QGPCOREMATH_EXPORT Segment
  {
  public:
    Segment() {}
    Segment(const Point& p1, const Point& p2) {set(p1,p2);}
    Segment(double x1, double y1, double z1,
            double x2, double y2, double z2) {set(x1, y1, z1,
                                                  x2, y2, z2);}
    Segment(const Segment& o);

    enum RelativePosition {Skew, Crossing, Parallel, Aligned,
                           Continuous, SmallOverlap, StrongOverlap};

    bool intersects(const Segment& seg, Point& p) const;
    bool intersects(const Plane& pl, Point& p) const;

    QVector<Segment> distanceTo(const Segment& seg, RelativePosition& relPos) const;
    Segment distanceTo(const Point& p) const;

    const Point& point(int index) const {return _point[index];}
    void setPoint(int index, const Point& p) {_point[index]=p;}

    Point center() const {return (_point[0]+_point[1])*0.5;}
    void set(const Point& p1, const Point& p2);
    void set(double x1, double y1, double z1,
             double x2, double y2, double z2);
    bool includes(const Point& p, double precision=1e-10) const;
    void setLength(double l);
    double length() const {return _point[0].distanceTo(_point[1]);}
    Point directionVector() const;
    void swap();
    bool parallelTo(const Segment& o) const;
    bool parallelTo(const Plane& o) const;

    bool isSimilar(const Segment& o, double precision) const;
    bool operator<(const Segment& o) const;
    bool operator==(const Segment& o) const;
  private:
    inline static Segment linkSegment(double sc, double tc,
                                      const Segment& seg1, const Point& u,
                                      const Segment& seg2, const Point& v);
    Point _point[2];
    Parallelepiped _limits;
  };

} // namespace QGpCoreMath

#endif // SEGMENT_H
