using System.Collections.Generic;
using Microsoft.Xna.Framework;

namespace XELF.Sphynx {

	enum DollJointKind {
		Head,
		Neck,
		Chest,
		Waist,
		UArmL,
		UArmR,
		LArmL,
		LArmR,
		HandL,
		HandR,
		ULegL,
		ULegR,
		LLegL,
		LLegR,
		FootL,
		FootR,
	}

	class DollSettings {
		const float s = 1 / 16.0f;

		public struct Joint {
			public readonly Vector2 Position;
			public readonly BodyKind Left, Right;
			public readonly float SpringConstant;
			public readonly float DampingConstant;
			public Joint(float x, float y, BodyKind left, BodyKind right) {
				Position.X = x;
				Position.Y = y;
				Left = left;
				Right = right;
				SpringConstant = 250;
				DampingConstant = 5;
			}
		}
		public struct BodyPart {
			/// <summary>位置</summary>
			public readonly Vector2 Position;
			/// <summary>奥行き（描画用）</summary>
			public readonly float Z;
			/// <summary>質量</summary>
			public readonly float Mass;
			/// <summary>テクスチャ座標の範囲</summary>
			public readonly Vector2 Min, Max;

			public readonly Vector2[] Shape;

			public BodyPart(float x, float y, float z, float mass, float tx0, float ty0, float tx1, float ty1,
				params Vector2[] shape) {
				Position.X = x;
				Position.Y = y;
				Z = z;
				Mass = mass;
				Min.X = tx0 * s;
				Min.Y = ty0 * s;
				Max.X = tx1 * s;
				Max.Y = ty1 * s;
				if (shape.Length == 0) {
					float scale = 4;
					Shape = new Vector2[] {
						new Vector2(-0.5f, +0.5f)*scale, new Vector2(+0.5f, +0.5f)*scale,
						new Vector2(+0.5f, -0.5f)*scale, new Vector2(-0.5f, -0.5f)*scale,
					};
				} else {
					Shape = shape;
				}
			}
		};

		const float offsetY = + 3.20f;

		public static readonly Joint[] Joints =
		{
			new Joint(+0.00f, -0.80f + offsetY, BodyKind.Head, BodyKind.Neck),
			new Joint(+0.00f, -1.00f + offsetY, BodyKind.Neck, BodyKind.Chest),
			new Joint(+0.00f, -2.00f + offsetY, BodyKind.Chest, BodyKind.Waist),
			new Joint(+0.00f, -2.60f + offsetY, BodyKind.Waist, BodyKind.Hip),
			new Joint(-0.60f, -1.20f + offsetY, BodyKind.Chest, BodyKind.UArmL),
			new Joint(+0.60f, -1.20f + offsetY, BodyKind.Chest, BodyKind.UArmR),
			new Joint(-1.90f, -1.20f + offsetY, BodyKind.UArmL, BodyKind.LArmL),
			new Joint(+1.90f, -1.20f + offsetY, BodyKind.UArmR, BodyKind.LArmR),
			new Joint(-2.90f, -1.20f + offsetY, BodyKind.LArmL, BodyKind.HandL),
			new Joint(+2.90f, -1.20f + offsetY, BodyKind.LArmR, BodyKind.HandR),
			new Joint(-0.50f, -3.80f + offsetY, BodyKind.Hip, BodyKind.ULegL),
			new Joint(+0.50f, -3.80f + offsetY, BodyKind.Hip, BodyKind.ULegR),
			new Joint(-0.50f, -5.60f + offsetY, BodyKind.ULegL, BodyKind.LLegL),
			new Joint(+0.50f, -5.60f + offsetY, BodyKind.ULegR, BodyKind.LLegR),
			new Joint(-0.50f, -7.40f + offsetY, BodyKind.LLegL, BodyKind.FootL),
			new Joint(+0.50f, -7.40f + offsetY, BodyKind.LLegR, BodyKind.FootR),
		};

		public static readonly BodyPart[] Parts =
		{
			//                X,              Y,     Z,    mass,     TX0,   TY0,   TX1,   TY1
			new BodyPart(+0.00f, -0.80f + offsetY, 0.49f,   1.00f,   00.25f, 08.25f, 01.75f, 09.75f,  // Head
				new Vector2(-1.5f, +1.5f), new Vector2(+1.5f, +1.5f),
				new Vector2(+1.5f, -1.5f), new Vector2(-1.5f, -1.5f)),
			new BodyPart(+0.00f, -1.00f + offsetY, 0.51f,   0.30f,   02.5f, 08.5f, 03.5f, 09.5f,  // Neck
				new Vector2(-1.0f, +1.0f), new Vector2(+1.0f, +1.0f),
				new Vector2(+1.0f, -1.0f), new Vector2(-1.0f, -1.0f)),
			new BodyPart(+0.00f, -2.00f + offsetY, 0.52f,   1.00f,   04.5f, 08.0f, 05.5f, 10.0f,  // Chest
				new Vector2(-1.0f, +2.0f), new Vector2(+1.0f, +2.0f),
				new Vector2(+1.0f, -2.0f), new Vector2(-1.0f, -2.0f)),
			new BodyPart(+0.00f, -2.60f + offsetY, 0.53f,   0.80f,   06.5f, 08.5f, 07.5f, 09.5f,  // Waist
				new Vector2(-1.0f, +1.0f), new Vector2(+1.0f, +1.0f),
				new Vector2(+1.0f, -1.0f), new Vector2(-1.0f, -1.0f)),
			new BodyPart(+0.00f, -3.20f + offsetY, 0.50f,   1.00f,   08.0f, 08.0f, 10.0f, 10.0f), // Hip
			new BodyPart(-0.60f, -1.20f + offsetY, 0.47f,   0.50f,   00.0f, 10.5f, 02.0f, 11.5f,  // UArmL
				new Vector2(-2.0f, +1.0f), new Vector2(+2.0f, +1.0f),
				new Vector2(+2.0f, -1.0f), new Vector2(-2.0f, -1.0f)),
			new BodyPart(+0.60f, -1.20f + offsetY, 0.47f,   0.50f,   02.0f, 10.5f, 00.0f, 11.5f,  // UArmR
				new Vector2(-2.0f, +1.0f), new Vector2(+2.0f, +1.0f),
				new Vector2(+2.0f, -1.0f), new Vector2(-2.0f, -1.0f)),
			new BodyPart(-1.90f, -1.20f + offsetY, 0.48f,   0.30f,   02.25f, 10.75f, 03.75f, 11.25f,  // LArmL
				new Vector2(-1.5f, +0.5f), new Vector2(+1.5f, +0.5f),
				new Vector2(+1.5f, -0.5f), new Vector2(-1.5f, -0.5f)),
			new BodyPart(+1.90f, -1.20f + offsetY, 0.48f,   0.30f,   03.75f, 10.75f, 02.25f, 11.25f,  // LArmR
				new Vector2(-1.5f, +0.5f), new Vector2(+1.5f, +0.5f),
				new Vector2(+1.5f, -0.5f), new Vector2(-1.5f, -0.5f)),
			new BodyPart(-2.90f, -1.20f + offsetY, 0.46f,   0.10f,   04.75f, 10.75f, 05.25f, 11.25f,  // HandL
				new Vector2(-0.5f, +0.5f), new Vector2(+0.5f, +0.5f),
				new Vector2(+0.5f, -0.5f), new Vector2(-0.5f, -0.5f)),
			new BodyPart(+2.90f, -1.20f + offsetY, 0.46f,   0.10f,   05.25f, 10.75f, 04.75f, 11.25f,  // HandR
				new Vector2(-0.5f, +0.5f), new Vector2(+0.5f, +0.5f),
				new Vector2(+0.5f, -0.5f), new Vector2(-0.5f, -0.5f)),
			new BodyPart(-0.50f, -3.60f + offsetY, 0.52f,   0.90f,   08.5f, 10.0f, 09.5f, 12.0f,  // ULegL
				new Vector2(-1.0f, +2.0f), new Vector2(+1.0f, +2.0f),
				new Vector2(+1.0f, -2.0f), new Vector2(-1.0f, -2.0f)),
			new BodyPart(+0.50f, -3.60f + offsetY, 0.52f,   0.90f,   09.5f, 10.0f, 08.5f, 12.0f,  // ULegR
				new Vector2(-1.0f, +2.0f), new Vector2(+1.0f, +2.0f),
				new Vector2(+1.0f, -2.0f), new Vector2(-1.0f, -2.0f)),
			new BodyPart(-0.50f, -5.40f + offsetY, 0.51f,   0.40f,   10.5f, 10.0f, 11.5f, 12.0f,  // LLegL
				new Vector2(-1.0f, +2.0f), new Vector2(+1.0f, +2.0f),
				new Vector2(+1.0f, -2.0f), new Vector2(-1.0f, -2.0f)),
			new BodyPart(+0.50f, -5.40f + offsetY, 0.51f,   0.40f,   11.5f, 10.0f, 10.5f, 12.0f,  // LLegR
				new Vector2(-1.0f, +2.0f), new Vector2(+1.0f, +2.0f),
				new Vector2(+1.0f, -2.0f), new Vector2(-1.0f, -2.0f)),
			new BodyPart(-0.50f, -7.20f + offsetY, 0.50f,   0.15f,   12.5f, 10.75f, 13.5f, 11.25f,  // FootL
				new Vector2(-1.0f, +1.0f), new Vector2(+1.0f, +1.0f),
				new Vector2(+1.0f, -0.0f), new Vector2(-1.0f, -0.0f)),
			new BodyPart(+0.50f, -7.20f + offsetY, 0.50f,   0.15f,   13.5f, 10.75f, 12.5f, 11.25f,  // FootR
				new Vector2(-1.0f, +1.0f), new Vector2(+1.0f, +1.0f),
				new Vector2(+1.0f, -0.0f), new Vector2(-1.0f, -0.0f)),
		};
	}

}
