using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;

public class MMDEngine : MonoBehaviour {

	public bool useRigidbody = false;
	public int[] groupTarget;		// 非衝突剛体リスト
	public GameObject[] rigids;		// 剛体リスト

	// 訳があってこうなってる
	public int[] ignore1;
	public int[] ignore2;
	public int[] ignore3;
	public int[] ignore4;
	public int[] ignore5;
	public int[] ignore6;
	public int[] ignore7;
	public int[] ignore8;
	public int[] ignore9;
	public int[] ignore10;
	public int[] ignore11;
	public int[] ignore12;
	public int[] ignore13;
	public int[] ignore14;
	public int[] ignore15;
	public int[] ignore16;
	List<int[]> ignoreList;
	
	#region Data For Morphing
	// Target Data For Morphing
	public MMD.PMD.PMDFormat.SkinList skinList;
	public MMD.PMD.PMDFormat.SkinData[] skin_data;
	
	// 表情の元データ
	public int[] baseSkinVertCountStorageArray;
		
	#endregion

	// Use this for initialization
	void Start () 
	{	
		if (useRigidbody)
		{
			ignoreList = new List<int[]>();
			ignoreList.Add(ignore1);
			ignoreList.Add(ignore2);
			ignoreList.Add(ignore3);
			ignoreList.Add(ignore4);
			ignoreList.Add(ignore5);
			ignoreList.Add(ignore6);
			ignoreList.Add(ignore7);
			ignoreList.Add(ignore8);
			ignoreList.Add(ignore9);
			ignoreList.Add(ignore10);
			ignoreList.Add(ignore11);
			ignoreList.Add(ignore12);
			ignoreList.Add(ignore13);
			ignoreList.Add(ignore14);
			ignoreList.Add(ignore15);
			ignoreList.Add(ignore16);

			// 非衝突グループの設定
			for (int i = 0; i < rigids.Length; i++)
			{
				for (int shift = 0; shift < 16; shift++)
				{
					// フラグチェック
					if ((groupTarget[i] & (1 << shift)) == (1 << shift))
					{
						for (int j = 0; j < ignoreList[shift].Length; j++)
						{
							if (i == j) continue;
							Physics.IgnoreCollision(rigids[i].collider, rigids[j].collider, true);
						}
					}
				}
			}
		}
	}
	
	// Update is called once per frame
	void Update () 
	{
	
	}

	public static void Initialize(MMDEngine engine, int[] groupTarget, List<int>[] ignoreGroups, GameObject[] rigidArray)
	{
		if (!engine.useRigidbody)
		{
			engine.groupTarget = groupTarget;
			engine.rigids = rigidArray;
			engine.useRigidbody = true;

			engine.ignore1 = ignoreGroups[0].ToArray();
			engine.ignore2 = ignoreGroups[1].ToArray();
			engine.ignore3 = ignoreGroups[2].ToArray();
			engine.ignore4 = ignoreGroups[3].ToArray();
			engine.ignore5 = ignoreGroups[4].ToArray();
			engine.ignore6 = ignoreGroups[5].ToArray();
			engine.ignore7 = ignoreGroups[6].ToArray();
			engine.ignore8 = ignoreGroups[7].ToArray();
			engine.ignore9 = ignoreGroups[8].ToArray();
			engine.ignore10 = ignoreGroups[9].ToArray();
			engine.ignore11 = ignoreGroups[10].ToArray();
			engine.ignore12 = ignoreGroups[11].ToArray();
			engine.ignore13 = ignoreGroups[12].ToArray();
			engine.ignore14 = ignoreGroups[13].ToArray();
			engine.ignore15 = ignoreGroups[14].ToArray();
			engine.ignore16 = ignoreGroups[15].ToArray();
		}
	}
	
	public static void CreateSkinListForMorphing( MMDEngine engine, MMD.PMD.PMDFormat format ){

		// Target a Skin Data For Morphong
		string[] skinNameStorageArray;
		int[] skinTypeStorageArray;
	
		// Target Vertex Data For Morphing
		int[] skinVertIndexStorageArray;
		Vector3[] skinVertPosStorageArray;
		
		int i = 0;
		int j = 0;
		
		//create Array For skin_count
		skinNameStorageArray = new string[format.skin_list.skin_count];
		skinTypeStorageArray = new int[ format.skin_list.skin_count ];
		
		// 表情ごとに使用する頂点や座標をゲームオブジェクトとして
		// まとめておくためのparentObject
		GameObject expression = new GameObject("Expression");
		expression.transform.parent = format.caller.transform;
		
		foreach( MMD.PMD.PMDFormat.SkinData data in format.skin_list.skin_data ){			
			// 表情ごとにGameObject作成
			// GameObjectにはそれぞれの表情で使用する
			// 頂点や座標などの情報を持たせる
			GameObject obj = new GameObject( data.skin_name );
			obj.transform.parent = expression.transform;
			SkinDataForMorph morph = obj.AddComponent<SkinDataForMorph>();
			
			if( i == 0 ){
				engine.baseSkinVertCountStorageArray = new int[ data.skin_vert_count ];
				
				// 他の表情で使用する頂点の情報を取得
				foreach( MMD.PMD.PMDFormat.SkinVertexData vertData in data.skin_vert_data ){
					engine.baseSkinVertCountStorageArray[j++] = (int)vertData.skin_vert_index;
				}
				j = 0;
				
				// 初期化
				skinNameStorageArray[i] = data.skin_name;
				skinTypeStorageArray[i] = (int)data.skin_type;
			
				skinVertIndexStorageArray = new int[ data.skin_vert_count ];
				skinVertPosStorageArray = new Vector3[ data.skin_vert_count ];
			
				// データ格納
				// skinVertIndexStorageArray : 表情で使用する頂点番号
				// skinVertPosStorageArray : 表情で使用する頂点座標の位置情報
				foreach( MMD.PMD.PMDFormat.SkinVertexData vertData in data.skin_vert_data ){
					skinVertIndexStorageArray[j] = (int)vertData.skin_vert_index;
					skinVertPosStorageArray[j++] = vertData.skin_vert_pos;
				}
				
			}else{
				// base以外の表情はこっち
				skinNameStorageArray[i] = data.skin_name;
				skinTypeStorageArray[i] = (int)data.skin_type;
			
				skinVertIndexStorageArray = new int[ data.skin_vert_count ];
				skinVertPosStorageArray = new Vector3[ data.skin_vert_count ];
			
				foreach( MMD.PMD.PMDFormat.SkinVertexData vertData in data.skin_vert_data ){
					skinVertIndexStorageArray[j] = (int)vertData.skin_vert_index;
					skinVertPosStorageArray[j++] = vertData.skin_vert_pos;
				}
			}
			SkinDataForMorph.createSkinDataForMorph( morph, skinNameStorageArray[i], skinTypeStorageArray[i], skinVertIndexStorageArray, skinVertPosStorageArray );

			i++;
			j = 0;
		}
	}
}
