/*
 * Copyright 2016 - 2022 Gary Talent (gary@drinkingtea.net). All rights reserved.
 */

#pragma once

#include <ox/std/error.hpp>

namespace nostalgia::geo {

class Size {
	public:
		static constexpr auto TypeName = "net.drinkingtea.nostalgia.geo.Size";
		static constexpr auto TypeVersion = 1;
		int width = 0;
		int height = 0;

		constexpr Size() noexcept = default;

		constexpr Size(int width, int height) noexcept;

		constexpr Size operator+(geo::Size p) const noexcept;

		constexpr Size operator-(geo::Size p) const noexcept;

		constexpr Size operator*(geo::Size p) const noexcept;

		constexpr Size operator/(geo::Size p) const noexcept;


		constexpr Size operator+=(geo::Size p) noexcept;

		constexpr Size operator-=(geo::Size p) noexcept;

		constexpr Size operator*=(geo::Size p) noexcept;

		constexpr Size operator/=(geo::Size p) noexcept;


		constexpr Size operator+(int i) const noexcept;

		constexpr Size operator-(int i) const noexcept;

		constexpr Size operator*(int i) const noexcept;

		constexpr Size operator/(int i) const noexcept;


		constexpr Size operator+=(int i) noexcept;

		constexpr Size operator-=(int i) noexcept;

		constexpr Size operator*=(int i) noexcept;

		constexpr Size operator/=(int i) noexcept;


		constexpr bool operator==(const Size&) const noexcept;

		constexpr bool operator!=(const Size&) const noexcept;

};

constexpr Size::Size(int width, int height) noexcept {
	this->width = width;
	this->height = height;
}

constexpr Size Size::operator+(geo::Size p) const noexcept {
	p.width += width;
	p.height += height;
	return p;
}

constexpr Size Size::operator-(geo::Size p) const noexcept {
	auto out = *this;
	out.width -= p.width;
	out.height -= p.height;
	return out;
}

constexpr Size Size::operator*(geo::Size p) const noexcept {
	p.width *= width;
	p.height *= height;
	return p;
}

constexpr Size Size::operator/(geo::Size p) const noexcept {
	auto out = *this;
	out.width /= p.width;
	out.height /= p.height;
	return out;
}

constexpr Size Size::operator+=(geo::Size p) noexcept {
	width += p.width;
	height += p.height;
	return *this;
}

constexpr Size Size::operator-=(geo::Size p) noexcept {
	width -= p.width;
	height -= p.height;
	return *this;
}

constexpr Size Size::operator*=(geo::Size p) noexcept {
	width *= p.width;
	height *= p.height;
	return *this;
}

constexpr Size Size::operator/=(geo::Size p) noexcept {
	width /= p.width;
	height /= p.height;
	return *this;
}


constexpr Size Size::operator+(int i) const noexcept {
	auto out = *this;
	out.width += i;
	out.height += i;
	return out;
}

constexpr Size Size::operator-(int i) const noexcept {
	auto out = *this;
	out.width -= i;
	out.height -= i;
	return out;
}

constexpr Size Size::operator*(int i) const noexcept {
	auto out = *this;
	out.width *= i;
	out.height *= i;
	return out;
}

constexpr Size Size::operator/(int i) const noexcept {
	auto out = *this;
	out.width /= i;
	out.height /= i;
	return out;
}


constexpr Size Size::operator+=(int i) noexcept {
	width += i;
	height += i;
	return *this;
}

constexpr Size Size::operator-=(int i) noexcept {
	width -= i;
	height -= i;
	return *this;
}

constexpr Size Size::operator*=(int i) noexcept {
	width *= i;
	height *= i;
	return *this;
}

constexpr Size Size::operator/=(int i) noexcept {
	width /= i;
	height /= i;
	return *this;
}


constexpr bool Size::operator==(const Size &p) const noexcept {
	return width == p.width && height == p.height;
}

constexpr bool Size::operator!=(const Size &p) const noexcept {
	return width != p.width || height != p.height;
}


oxModelBegin(Size)
	oxModelField(width)
	oxModelField(height)
oxModelEnd()

}
