use super::vector3::Vector3;

#[derive(Clone,Copy)]
pub struct CFrame(pub(crate)glam::Affine3A);

impl CFrame{
	pub fn new(x:f32,y:f32,z:f32)->Self{
		Self(glam::Affine3A::from_translation(glam::vec3(x,y,z)))
	}
	pub fn angles(x:f32,y:f32,z:f32)->Self{
		Self(glam::Affine3A::from_mat3(glam::Mat3::from_euler(glam::EulerRot::YXZ,y,x,z)))
	}
}

impl mlua::UserData for CFrame{
	fn add_fields<'lua,F:mlua::UserDataFields<'lua,Self>>(fields:&mut F){
		//CFrame.p
		fields.add_field_method_get("p",|_,this|Ok(Vector3(this.0.translation)));
	}

	fn add_methods<'lua,M:mlua::UserDataMethods<'lua,Self>>(methods:&mut M){
		//methods.add_method("area",|_,this,()|Ok(this.length*this.width));

		//methods.add_meta_method(mlua::MetaMethod::Mul,|_,this,val:&Vector3|Ok(Vector3(this.0.matrix3*val.0+this.0.translation)));
		methods.add_meta_function(mlua::MetaMethod::Mul,|_,(this,val):(Self,Self)|Ok(Self(this.0*val.0)));
		methods.add_meta_function(mlua::MetaMethod::ToString,|_,this:Self|
			Ok(format!("CFrame.new({},{},{},{},{},{},{},{},{},{},{},{})",
				this.0.translation.x,
				this.0.translation.y,
				this.0.translation.z,
				this.0.matrix3.x_axis.x,
				this.0.matrix3.y_axis.x,
				this.0.matrix3.z_axis.x,
				this.0.matrix3.x_axis.y,
				this.0.matrix3.y_axis.y,
				this.0.matrix3.z_axis.y,
				this.0.matrix3.x_axis.z,
				this.0.matrix3.y_axis.z,
				this.0.matrix3.z_axis.z,
			))
		);
	}
}
impl<'lua> mlua::FromLua<'lua> for CFrame{
	fn from_lua(value:mlua::prelude::LuaValue<'lua>,_lua:&'lua mlua::prelude::Lua)->mlua::prelude::LuaResult<Self>{
		match value{
			mlua::Value::UserData(ud)=>ud.take()?,
			other=>Err(mlua::Error::runtime(format!("Expected CFrame got {:?}",other))),
		}
	}
}