using System;
using System.Collections.Generic;
using System.Text;
using Box2DX.Collision;
using Box2DX.Common;
using Box2DX.Dynamics;

namespace Nlgp1.B2DX
{
	public class DynamicBox:Box
	{
		public static new string BoxKind = "Dynamic";

		/// <summary>
		/// 力を加えると動く物体の定義
		/// </summary>
		/// <param name="pos">場所</param>
		/// <param name="angle">角度</param>
		/// <param name="world">投入するWorld</param>
		/// <param name="boxwidth">判定の広さ</param>
		/// <param name="boxheight">判定の高さ</param>
		/// <param name="noRotateFlag">非回転フラグ</param>
		/// <param name="userdata">名前データと衝突判定</param>
		public DynamicBox(Vec2 pos,float angle,World world,float boxwidth,float boxheight,bool noRotateFlag,Dictionary<UserDataKind,string> userdata):
			this(pos, angle, world, boxwidth, boxheight, noRotateFlag, userdata, new Dictionary<ObjectDataKind,float>(),false)
		{
			
		}

		/// <summary>
		/// 力を加えると動く物体の定義
		/// </summary>
		/// <param name="pos">場所</param>
		/// <param name="angle">角度</param>
		/// <param name="world">投入するWorld</param>
		/// <param name="boxwidth">判定の広さ</param>
		/// <param name="boxheight">判定の高さ</param>
		/// <param name="noRotateFlag">非回転フラグ</param>
		/// <param name="userdata">名前データと衝突判定</param>
		/// <param name="data">密度や摩擦の指定</param>
		/// <param name="allowregenerate">ボックスの再生成を許可するかのフラグ</param>
		public DynamicBox(Vec2 pos, float angle, World world, float boxwidth, float boxheight,
			bool noRotateFlag, Dictionary<UserDataKind, string> 
			userdata,Dictionary<ObjectDataKind,float> data,
			bool allowregenerate):
			base(pos, angle, world, boxwidth, boxheight, noRotateFlag, userdata, data,allowregenerate)
		{
		}
		public DynamicBox(Vec2 pos, float angle, World world, float boxwidth, float boxheight,
			bool noRotateFlag, Dictionary<UserDataKind, string>
			userdata, Dictionary<ObjectDataKind, float> data) :
			base(pos, angle, world, boxwidth, boxheight, noRotateFlag, userdata, data, false)
		{
		}
		public DynamicBox(Vec2 pos, float angle,float lind,float angd) : base(pos, angle,lind,angd) { }


		public void ApplyRelativeImpulse(float power, float angle)
		{
			SelfBody.SetLinearVelocity(culcForce(new Vec2(power,power),angle));
		}
		public void ApplyRelativeImpulse(Vec2 power, float angle)
		{
			SelfBody.SetLinearVelocity(culcForce(power, angle));
		}

		public void ApplyRelativeForce(float power, float angle)
		{
			SelfBody.ApplyForce(culcForce(new Vec2(power, power), angle), Center);
		}
		public void ApplyRelativeForce(Vec2 power, float angle)
		{
			SelfBody.ApplyForce(culcForce(power, angle), Center);
		}
		/// <summary>
		/// 力を加えます、作用点指定なしで重心へと力がかかります
		/// </summary>
		/// <param name="power"></param>
		/// <param name="center"></param>
		public void ApplyForce(Vec2 power, Vec2 center)
		{
			SelfBody.ApplyForce(power, center);
		}
		public void ApplyForce(Vec2 power)
		{
			SelfBody.ApplyForce(power, SelfBody.GetWorldCenter());
		}
		/// <summary>
		/// 加速度を加えます、作用点指定なしで重心へと力がかかります
		/// </summary>
		/// <param name="power"></param>
		/// <param name="center"></param>
		public void ApplyImpulse(Vec2 power, Vec2 center)
		{
			SelfBody.ApplyImpulse(power, center);
		}
		public void ApplyImpulse(Vec2 power)
		{
			SelfBody.ApplyImpulse(power, SelfBody.GetWorldCenter());
		}

		/// <summary>
		/// 物体を回転させます、正で時計回りに回転させます
		/// </summary>
		/// <param name="angulervelocity">回転速度</param>
		public void ApplyTorque(float angulervelocity)
		{
			SelfBody.ApplyTorque(angulervelocity);
		}
		
		/// <summary>
		/// 重さ、慣性、重心を設定します
		/// </summary>
		/// <param name="center">重心の位置（ワールド座標）</param>
		/// <param name="inertia">慣性</param>
		/// <param name="mass">重さ（大きければ大きいほど力がかかりにくくなる）</param>
		public void SetMassData(Vec2 center,float inertia,float mass)
		{
			MassData m;
			m.Center = center;
			m.I = inertia;
			m.Mass = mass;
			SelfBody.SetMass(m);
		}
		public myUserData GetUserData()
		{
			return UserData;
		}
		public void SetUserData(myUserData value)
		{
			UserData = value;
		}
		


		Vec2 culcForce(Vec2 power, float angle)
		{

			float dirx, diry;
			dirx = MathF.Cos(Angle + angle * MathF.PI / 180) * power.X;
			diry = MathF.Sin(Angle + angle * MathF.PI / 180) * power.Y;
			return new Vec2(dirx, diry);

		}


	}
}

