use crate::integer::{vec3,Planar64Vec3};

#[derive(Clone)]
pub struct Aabb{
	// min is inclusive
	min:Planar64Vec3,
	// max is not inclusive
	max:Planar64Vec3,
}

impl Default for Aabb{
	#[inline]
	fn default()->Self{
		Self{min:vec3::MAX,max:vec3::MIN}
	}
}

impl Aabb{
	#[inline]
	pub const fn new(min:Planar64Vec3,max:Planar64Vec3)->Self{
		Self{min,max}
	}
	#[inline]
	pub const fn max(&self)->Planar64Vec3{
		self.max
	}
	#[inline]
	pub const fn min(&self)->Planar64Vec3{
		self.min
	}
	#[inline]
	pub fn grow(&mut self,point:Planar64Vec3){
		self.min=self.min.min(point);
		self.max=self.max.max(point);
	}
	#[inline]
	pub fn join(&mut self,aabb:&Aabb){
		self.min=self.min.min(aabb.min);
		self.max=self.max.max(aabb.max);
	}
	#[inline]
	pub fn inflate(&mut self,hs:Planar64Vec3){
		self.min-=hs;
		self.max+=hs;
	}
	#[inline]
	pub fn contains(&self,point:Planar64Vec3)->bool{
		let bvec=self.min.le(point)&point.lt(self.max);
		bvec.all()
	}
	#[inline]
	pub fn intersects(&self,aabb:&Aabb)->bool{
		let bvec=self.min.lt(aabb.max)&aabb.min.lt(self.max);
		bvec.all()
	}
	#[inline]
	pub fn size(&self)->Planar64Vec3{
		self.max-self.min
	}
	#[inline]
	pub fn center(&self)->Planar64Vec3{
		self.min.map_zip(self.max,|(min,max)|min.midpoint(max))
	}
	#[inline]
	pub fn area_weight(&self)->fixed_wide::types::F128_64{
		let d=self.max-self.min;
		d.x*d.y+d.y*d.z+d.z*d.x
	}
	// pub fn volume(&self)->f32{
	// 	let d=self.max-self.min;
	// 	d.x*d.y*d.z
	// }
}
