/*
	Copyright 2016, 2017 Michele "King_DuckZ" Santullo

	This file is part of MyCurry.

	MyCurry 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.

	MyCurry 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 MyCurry.  If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include "vector.hpp"
#if !defined(NDEBUG)
#	include <iostream>
#endif

namespace curry {
	template <typename T>
	class Rect {
	public:
		typedef vwr::Vec<std::array<T, 2>> VecType;

		Rect() = default;
		Rect (T parLeft, T parTop, T parRight, T parBottom);
		template <typename V1, typename V2>
		Rect (const vwr::Vec<V1>& parLeftTop, const vwr::Vec<V2>& parBottomRight);

		T left() const { return from.x(); }
		T top() const { return from.y(); }
		T right() const { return to.x(); }
		T bottom() const { return to.y(); }
		T& left() { return from.x(); }
		T& top() { return from.y(); }
		T& right() { return to.x(); }
		T& bottom() { return to.y(); }
		T width() const { return right() - left(); }
		T height() const { return bottom() - top(); }
		VecType width_height() const { return VecType(width(), height()); }

		bool is_valid() const;

		VecType from;
		VecType to;
	};

	template <typename T>
	Rect<T>::Rect (T parLeft, T parTop, T parRight, T parBottom) :
		from(parLeft, parTop),
		to(parRight, parBottom)
	{
	}

	template <typename T>
	template <typename V1, typename V2>
	Rect<T>::Rect (const vwr::Vec<V1>& parLeftTop, const vwr::Vec<V2>& parBottomRight) :
		Rect(parLeftTop.x(), parLeftTop.y(), parBottomRight.x(), parBottomRight.y())
	{
	}

	template <typename T>
	bool Rect<T>::is_valid() const {
		return from <= to;
	}

#if !defined(NDEBUG)
	template <typename T>
	std::ostream& operator<< (std::ostream& parStream, const Rect<T>& parRect) {
		parStream << '{' << parRect.from << '-' << parRect.to << '}';
		return parStream;
	}
#endif
} //namespace curry
