namespace CGAL {
/*!
\ingroup kernel_classes2

An object `l` of the data type `Line_2` is a directed
straight line in the two-dimensional Euclidean plane \f$ \E^2\f$. It is
defined by the set of points with %Cartesian coordinates \f$ (x,y)\f$
that satisfy the equation

\f[ l:\; a\, x +b\, y +c = 0. \f]

The line splits \f$ \E^2\f$ in a <I>positive</I> and a <I>negative</I>
side. A point `p` with %Cartesian coordinates
\f$ (px, py)\f$ is on the positive side of `l`, iff
\f$ a\, px + b\, py +c > 0\f$, it is
on the negative side of `l`, iff
\f$ a\, px + b\, py +c < 0\f$.
The positive side is to the left of `l`.

\cgalHeading{Example}

Let us first define two %Cartesian two-dimensional points in the Euclidean
plane \f$ \E^2\f$. Their
dimension and the fact that they are %Cartesian is expressed by
the suffix `_2` and the representation type `Cartesian`.

\code
Point_2< Cartesian<double> > p(1.0,1.0), q(4.0,7.0);
\endcode

To define a line `l` we write:

\code
Line_2< Cartesian<double> > l(p,q);
\endcode

\cgalModels{Kernel::Line_2}

*/
template< typename Kernel >
class Line_2 {
public:

/// \name Creation
/// @{

/*!
introduces a line `l` with the line equation in %Cartesian
coordinates \f$ ax +by +c = 0\f$.
\cgalEpicExact
*/
Line_2(const Kernel::RT &a, const Kernel::RT &b, const Kernel::RT &c);

/*!
introduces a line `l` passing through the points `p` and `q`.
Line `l` is directed from `p` to `q`.
*/
Line_2(const Point_2<Kernel> &p, const Point_2<Kernel> &q);

/*!
introduces a line `l` passing through point `p` with
direction `d`.
*/
Line_2(const Point_2<Kernel> &p, const Direction_2<Kernel>&d);

/*!
introduces a line `l` passing through point `p` and
oriented by `v`.
*/
Line_2(const Point_2<Kernel> &p, const Vector_2<Kernel>&v);

/*!
introduces a line `l` supporting the segment `s`,
oriented from source to target.
*/
Line_2(const Segment_2<Kernel> &s);

/*!
introduces a line `l` supporting the ray `r`,
with same orientation.
*/
Line_2(const Ray_2<Kernel> &r);

/// @}

/// \name Operations
/// @{

/*!
Test for equality: two lines are equal, iff they have a non
empty intersection and the same direction.
*/
bool operator==(const Line_2<Kernel> &h) const;

/*!
Test for inequality.
*/
bool operator!=(const Line_2<Kernel> &h) const;

/*!
returns the first coefficient of `l`.
\cgalEpicExact
*/
Kernel::RT a() const;

/*!
returns the second coefficient of `l`.
\cgalEpicExact
*/
Kernel::RT b() const;

/*!
returns the third coefficient of `l`.
\cgalEpicExact
*/
Kernel::RT c() const;

/*!
returns an arbitrary point on `l`. It holds
`point(i) == point(j)`, iff `i==j`.
Furthermore, `l` is directed from `point(i)`
to `point(j)`, for all `i` \f$ <\f$ `j`.
*/
Point_2<Kernel> point(const Kernel::FT i) const;

/*!
returns the orthogonal projection of `p` onto `l`.
*/
Point_2<Kernel> projection(const Point_2<Kernel> &p) const;

/*!
returns the \f$ x\f$-coordinate of the point at `l` with
given \f$ y\f$-coordinate.
\pre `l` is not horizontal.
*/
Kernel::FT x_at_y(const Kernel::FT &y) const;

/*!
returns the \f$ y\f$-coordinate of the point at `l` with
given \f$ x\f$-coordinate.
\pre `l` is not vertical.
*/
Kernel::FT y_at_x(const Kernel::FT &x) const;

/// @}

/// \name Predicates
/// @{

/*!
line `l` is degenerate, if the coefficients `a` and
`b` of the line equation are zero.
*/
bool is_degenerate() const;

/*!

*/
bool is_horizontal() const;

/*!

*/
bool is_vertical() const;

/*!
returns \ref ON_ORIENTED_BOUNDARY,
\ref ON_NEGATIVE_SIDE, or the constant
\ref ON_POSITIVE_SIDE,
depending on the position of `p` relative to the oriented line `l`.

*/
Oriented_side oriented_side(const Point_2<Kernel> &p) const;

/// @}

/// \name Convenience Boolean Functions
/// @{

/*!

*/
bool has_on(const Point_2<Kernel> &p) const;

/*!

*/
bool has_on_positive_side(const Point_2<Kernel> &p) const;

/*!

*/
bool has_on_negative_side(const Point_2<Kernel> &p) const;

/// @}

/// \name Miscellaneous
/// @{

/*!
returns a vector having the direction of `l`.
*/
Vector_2<Kernel> to_vector() const;

/*!
returns the direction of `l`.
*/
Direction_2<Kernel> direction() const;

/*!
returns the line with opposite direction.
\cgalEpicExact
*/
Line_2<Kernel> opposite() const;

/*!
returns the line perpendicular to `l` and passing through `p`,
where the direction is the direction of `l` rotated
counterclockwise by 90 degrees.
*/
Line_2<Kernel> perpendicular(const Point_2<Kernel> &p) const;

/*!
returns the line obtained by applying `t` on a point on `l`
and the direction of `l`.
*/
Line_2<Kernel> transform(const Aff_transformation_2<Kernel> &t) const;

/// @}

}; /* end Line_2 */
} /* end namespace CGAL */

