/*
	Copyright 2014 Michele "King_DuckZ" Santullo

	This file is part of CloonelJump.

	CloonelJump is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	CloonelJump 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 General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with CloonelJump.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef id56F112C6551D44039D0C0270F573B35B
#define id56F112C6551D44039D0C0270F573B35B

#include "vector.hpp"
#include "vectormath.hpp"

namespace cloonel {
	template <typename T, uint32_t S>
	class Line {
	public:
		typedef Vector<T, S> Point;
		typedef T Scalar;

		Line ( void ) = default;
		Line ( const Line& parOther );
		Line ( const Point& parStart, const Point& parEnd );
		Line ( const Point& parStart, const Point& parDirection, Scalar parLength ) : Line(parStart, parDirection * parLength) { }
		~Line ( void ) noexcept = default;

		Point& Start ( void ) { return m_points.x(); }
		Point& End ( void ) { return m_points.y(); }
		const Point& Start ( void ) const { return m_points.x(); }
		const Point& End ( void ) const { return m_points.y(); }

		Line& operator+= ( const Point& parRhs ) __attribute__((flatten));
		Line& operator-= ( const Point& parRhs ) __attribute__((flatten));

	private:
		Vector<Point, 2> m_points;
	};

	template <typename T, uint32_t S>
	Line<T, S> operator+ ( Line<T, S> parLhs, const Vector<T, S>& parRhs ) __attribute__((pure)) __attribute__((flatten));
	template <typename T, uint32_t S>
	Line<T, S> operator- ( Line<T, S> parLhs, const Vector<T, S>& parRhs ) __attribute__((pure)) __attribute__((flatten));
	template <typename T, uint32_t S>
	Line<T, S> operator+ ( const Vector<T, S>& parLhs, Line<T, S> parRhs ) __attribute__((pure)) __attribute__((flatten));
	template <typename T, uint32_t S>
	Line<T, S> operator- ( const Vector<T, S>& parLhs, Line<T, S> parRhs ) __attribute__((pure)) __attribute__((flatten));

	template <typename T>
	bool operator> ( const Vector<T, 2>& parLhs, const Line<T, 2>& parRhs ) __attribute__((pure));
	template <typename T>
	bool operator< ( const Vector<T, 2>& parLhs, const Line<T, 2>& parRhs ) __attribute__((pure));
	template <typename T>
	bool operator>= ( const Vector<T, 2>& parLhs, const Line<T, 2>& parRhs ) __attribute__((pure));
	template <typename T>
	bool operator<= ( const Vector<T, 2>& parLhs, const Line<T, 2>& parRhs ) __attribute__((pure));
} //namespace cloonel

#include "line.inl"

#endif
