using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
#endif

//-------------------------------------------------------------------------------------------------

public enum CAT_STATE
{
	IDLE,
	WALKING,
	SEDUCE,
	FUCK,
	EAT,
	TAKING,
	SLEEP,
	SHIT,
	PUKE,
	SIT,
	FORCE,
	SHOT,
	BUZZ,
	BEAUTY,
	GAME,
	READ,
	ANGE,
	POSE,
	MUTATION,
	DEAD,
	MENU,
	HIDE,

	COUNT,
	INVALID
}

public enum SPRITE_BULLE
{
	BULLE_0_HUNGRY,
	BULLE_1_TIRED,
	BULLE_2_LEWD,
	BULLE_3_LIFE,
	BULLE_4_NOSPACE,
	BULLE_5_CANDY,
	BULLE_6_HEART,
	BULLE_7_SICK,
	BULLE_8_INVERSO,
	BULLE_9_SOAP,
	BULLE_10_WHITE,

	BULLE_NONE,
	OK
}

//-------------------------------------------------------------------------------------------------

public class CatModel : MonoBehaviour
{
	const bool debug = false;

	public Cat Cat;

	public Texture3D texture;

	//[System.NonSerialized]
	public Animator animator;

	//[System.NonSerialized]		Item eatItem;

	[System.NonSerialized]		public GameObject tombPrefab;
	[SerializeField]			GameObject tombModel = null;

	//[System.NonSerialized]		StatePlay statePlay;

	[System.NonSerialized]		public Vector3 destination;

	[System.NonSerialized]		float alarmShit = -1.0f;
	[System.NonSerialized]		float shitDelay = 0.2f;

	[System.NonSerialized]		double previousAge = -1.0f;
	[System.NonSerialized]		float takenRotate = 0.0f;

	[System.NonSerialized]		float alarmSec = -1.0f;
	public bool inField = true;

	public SkinnedMeshRenderer skinnedMeshBody;
	public SkinnedMeshRenderer skinnedMeshHead;
	public SkinnedMeshRenderer skinnedMeshLegs;
	public SkinnedMeshRenderer skinnedMeshBalls;
	public SkinnedMeshRenderer[] skinnedMeshTails;

	public SkinnedMeshRenderer skinnedMeshEyes;
	public SkinnedMeshRenderer skinnedMeshTruffe;
	public SkinnedMeshRenderer skinnedMeshSurcils;

	public GameObject[] Tails;
	public GameObject Testiboules;

	[System.NonSerialized]		public float alarm = -1.0f;

	[SerializeField]			Transform selection = null;

	[SerializeField]			public MenuBar menuBar;

	CatModel partenaire;

	[SerializeField]
	public Transform model = null;

	public Material material = null;
	public Material eyesMaterial = null;
	public Material truffeMaterial = null;

	public const float CAT_SIZE = 0.80f;

	public CAT_STATE State = CAT_STATE.IDLE; // { get; private set; } = CAT_STATE.IDLE;

	//---------------------------------------------------------------------------------------------

	public void Init(Cat rabbit/*, StatePlay statePlay = null*/)
	{
		this.Cat = rabbit;

		/*if (statePlay != null)
		{
			this.statePlay = statePlay;
		}*/

		if (animator == null && model != null)
		{
			animator = model.GetComponent<Animator>();
		}		

		//if (legendaryBack != null)
		//{
		//	Destroy(legendaryBack);
		//	legendaryBack = null;
		//}

		//if (legendaryHead != null)
		//{
		//	Destroy(legendaryHead);
		//	legendaryHead = null;
		//}

		//if (legendaryTail != null)
		//{
		//	Destroy(legendaryTail);
		//	legendaryTail = null;
		//}


		//if (Cat.Properties.dead)
		//{
		//	BecameTomb();
		//}
	}

	//---------------------------------------------------------------------------------------------
	public void UpdateSize()
	{
		transform.localScale = Vector3.one;
		float lossy = transform.lossyScale.x;

		if (State == CAT_STATE.MENU)
		{
			lossy = 1.0f;
			//bulle.SetActive(false);
		}

		if (Cat.IsChild)
		{
			//float ratio = Mathf.Clamp01((float)(Cat.Age / Rabbit.ADULT_AGE)) * 0.8f;

			//transform.localScale = Vector3.one * CAT_SIZE * Mathf.Min(1.0f, ((ratio + 1.0f) * 0.5f)) / lossy;
			//boneHead.transform.localScale = Vector3.one * (Mathf.Max(1.0f, (1.5f - (0.5f * ratio))));

			if (State != CAT_STATE.TAKING && State != CAT_STATE.MENU)
			{
				Vector3 position = transform.localPosition;
				position.y = 0.0f;
				transform.localPosition = position;
			}
		}
		else
		{
			transform.localScale = Vector3.one * CAT_SIZE / lossy;
			//boneHead.transform.localScale = Vector3.one;

			/*if (previousAge < Rabbit.ADULT_AGE)
			{
				//RefreshSkin();
			}*/
		}

		previousAge = Cat.Age;

		//menuBar.transform.localScale = 0.0017f * Vector3.one / transform.localScale.x;
	}

	//---------------------------------------------------------------------------------------------
	public void Refresh()
	{
		Debug.Log("CatModel.Refresh()");

		//head?.DestroyChildren();

		//if (State != CAT_STATE.MENU && State != CAT_STATE.HIDE && State != CAT_STATE.DEAD)
		//{
		//	if (noBulle == false)
		//	{
		//		if (IsObjective())
		//		{
		//			Instantiate(Interface.Instance.star, head);
		//		}
		//	}
		//}

		//// Affect the material

		//Cat.AffectMaterial(material);

		ApplyMaterials();
		ApplyBlendshapes();


		//dirtyVal.x = Mathf.Min(Cat.Properties.dirty * 3.0f, 1.0f);
		//material.SetVector("_Dirty", dirtyVal);
		//material.SetVector("_DirtyColor", new Color(0.3f, 0.2f, 0.1f, 0.0f));

		//// Legendary effects

		//if (rabbit.apparence.IsLegendary())
		//{
		//	GameObject prefab;
		//	CAT_COLOR legendaryIndex = rabbit.apparence.Color;

		//	if (legendaryIndex == CAT_COLOR.EPIQUE_UNICORN)
		//	{
		//		rabbit.skin1 = SKIN_TYPE.S92_CHEWINGGUM;
		//	}

		//	if (legendaryIndex == CAT_COLOR.DEATH)
		//	{
		//		deathFace = ClockUI.IsNight() > 0.2f;

		//		Destroy(legendaryTail);
		//		if (deathFace)
		//		{
		//			DeathBody deathBody = Instantiate(Legendary.Instance.deathAsset.deathBody, transform);
		//			deathBody.Init(this);
		//			legendaryTail = deathBody.gameObject;

		//			material.CopyPropertiesFromMaterial(Legendary.Instance.deathAsset.deathMaterial);
		//			foreach (Renderer renderer in rendererList)
		//			{
		//				renderer.material = material;
		//			}

		//			fly = false;
		//			flyAlways = false;
		//		}
		//		else
		//		{
		//			material.CopyPropertiesFromMaterial(Legendary.Instance.deathAsset.angelMaterial);
		//			foreach (Renderer renderer in rendererList)
		//			{
		//				renderer.material = material;
		//			}

		//			fly = true;
		//			flyAlways = true;
		//		}

		//		gameObjectBody.SetActive(legendaryIndex != CAT_COLOR.DEATH || deathFace);
		//		gameObjectHead.SetActive(legendaryIndex != CAT_COLOR.DEATH || !deathFace);
		//	}
		//	else if (legendaryIndex == CAT_COLOR.EPIQUE_CLOWN)
		//	{
		//		deathFace = (ClockUI.Hour == 0);

		//		if (legendaryHead != null)
		//		{
		//			Destroy(legendaryHead);
		//			legendaryHead = null;
		//		}

		//		if (deathFace)
		//		{
		//			// Angry Clown 
		//			legendaryHead = Instantiate(Legendary.Instance.clownAsset.angryPrefabHead, skinHead.parent);

		//			material.CopyPropertiesFromMaterial(Legendary.Instance.clownAsset.angryMaterial);
		//			foreach (Renderer renderer in rendererList)
		//			{
		//				renderer.material = material;
		//			}
		//		}
		//		else
		//		{
		//			// Nice Clown 
		//			legendaryHead = Instantiate(Legendary.Instance.clownAsset.nicePrefabHead, skinHead.parent);

		//			material.CopyPropertiesFromMaterial(Legendary.Instance.clownAsset.niceMaterial);
		//			foreach (Renderer renderer in rendererList)
		//			{
		//				renderer.material = material;
		//			}
		//		}
		//	}
		//	else
		//	{
		//		if ((prefab = Legendary.Instance.GetPrefabTail(legendaryIndex)) != null)
		//		{
		//			if (legendaryTail == null)
		//			{
		//				legendaryTail = Instantiate(prefab, tail);
		//			}
		//		}
		//		else if (legendaryTail != null)
		//		{
		//			Destroy(legendaryTail);
		//			legendaryTail = null;
		//		}
		//	}

		//	if ((prefab = Legendary.Instance.GetPrefabBack(legendaryIndex)) != null)
		//	{
		//		if (legendaryBack == null)
		//		{
		//			legendaryBack = Instantiate(prefab, skinDos.parent);
		//		}
		//	}
		//	else
		//	{
		//		if (legendaryBack != null)
		//		{
		//			Destroy(legendaryBack);
		//			legendaryBack = null;
		//		}
		//	}

		//	if ((prefab = Legendary.Instance.GetPrefabHead(legendaryIndex)) != null)
		//	{
		//		if (legendaryHead == null)
		//		{
		//			legendaryHead = Instantiate(prefab, skinHead.parent);
		//		}
		//	}
		//	else if (legendaryHead != null)
		//	{
		//		Destroy(legendaryHead);
		//		legendaryHead = null;
		//	}

		//	Legendary.LegendaryAsset asset = Legendary.Instance.FindAsset(legendaryIndex);

		//	gameObjectTail.SetActive(!asset.hideTail);

		//	if (legendaryIndex != CAT_COLOR.DEATH)
		//	{
		//		gameObjectBody.SetActive(!asset.hideBody);
		//		fly = asset.fly;
		//		flyAlways = asset.flyAlways;
		//	}

		//	if (asset.hideEars)
		//	{
		//		//ear
		//		//oreilleMat

		//		Material[] mats = skinnedMeshHead.materials;
		//		mats[1] = mats[0];
		//		skinnedMeshHead.materials = mats;
		//	}
		//}

		//RefreshSkin();
	}

	//---------------------------------------------------------------------------------------------

	public void MoveRandom()
	{
		//if (statePlay == null) return;

		bool destinationUndefined = true;

		//if (rabbit.apparence.Color == CAT_COLOR.EPIQUE_FLY)
		//{
		//	// find shits

		//	if (Shit.Shits.Count > 0)
		//	{
		//		Shit shit = Shit.Shits[0];
		//		destination = shit.transform.position;
		//		destinationUndefined = false;
		//	}
		//}
		//else if (rabbit.apparence.Color == CAT_COLOR.DEATH)
		//{
		//	// find grave
		//	RabbitModel grave = statePlay.FindDeadRabbitModel();

		//	if (grave != null)
		//	{
		//		destination = grave.transform.position - grave.transform.forward * 0.5f;
		//		destinationUndefined = false;
		//	}
		//}

		/*if (destinationUndefined && Cat.Properties.hunger < 0.2f)
		{
			// find carrot

			/*foreach (ItemField itemField in statePlay.itemFields)
			{
				if (itemField != null && itemField.GetItem() is Consumable consumable && consumable.Type == Consumable.TYPE.FOOD)
				{
					destination = itemField.transform.position;
					destinationUndefined = false;
					break;
				}
			}
		}*/

		if (destinationUndefined)
		{
			//destination = statePlay.GetPosition();
		}

		//Cat.position = statePlay.GetPositionRatio(destination);

		transform.LookAt(destination, Vector3.up);

		//destination -= statePlay.transformRabbits.position;
		//destination /= statePlay.transformRabbits.lossyScale.x;

		SetState(CAT_STATE.WALKING, Random.Range(3f, 10f));
	}

	//---------------------------------------------------------------------------------------------
	public bool IsObjective(bool remove = false)
	{
		if (Cat.IsLocked)
		{
			return false;
		}

		/*List<Apparence> objectives = Data.Instance.mission.objectives;

		if (objectives != null)
		{
			for (int i=0; i<objectives.Count; i++)
			{
				if (rabbit.apparence == objectives[i])
				{
					if (remove)
					{
						objectives.RemoveAt(i);
					}

					return true;
				}
			}
		}*/

		return false;
	}

	//---------------------------------------------------------------------------------------------

	public void Kill(bool withBlood)
	{
		if (debug)
		{
			Debug.Log(Cat.Id + " killed");
		}

		//if (Cat.Apparence.Color == CAT_COLOR.DEATH)
		//{
		//	return;
		//}

		//Data.Instance.stats.Dies++;

		SetState(CAT_STATE.DEAD, 10.0f);
		//Cat.dna.life = 0.0f;

		//bulle.SetActive(false);

		/*if (withBlood && Settings.mode > MODES.KIDS)
		{
			ParticleSystem ps = Instantiate(Interface.Instance.psBloodGrowing, transform.parent);
			ps.transform.position = new Vector3(transform.position.x, 0.01f, transform.position.z);
			Destroy(ps.gameObject, ps.main.duration);
		}*/
	}

	//------------------------------------------------------------------------------------------------

	public void SetState(CAT_STATE value, float delay = float.MaxValue)
	{
		Debug.Log($"CatModel.SetState({value})");

		alarm = Time.time + delay;

		if (State == value)
		{
			return;
		}

		if (debug)
		{
			Debug.Log(Cat.Id + " change State from " + State + " to " + value);
		}

		// Old value
		switch (State)
		{
			case CAT_STATE.FUCK:
			{
				if (partenaire != null)
				{
					partenaire.partenaire = null;
					partenaire.SetState(CAT_STATE.WALKING);
				}
				break;
			}
			case CAT_STATE.SHIT:
			{
				//Cat.Properties.dirty = Mathf.Max(0.0f, Cat.Properties.dirty - (Auras.lessDirty ? 0.35f : 0.7f));
				break;
			}

			case CAT_STATE.TAKING:
			{
				Vector3 euler = transform.eulerAngles;
				transform.rotation = Quaternion.Euler(0, euler.y, 0);
				takenRotate = 0.0f;
				break;
			}
			case CAT_STATE.SHOT:
			{
				//if (dart != null)
				//{
				//	dart.transform.position = Vector3.Lerp(handLeftTransform.position, dartPosition, 0.99f);
				//	dart.transform.SetParent(null);
				//	Destroy(dart);
				//	dart = null;
				//}
				break;
			}
			case CAT_STATE.EAT:
			{
				//if (eatItem != null)
				//{
				//	// On a arreté le lapin pendant qu'il mangeait => On restore la carotte
				//	Data.Instance.items.Add(eatItem);
				//	menuBar.Refresh();
				//	eatItem = null;
				//	mouthTransform.DestroyChildren();
				//}
				break;
			}
			case CAT_STATE.SEDUCE:
			{
				if (value != CAT_STATE.FUCK)
				{
					if (partenaire != null)
					{
						partenaire.partenaire = null;
						//partenaire.MoveRandom();
						partenaire = null;
					}
				}

				//if (heartPS != null)
				//{
				//	heartPS.Stop();
				//	Destroy(heartPS.gameObject, heartPS.main.duration);
				//	heartPS = null;
				//}
				break;
			}
			case CAT_STATE.SLEEP:
			{
				//if (sleepingPS != null)
				//{
				//	sleepingPS.Stop();
				//	Destroy(sleepingPS.gameObject);
				//	sleepingPS = null;
				//}

				//Cat.Properties.sleep = false;
				break;
			}
			case CAT_STATE.HIDE:
			{
				if (model.gameObject != null)
				{
					model.gameObject.SetActive(true);
				}
				break;
			}
		}

		State = value;

		// New Value
		switch (State)
		{
			case CAT_STATE.SLEEP:
			{
				//Cat.Properties.sleep = true;
				//sleepingPS = Instantiate(Interface.Instance.psSleeping, transform.position, transform.rotation, transform);
				break;
			}
		}

		UpdateAnimation(value);
	}

	//------------------------------------------------------------------------------------------------

	CAT_STATE previousState = CAT_STATE.INVALID;

	void UpdateAnimation(CAT_STATE state)
	{
		if (animator == null)
		{
			return;
		}

		if (state == previousState || animator.gameObject.activeInHierarchy == false)
		{
			return;
		}

		previousState = state;

		Debug.Log("UpdateAnimation " + state);

		switch (state)
		{
			case CAT_STATE.MENU:
				//animator.Play("Idle");
				animator.CrossFade(Random.value > 0.5f ? "Sit" : "Sit2", 0.2f);
				break;
			case CAT_STATE.IDLE:
				if (false) //flyAlways)
				{
					animator.CrossFade("FLY", 0.2f);
				}
				else
				{
					switch (Random.Range(0, 2))
					{
						case 0:
							animator.CrossFade("Idle", 0.2f);
							break;
						case 1:
							animator.CrossFade("Idle", 0.2f);
							break;
					}
				}
				break;
			case CAT_STATE.SHIT:
				animator.CrossFade("SHIT", 0.2f);
				break;
			case CAT_STATE.PUKE:
				animator.CrossFade("VOMI", 0.2f);
				break;
			case CAT_STATE.SIT:
				animator.CrossFade(Random.value > 0.5f ? "Sit" : "Sit2", 0.2f);
				break;
			case CAT_STATE.FORCE:
				animator.CrossFade("FORCE", 0.2f);
				break;
			case CAT_STATE.SHOT:
				animator.CrossFade("SHOTTARGET", 0.2f);
				break;
			case CAT_STATE.BUZZ:
				animator.CrossFade("BUZZIDLE", 0.2f);
				break;
			case CAT_STATE.READ:
				animator.CrossFade("READ", 0.2f);
				break;
			case CAT_STATE.BEAUTY:
				animator.CrossFade("BEAUTY", 0.2f);
				break;
			case CAT_STATE.GAME:
				animator.CrossFade("GAME", 0.2f);
				break;
			case CAT_STATE.WALKING:
				//animator.CrossFade(fly || flyAlways ? "FLY" : "Cat_Run", 0.2f);
				animator.CrossFade("Walk2", 0.2f);
				break;
			case CAT_STATE.SEDUCE:
				animator.CrossFade("SEDUCTION", 0.2f);
				break;
			case CAT_STATE.DEAD:
				animator.CrossFade("DEAD", 0.2f);
				break;
			case CAT_STATE.ANGE:
				animator.CrossFade("ANGE", 0.2f);
				break;
			case CAT_STATE.POSE:
				int val = Random.Range(0, 3);
				switch (val)
				{
					case 0:
						animator.CrossFade("POSE_1", 0.5f);
						break;
					case 1:
						animator.CrossFade("POSE_2", 0.5f);
						break;
					case 2:
						animator.CrossFade("POSE_3", 0.5f);
						break;
				}
				break;
			case CAT_STATE.MUTATION:
				animator.CrossFade("MUTATION", 0.2f);
				break;
			case CAT_STATE.FUCK:
				animator.CrossFade(/*frontPosition*/true ? "Cat_Hug_1" : "Cat_hug2", 0.2f);
						
				break;
			case CAT_STATE.EAT:
				animator.CrossFade("Cat_Eat", 0.2f);
				break;
			case CAT_STATE.TAKING:
				animator.CrossFade("grab", 0.2f);
				break;
			case CAT_STATE.SLEEP:
				animator.CrossFade("SLEEP", 0.5f);
				break;
			case CAT_STATE.HIDE:
				model.gameObject.SetActive(false);
				selection.gameObject.SetActive(false);
				menuBar.gameObject.SetActive(false);
				break;
		}

		//SetEyes();
	}

	//------------------------------------------------------------------------------------------------

	public void BecameTomb()
	{
		if (debug)
		{
			Debug.Log(Cat.Id + " became tomb");
		}

		SetState(CAT_STATE.DEAD, 10.0f);
		//Cat.dna.life = 0.0f;

		//RefreshBulle();

		tombModel = Instantiate(tombPrefab, transform.position, transform.rotation, transform);
		tombModel.transform.localPosition = new Vector3(0f, 1.6f, 0f);
		transform.rotation = Quaternion.Euler(0.0f, Random.Range(-45.0f, 45.0f), 0.0f);
		model.gameObject.SetActive(false);

		//if (legendaryBack != null)
		//{
		//	Destroy(legendaryBack);
		//	legendaryBack = null;
		//}

		//if (legendaryHead != null)
		//{
		//	Destroy(legendaryHead);
		//	legendaryHead = null;
		//}

		//if (legendaryTail != null)
		//{
		//	Destroy(legendaryTail);
		//	legendaryTail = null;
		//}

		//if (wings == null)
		//{
		//	wings = Instantiate(Interface.Instance.wings, body);
		//	wings.transform.localPosition = new Vector3(0.0f, 0.42f, 1.83f);
		//}

		//if (torus == null)
		//{
		//	torus = Instantiate(Interface.Instance.torus, head.parent);
		//}

		//ParticleSystem ps = Instantiate(Interface.Instance.psExplode, transform.position, transform.rotation, transform.parent);
		//ps.transform.localScale = new Vector3(0.4f, 0.4f, 0.4f);
		//Destroy(ps.gameObject, ps.main.duration);

		//if (Cat.Properties.dead == false)
		//{
		//	Cat.Properties.dead = true;
		//	if (statePlay != null)
		//	{
		//		rabbit.position = statePlay.GetPositionRatio(transform);
		//		rabbit.rotation = statePlay.GetRotation(transform);
		//	}

		//	rabbit.tombInfo = new TombInfo
		//	{
		//		age = rabbit.Age,
		//		ageStr = rabbit.GetAgeStr(),
		//		//epitaph = Local.Get("EPITAPH_" + Random.Range(1, 13).ToString("00"), rabbit.name),
		//		epitaphIndex = Random.Range(1, 13)
		//	};
		//}

		//if (Cat.Properties.zombie)
		//{
		//	BecameZombie();
		//	//zombie = statePlay.DoSpecial(SPECIAL.ZOMBIE, transform.position - Vector3.forward * 0.5f);
		//}

		//if (rabbit.apparence.IsLegendary())
		//{
		//	Auras.UpdateAuras();
		//}
	}

	//---------------------------------------------------------------------------------------------

// 	public bool Apply(Item item)
// 	{
// 		Data.Instance.Remove(item);
//
// 		if (item is Candy candy)
// 		{
// 			Data.Instance.stats.EatCandies++;
// 			//FXChangeColor(candy.Color);
//
// 			Cat.Apparence.Color = candy.Color;
// 			Data.Instance.Unlock(Cat.Apparence);
//
// 			Refresh();
//
// 			if (!statePlay.Busy() && statePlay.mission.Index == 0 && Tutorial.HasArrrow() == false && rabbit.apparence == new Apparence(CAT_COLOR.RED))
// 			{
// 				Farmer farmer = Instantiate(Interface.Instance.farmer);
// 				farmer.Say(DIALOG.STANDARD, Local.Get("TUTO1_1"));
// 				farmer.Say(DIALOG.STANDARD, Local.Get("TUTO1_2"));
// 				farmer.Say(DIALOG.STANDARD, Local.Get("TUTO1_3"));
// 				farmer.Say(DIALOG.STANDARD, Local.Get("TUTO1_4"));
// 				farmer.Say(DIALOG.STANDARD, Local.Get("TUTO1_5"));
// 			}
//
// 			return true;
// 		}
// 		else if (item is Carrot carrot)
// 		{
// 			if (Cat.Apparence.Color == carrot.Color)
// 			{
// 				//Cat.dna.life = Mathf.Clamp01(Cat.Properties.life + 0.25f);
// 				//Cat.Properties.hunger = 1.0f;
// 			}
// 			else
// 			{
// 				//Cat.Properties.hunger = Mathf.Clamp01(Cat.Properties.hunger + CARROT_HUNGRY);
// 			}
// 			return true;
// 		}
// 		else if (item is Consumable consumable)
// 		{
// 			switch (consumable.Type)
// 			{
// 				case Consumable.TYPE.SOAP:
// 					//washPS = Instantiate(Interface.Instance.psWash, transform);
// 					break;
// 				case Consumable.TYPE.VIAGRA:
// 					//Cat.Properties.love = 1.0f;
// 					StatePlay.PlayFX(Interface.Instance.psCartoonyBodySlam, transform.position);
// 					break;
// 				case Consumable.TYPE.HEAL:
// 					StatePlay.PlayFX(Interface.Instance.psHeal, transform.position);
//
// 					//Cat.Properties.immune = true;
// 					//Cat.Properties.life = 1.0f;
// 					//Cat.Properties.sick = false;
// 					//if (sickPS != null)
// 					//{
// 					//	sickPS.Stop(true);
// 					//	Destroy(sickPS, 2.0f);
// 					//	sickPS = null;
// 					//}
// 					break;
// 				case Consumable.TYPE.CHILLI_PEPPER:
// //					Cat.Properties.cold = 1.0f;
// 					break;
// 				case Consumable.TYPE.FOOD:
// 					Data.Instance.stats.EatCarrots++;
// 					//Cat.Properties.hunger = 1.0f;
// 					//Cat.Properties.life = Mathf.Clamp01(Cat.Properties.life + 0.1f);
// 					break;
// 				case Consumable.TYPE.POISON:
// 					//Cat.Properties.BecameSick();
// 					break;
// 				case Consumable.TYPE.DRUG:
// 					if (Cat.IsLegendary)
// 					{
// 						CAT_COLOR legendaryIndex = Cat.Apparence.Color;
// 						Progress progress = Data.Instance.GetProgress(legendaryIndex);
// 						progress.SetEnergy(progress.GetEnergy() + 1.0f);
// 					}
//
// 					break;
// 				case Consumable.TYPE.ZOMBIE:
// 					//BecameZombie();
// 					break;
// 				case Consumable.TYPE.COFFEE:
// 					ItemModel reveil = Instantiate(Interface.Instance.coffeeModelPrefab, transform);
// 					reveil.transform.localPosition = Vector3.up * 6.0f;
// 					reveil.transform.localScale = Vector3.one * 8.0f;
// 					reveil.gameObject.AddComponent<Billboard>();
// 					iTween.PunchScale(reveil.gameObject, Vector3.one * 10.0f, 0.5f);
//
// 					Destroy(reveil.gameObject, 2.0f);
// 					//Cat.Properties.tired = 1.0f;
// 					break;
// 				case Consumable.TYPE.LOLLIPOP:
// 					Data.Instance.stats.EatLollipops++;
// 					//FXChangeColor(rabbit.apparence.Color);
// 					Cat.Apparence.Inverse();
// 					Data.Instance.Unlock(Cat.Apparence);
// 					Refresh();
// 					break;
// 				default:
// 					return false;
// 			}
// 			return true;
// 		}
// 		else if (item is Permanent permanent)
// 		{
// 			switch (permanent.Type)
// 			{
// 				case Permanent.TYPE.LOVE:
// 					Cat.Properties.loveBonus = Mathf.Min(Cat.Properties.loveBonus + 0.2f, 2.0f - Cat.Properties.loveCoef);
// 					break;
// 				case Permanent.TYPE.SICK:
// 					Cat.Properties.sickBonus = Mathf.Min(Cat.Properties.sickBonus + 0.2f, 2.0f - Cat.Properties.sickCoef);
// 					break;
// 				case Permanent.TYPE.TIRED:
// 					Cat.Properties.tiredBonus = Mathf.Min(Cat.Properties.tiredBonus + 0.2f, 2.0f - Cat.Properties.tiredCoef);
// 					break;
// 				case Permanent.TYPE.HUNGER:
// 					Cat.Properties.hungerBonus = Mathf.Min(Cat.Properties.hungerBonus + 0.2f, 2.0f - Cat.Properties.hungerCoef);
// 					break;
// 				case Permanent.TYPE.LIFE:
// 					Cat.Properties.lifeBonus = Mathf.Min(Cat.Properties.lifeBonus + 0.2f, 2.0f - Cat.Properties.lifeCoef);
// 					break;
// 				case Permanent.TYPE.COLD:
// 					Cat.Properties.coldBonus = Mathf.Min(Cat.Properties.coldBonus + 0.2f, 2.0f - Cat.Properties.coldCoef);
// 					break;
// 				default:
// 					return false;
// 			}
// 			return true;
// 		}
//
// 		return false;
// 	}
	//---------------------------------------------------------------------------------------------
	public void Apply()
	{
		//Apply(skinnedMeshBody);
		//Apply(skinnedMeshHead);
		//Apply(skinnedMeshLegs);
		//Apply(skinnedMeshBalls);

		ApplyMaterials();
		ApplyBlendshapes();		
	}

	//---------------------------------------------------------------------------------------------
	public void ApplyBlendshapes()
	{
		if (Cat.Apparence.Morpho > 0.0f)
		{
			skinnedMeshBody.SetBlendShapeWeight(0, 100.0f * Cat.Apparence.Morpho);
			skinnedMeshBody.SetBlendShapeWeight(1, 0.0f);

			skinnedMeshHead.SetBlendShapeWeight(4, 100.0f * Cat.Apparence.Morpho);
			skinnedMeshHead.SetBlendShapeWeight(5, 0.0f);

			skinnedMeshLegs.SetBlendShapeWeight(0, 100.0f * Cat.Apparence.Morpho);
			skinnedMeshLegs.SetBlendShapeWeight(1, 0.0f);
		}
		else
		{
			skinnedMeshBody.SetBlendShapeWeight(0, 0.0f);
			skinnedMeshBody.SetBlendShapeWeight(1, -100.0f * Cat.Apparence.Morpho);

			skinnedMeshHead.SetBlendShapeWeight(4, 0.0f);
			skinnedMeshHead.SetBlendShapeWeight(5, -100.0f * Cat.Apparence.Morpho);

			skinnedMeshLegs.SetBlendShapeWeight(0, 0.0f);
			skinnedMeshLegs.SetBlendShapeWeight(1, -100.0f * Cat.Apparence.Morpho);
		}

		for (int tailIndex = 0; tailIndex < Tails.Length; tailIndex++)
		{
			Tails[tailIndex].SetActive(tailIndex == Cat.Apparence.Tail);
		}

		Testiboules.SetActive(Cat.Apparence.Male);
	}

	//---------------------------------------------------------------------------------------------

	public bool BeginApply(Item item)
	{
		if (item == null)
		{
			Debug.LogError("Cannot eat NULL item");
			return false;
		}

		if (CanApply(item) == false)
		{
			// Cancel eat
			return false;
		}

		ApplyEffect(item);

		//Data.Instance.Remove(item);

		return true;
	}

	//---------------------------------------------------------------------------------------------

	void ApplyEffect(Item item)
	{
		if (item.IsEat())
		{
			// Eating
			SetState(CAT_STATE.EAT, 2.0f);

			//eatItem = item;

			//ItemModel itemModelPrefab = Interface.Instance.GetItemModelPrefab(item);

			// if (itemModelPrefab)
			// {
			// 	ItemModel itemModel = Instantiate(itemModelPrefab, transform /*mouthTransform*/);
			// 	itemModel.transform.localScale *= 15.0f;
			// 	itemModel.Init(item);
			//
			// 	/*if (itemModel is CarrotModel carrotModel)
			// 	{
			// 		Debug.Log("-------------------oooh");
			// 		itemModel.transform.localPosition = new Vector3(0f, 2f, 0f);
			// 		carrotModel.motte.SetActive(false);
			// 	}*/
			//
			// 	if (itemModel is FoodModel foodModel)
			// 	{
			// 		itemModel.transform.localPosition = new Vector3(0f, 2f, 0f);
			// 		foodModel.motte.SetActive(false);
			// 	}
			//
			// 	if (itemModel.Item is Consumable conso && conso.Type == Consumable.TYPE.VIAGRA)
			// 	{
			// 		itemModel.transform.localPosition = new Vector3(0f, -1.5f, 0f);
			// 		itemModel.transform.localScale = Vector3.one;
			// 	}
			//
			// 	if (item is Candy candy)
			// 	{
			// 		Animator animator = itemModel.GetComponent<Animator>();
			// 		Destroy(animator);
			//
			// 		Color col = Rabbit.GetColor(candy.Color);
			//
			// 		ParticleSystem ps = Instantiate(Interface.Instance.psMagicCharge, transform);
			// 		ParticleSystem ps2 = ps.transform.GetChild(0).GetComponent<ParticleSystem>();
			//
			// 		ps.startColor = col;
			// 		ps2.startColor = col;
			//
			// 		Destroy(ps.gameObject, 2.0f);
			// 	}
			//
			// 	if (item is Consumable consumable && consumable.Type == Consumable.TYPE.LOLLIPOP)
			// 	{
			// 		Color col = Rabbit.GetColor(Cat.Apparence.Color);
			//
			// 		ParticleSystem ps = Instantiate(Interface.Instance.psMagicCharge, transform);
			// 		ParticleSystem ps2 = ps.transform.GetChild(0).GetComponent<ParticleSystem>();
			//
			// 		ps.startColor = col;
			// 		ps2.startColor = col;
			//
			// 		Destroy(ps.gameObject, 2.0f);
			// 	}
			//
			// }
			// return;
		}

		SetState(CAT_STATE.IDLE, 2.0f);

		//Apply(item);
	}

	//---------------------------------------------------------------------------------------------
	// Est ce que le lapin est en état de manger ?

	public bool CanApply(Item item)
	{
		// if (item is Gift)
		// {
		// 	return false;
		// }
		//
		// if (Cat.IsLegendary)
		// {
		// 	if (item is Candy ||
		// 		(item is Consumable consumable1 && consumable1.Type == Consumable.TYPE.LOLLIPOP))
		// 	{
		// 		return false;
		// 	}
		// }
		// else
		// {
		// 	if (item is Consumable consumable2 && consumable2.Type == Consumable.TYPE.DRUG)
		// 	{
		// 		return false;
		// 	}
		// }
		//
		// if (item is Consumable consumable && consumable.Type == Consumable.TYPE.LOLLIPOP && Cat.Apparence.Shape == CAT_SHAPE.NONE)
		// {
		// 	return false;
		// }
		//
		// if (item is Candy candy && candy.Color == Cat.Apparence.Color)
		// {
		// 	// Cannot eat a candy of my color
		// 	return false;
		// }
		//
		// switch (State)
		// {
		// 	case CAT_STATE.IDLE:
		// 	case CAT_STATE.WALKING:
		// 	case CAT_STATE.SEDUCE:
		// 		return true;
		// 	case CAT_STATE.SLEEP:
		// 		return (item is Consumable conso && conso.Type == Consumable.TYPE.COFFEE);
		// }

		return false;
	}

	//---------------------------------------------------------------------------------------------

	//void Apply(SkinnedMeshRenderer skinnedMeshRenderer)
	//{		
	//	//Cat.Apparence.AffectMaterial(material);

	//	//material.SetColor("_Color", Cat.GetColor(Cat.Apparence.Color));
	//	//material.SetFloat("_ShapeAlpha", Cat.Apparence.ShapeAlpha);
	//	//material.SetColor("_BackColor", Cat.GetColor(Cat.Apparence.BackColor));
	//	//material.SetColor("_DetailColor", Cat.GetColor(Cat.Apparence.TruffeColor));		
	//}

	//---------------------------------------------------------------------------------------------
	void ApplyMaterials()
	{
		Debug.Log("ApplyMaterials()");

		if (material == null)
		{
			Debug.Log("NULL Mat");

			material = new Material(skinnedMeshBody.material);
			skinnedMeshBody.material = material;
			skinnedMeshHead.material = material;
			skinnedMeshLegs.material = material;
			skinnedMeshBalls.material = material;

			foreach (Renderer renderer in skinnedMeshTails)
			{
				renderer.material = material;
			}
		}

		if (truffeMaterial == null)
		{
			truffeMaterial = new Material(skinnedMeshTruffe.material);
			skinnedMeshTruffe.material = truffeMaterial;
		}

		if (eyesMaterial == null)
		{
			eyesMaterial = new Material(skinnedMeshEyes.material);
			skinnedMeshEyes.material = eyesMaterial;
		}

		// Set Cat color

		material.color = Cat.GetColor(Cat.Apparence.Color);
		material.SetFloat("_BaseRatio", Cat.Apparence.BaseRatio);
		if (material == null)
		{
			Debug.LogError("ApplyMaterials: material is null");
		}
		else if (Interface.Instance == null)
		{
			Debug.LogError("ApplyMaterials: Interface.Instance is null");
			material.SetTexture("_ZoneShape", null);
		}
		else if (Cat == null || Cat.Apparence == null)
		{
			Debug.LogError("ApplyMaterials: Cat or Cat.Apparence is null");
			material.SetTexture("_ZoneShape", null);
		}
		else
		{
			Texture zoneTex = null;
			try
			{
				zoneTex = Interface.Instance.GetZoneTexture(Cat.Apparence.Zone);
			}
			catch (System.Exception ex)
			{
				Debug.LogError("ApplyMaterials: GetZoneTexture threw: " + ex);
			}

			if (zoneTex == null)
			{
				Debug.LogWarning("ApplyMaterials: zone texture is null for zone " + Cat.Apparence.Zone);
			}

			material.SetTexture("_ZoneShape", zoneTex);
		}
		material.SetColor("_DetailColor", Cat.GetColor(Cat.Apparence.TruffeColor));

		if (Cat.Apparence.Shape != CAT_SHAPE.INVALID && Cat.Apparence.Shape != CAT_SHAPE.NONE)
		{
			material.SetFloat("_ShapeAlpha", Cat.Apparence.ShapeAlpha);
			material.SetTexture("_TexShape", Interface.Instance.GetShapeTexture(Cat.Apparence.Shape));
		}
		else
		{
			material.SetFloat("_ShapeAlpha", 0.0f);
			material.SetTexture("_TexShape", null);
		}

		truffeMaterial.SetColor("_Color", Cat.GetColor(Cat.Apparence.TruffeColor));
		eyesMaterial.SetColor("_FresnelColor", Cat.GetColor(Cat.Apparence.EyesColor));
	}

	//---------------------------------------------------------------------------------------------
	public void Select(bool select)
	{
		selection.gameObject.SetActive(select);
		menuBar.gameObject.SetActive(select);

		if (select)
		{
			menuBar.rabbitModel = this;
			menuBar.Back();
			//bulle.SetActive(false);
		}
	}

	//---------------------------------------------------------------------------------------------
	public void Take()
	{
		SetState(CAT_STATE.TAKING);
	}

	//---------------------------------------------------------------------------------------------

	public void Release()
	{
		if (debug)
		{
			Debug.Log("Release()");
		}

		takenRotate = 0.0f;
		SetState(CAT_STATE.IDLE, Random.Range(5.0f, 10));
		transform.localPosition = new Vector3(transform.localPosition.x, 0.0f, transform.localPosition.z);
		model.transform.localRotation = Quaternion.identity;
		//model.transform.localPosition = new Vector3(0,1.2f,0);
		model.transform.localPosition = Vector3.zero;
		UpdateSize();

		//if (rabbit.apparence.Color == CAT_COLOR.EPIQUE_TICTAC)
		//{
		//	Data.Instance.SetBoost(1.0f);
		//	AudioService.Instance.UpdateSpeed(1.0f, 0.5f);
		//}

		// if (statePlay != null && inField)
		// {
		// 	if (CheckFuck() == false)
		// 	{
		// 		CheckItem();
		// 	}
		// }
	}

	//---------------------------------------------------------------------------------------------
	bool CheckFuck()
	{
		CatModel otherRabbitModel;
		if ((otherRabbitModel = GetNearestCat(out float distance)))
		{
			// if (distance < StatePlay.DISTANCE_FUCK &&
			// 	!otherRabbitModel.Cat.IsChild &&
			// 	!Cat.IsChild &&
			// 	(otherRabbitModel.State == CAT_STATE.IDLE))
			// {
			// 	float delay = 3.0f;
			//
			// 	SetState(CAT_STATE.SEDUCE, delay);
			// 	otherRabbitModel.SetState(CAT_STATE.SEDUCE);
			//
			// 	partenaire = otherRabbitModel;
			// 	otherRabbitModel.partenaire = this;
			//
			// 	Vector3 euler = otherRabbitModel.transform.rotation.eulerAngles;
			// 	euler.y += 180f;
			// 	transform.rotation = Quaternion.Euler(euler);
			// 	transform.localPosition = otherRabbitModel.transform.localPosition + otherRabbitModel.transform.forward * 0.4f; //0.4f
			//
			// 	//heartPS = Instantiate(Interface.Instance.psHeartEmit, (otherRabbitModel.transform.position + transform.position) * 0.5f, Interface.Instance.psHeartEmit.transform.rotation, transform.parent);
			// 	//Destroy(heartPS.gameObject, heartPS.main.duration);
			//
			// 	return true;
			// }
		}

		return false;
	}

	//---------------------------------------------------------------------------------------------

	CatModel GetNearestCat(out float distance)
	{
		distance = float.MaxValue;
		CatModel nearestRabbit = null;

		// if (statePlay == null)
		// {
		// 	return null;
		// }

		// foreach (CatModel rabbit in statePlay.catModels)
		// {
		// 	if (rabbit == null || rabbit == this) continue;
		// 	if (rabbit.State == CAT_STATE.DEAD) continue;
		//
		// 	float newDistance = Vector3.Magnitude(rabbit.transform.position - transform.position);
		// 	if (distance > newDistance)
		// 	{
		// 		distance = newDistance;
		// 		nearestRabbit = rabbit;
		// 	}
		// }

		return nearestRabbit;
	}

	//---------------------------------------------------------------------------------------------

	public bool Selected()
	{
		if (selection == null)
		{
			return false;
		}
		return selection.gameObject.activeInHierarchy;
	}

	//---------------------------------------------------------------------------------------------

	private void Update()
	{
		// if (StateMachine.pause) return;
		//
		// if (tombModel != null &&
		// 	alarm < Time.time)
		// {
		// 	alarm = Time.time + 30f;
		//
		// 	if (Random.value < Probability.becameZombie && Data.Instance.CountNumberOfZombies() < 4)
		// 	{
		// 		//BecameZombie();
		// 	}
		// }

		if (State == CAT_STATE.MENU /* || Cat.Properties.dead */) return;

		if (inField && alarmSec < Time.unscaledTime)
		{
			Update1Sec();
			alarmSec = Time.unscaledTime + 1.0f;
		}

		switch (State)
		{
			case CAT_STATE.IDLE:
			{
				if (alarm < Time.time)
				{
					//UpdateProbability();

					// if (Cat.Properties.tired <= 0.0f || Cat.Properties.sleep)
					// {
					// 	SetState(CAT_STATE.SLEEP, Random.Range(30f, 60f));
					// 	Cat.Properties.sleep = true;
					// }
					// //else if (Random.value < 0.002f && Shit.nbShit < 10)
					// else if (Random.value < 0.005f && Shit.nbShit < 10)
					// {
					// 	if (inField)
					// 	{
					// 		shitDelay = Random.Range(0.3f, 0.6f);
					// 		SetState(CAT_STATE.SHIT, 3.4f);
					// 	}
					// }
					// else
					// {
					// 	if (Cat.Properties.sick)
					// 	{
					// 		if (Random.value < 0.05f && Shit.nbShit < 10)
					// 		{
					// 			shitDelay = Random.value < 0.1f ? Random.Range(0.01f, 0.4f) : Random.Range(0.2f, 0.4f);
					// 			SetState(CAT_STATE.SHIT, 3.4f);
					// 		}
					// 		else if (Random.value < 0.1f)
					// 		{
					// 			//ParticleSystem ps = Instantiate(Interface.Instance.psVomit, mouthTransform);
					// 			//Destroy(ps.gameObject, ps.main.duration);
					//
					// 			//SetState(CAT_STATE.PUKE, ps.main.duration + 0.5f);
					// 		}
					// 		else
					// 		{
					// 			MoveRandom();
					// 		}
					// 	}
					// 	else
					// 	{
					// 		MoveRandom();
					// 	}
					// }
				}

				break;
			}

			case CAT_STATE.SLEEP:
			{
				//Cat.Properties.tired += Cat.Properties.tiredCoef * statePlay.mission.tiredSpeed * Time.deltaTime;

				if (inField)
				{
					//if (Cat.Properties.hunger <= 0.0f)
					//{
					//	MoveRandom();
					//}
					//else if (Cat.Properties.tired >= 1.0f)
					//{
					//	Cat.Properties.sleep = false;
					//	SetState(CAT_STATE.IDLE, Random.Range(5f, 10f));
					//}
				}

				break;
			}

			case CAT_STATE.SHIT:
			{
				//if (alarmShit < Time.time)
				//{
				//	if (shitLot == null)
				//	{
				//		GameObject go = new GameObject("shit");
				//		shitLot = go.AddComponent<Shit>();
				//		Vector3 pos = tail.transform.position;
				//		pos.y = transform.position.y;
				//		shitLot.transform.position = pos;
				//		ParticleSystem ps = Instantiate(Interface.Instance.psShitSmoke, shitLot.transform);
				//		ps.transform.localPosition = Vector3.zero;

				//		Color color = ps.main.startColor.color;
				//		color.a = Mathf.InverseLerp(0.5f, -0.3f, shitDelay);
				//		ps.startColor = color;

				//		/*var col = ps.main.startColor;
				//		col.color.a = Mathf.InverseLerp(0.4f, 0.0f, shitDelay);*/
				//	}

				//	Instantiate(Interface.Instance.shitPrefab, tail.transform.position + 0.05f * Vector3.down + 0.01f * Random.insideUnitSphere, Quaternion.identity, shitLot.transform);
				//	alarmShit = Time.time + shitDelay;
				//}

				//if (alarm < Time.time)
				//{
				//	shitLot = null;
				//	MoveRandom();
				//}

				break;
			}

			case CAT_STATE.PUKE:
			case CAT_STATE.POSE:
			{
				if (alarm < Time.time)
				{
					SetState(CAT_STATE.IDLE, 0.5f);
				}

				break;
			}

			case CAT_STATE.DEAD:
			{
				if (alarm < Time.time)
				{
					BecameTomb();
				}

				break;
			}

			case CAT_STATE.SHOT:
			{
				AnimatorStateInfo info = animator.GetCurrentAnimatorStateInfo(0);

				//if (info.normalizedTime > 0.0f)
				//{
				//	if (dart == null && info.normalizedTime < 0.5f)
				//	{
				//		CarrotModel carrotModel = Instantiate(Interface.Instance.carrotModelPrefab, handLeftTransform);
				//		carrotModel.motte.SetActive(false);
				//		dart = carrotModel.gameObject;
				//		dart.transform.localScale = Vector3.one;

				//		//carrotModel.model.transform.localRotation = Quaternion.Euler(-90.0f, 0f, 0f);
				//		carrotModel.model.transform.localRotation = Quaternion.Euler(-90.0f, 0f, 0f);

				//		dartPosition = Mill.Instance.positionTarget.position + Mill.Instance.positionTarget.rotation * new Vector3(0.35f * (Random.value - 0.5f), 0.35f * (Random.value - 0.5f), 0f);
				//		//lookAt.target = Mill.Instance.positionTarget;
				//	}

				//	if (dart != null)
				//	{
				//		if (info.normalizedTime > 0.5f && dart.GetComponent<LookAt>() == null)
				//		{
				//			LookAt lookAt = dart.AddComponent<LookAt>();
				//			lookAt.worldPosition = dartPosition;
				//		}

				//		float ratio = 50.0f * (info.normalizedTime - 0.5f);
				//		dart.transform.position = Vector3.Lerp(handLeftTransform.position + new Vector3(-0.05f, 0f, 0f), dartPosition, Mathf.Min(0.99f, ratio));

				//		if (ratio > 1.0f)
				//		{
				//			if (dart != null)
				//			{
				//				dart.transform.position = Vector3.Lerp(handLeftTransform.position, dartPosition, 0.99f);
				//				DestroyImmediate(dart.GetComponent<LookAt>());
				//				dart.transform.localRotation = Quaternion.Euler(0f, 0f, Random.value * 360.0f);
				//				dart.transform.SetParent(null);
				//				Destroy(dart, 30.0f);
				//				dart = null;
				//			}
				//		}
				//	}
				//}
				//else
				//{
				//	if (dart != null)
				//	{
				//		dart.transform.position = Vector3.Lerp(handLeftTransform.position, dartPosition, 0.99f);
				//		dart.transform.SetParent(null);
				//		Destroy(dart, 10.0f);
				//		dart = null;
				//	}
				//}

				break;
			}

			case CAT_STATE.EAT:
			{
				if (alarm < Time.time)
				{
					// la carotte est complètement mangée 

					// Apply(eatItem);
					//
					// eatItem = null;
					// //mouthTransform.DestroyChildren();
					//
					// Refresh();
					//
					// SetState(CAT_STATE.IDLE, Random.Range(10f, 30f) * Data.boostReal);
					//
					// menuBar.Refresh();
				}
				break;
			}

			case CAT_STATE.TAKING:
			{
				/*Vector3 takePos = statePlay.takenClic;

				Vector3 translate = takePos - earsList[0].transform.position;
				transform.position += translate;
				*/

				//transform.position = Ground.positionClicHF;

				Vector3 rotation = transform.localRotation.eulerAngles;
				// if (rotation.y < 180.0f)
				// {
				// 	transform.Rotate(0.0f, 100.0f * Ground.deltaClic.magnitude + 90.0f * Time.deltaTime, 0.0f, Space.Self);
				// }
				// else if (rotation.y >= 180.0f)
				// {
				// 	transform.Rotate(0.0f, -100.0f * Ground.deltaClic.magnitude - 90.0f * Time.deltaTime, 0.0f, Space.Self);
				// }
				//
				// float angle = -takenRotate * 6.0f * Time.deltaTime - 60.0f * Ground.deltaClic.x;
				// takenRotate += angle;
				//model.transform.RotateAround(earsList[0].transform.position, Vector3.forward, angle);

				break;
			}

			case CAT_STATE.WALKING:
			{
				if (inField)
				{

					Vector3 move = destination - transform.localPosition;
					move.y = 0.0f;

					// if (move.magnitude > 0.1f && animator != null)
					// {
					// 	AnimatorStateInfo info = animator.GetCurrentAnimatorStateInfo(0);
					//
					// 	//if ((info.normalizedTime > 0.26f && info.normalizedTime < 0.94f)/* || fly || flyAlways*/)
					// 	{
					// 		transform.localPosition += /*0.05f **/ move.normalized * Time.deltaTime * (Cat.Properties.sick ? 0.5f : 1.0f);
					// 	}
					// }
				}
				break;
			}

			case CAT_STATE.SEDUCE:
			{
				//if (alarm < Time.time)
				//{
				//	SPRITE_BULLE reason = Cat.ReadyForSex();
				//	SPRITE_BULLE reasonP = partenaire.rabbit.ReadyForSex();

				//	if (!Settings.unlockAll &&
				//		((Data.Instance.Cats.Count >= Data.Instance.MaxRabbits && !Data.Instance.IsMutationReady()) ||
				//		reason != SPRITE_BULLE.OK ||
				//		reasonP != SPRITE_BULLE.OK))
				//	{
				//		// Honey my head hurts... sorry.

				//		if (reason != SPRITE_BULLE.OK)
				//		{
				//			ShowBulle(reason);
				//		}
				//		if (reasonP != SPRITE_BULLE.OK)
				//		{
				//			partenaire.ShowBulle(reasonP);
				//		}

				//		if (Data.Instance.Cats.Count >= Data.Instance.MaxRabbits)
				//		{
				//			ShowBulle(SPRITE_BULLE.BULLE_4_NOSPACE);
				//			partenaire.ShowBulle(SPRITE_BULLE.BULLE_4_NOSPACE);
				//		}

				//		if (Farmer.window == null)
				//		{
				//			if (Data.NbUnlocked < 20 && (Data.Instance.Cats.Count >= Data.Instance.MaxRabbits) && !StatePlay.Instance.menu.activeInHierarchy)
				//			{
				//				Farmer farmer = Instantiate(Interface.Instance.farmer);
				//				farmer.Say(DIALOG.STANDARD, Local.Get("TUTO11_1"));
				//				farmer.Say(DIALOG.STANDARD, Local.Get("TUTO11_2"));
				//				farmer.Do(() =>
				//				{
				//					Tutorial.SetArrow(StatePlay.Instance.forSaleCollider.transform);
				//				});
				//			}
				//			else if (Data.NbUnlocked < 10 && (reason == SPRITE_BULLE.BULLE_2_LEWD || reasonP == SPRITE_BULLE.BULLE_2_LEWD))
				//			{
				//				Farmer farmer = Instantiate(Interface.Instance.farmer);
				//				farmer.Say(DIALOG.STANDARD, Local.Get("TUTO13_1"));
				//				farmer.Say(DIALOG.STANDARD, Local.Get("TUTO13_2"));
				//				farmer.Say(DIALOG.STANDARD, Local.Get("TUTO13_3"));
				//				farmer.Do(() =>
				//				{
				//					Tutorial.SetArrow(StatePlay.Instance.actionBar.boostButton.transform);
				//				});
				//			}
				//		}



				//		partenaire.SetState(CAT_STATE.IDLE, 0.5f);
				//		SetState(CAT_STATE.IDLE, 0.5f);

				//		return;
				//	}

				//	//Fuck now :)					
				//	float delay = DELAY_FUCK;

				//	Vector3 center = 0.5f * (partenaire.transform.localPosition + transform.localPosition);
				//	SEX_POSITION sexPos = Data.Instance.GetRandomSexPosition();

				//	if (debug)
				//	{
				//		Debug.Log("I want this sex position " + sexPos.ToString());
				//	}

				//	float sexOffsetX = 0.0f; // sexOffsets[(int)sexPos];
				//	bool sexSameSideX = sexSameSide[(int)sexPos];

				//	sexPosition = sexPos;
				//	partenaire.sexPosition = sexPos;

				//	Vector3 euler = transform.rotation.eulerAngles;
				//	if (!sexSameSideX)
				//	{
				//		euler.y += 180f;
				//	}

				//	partenaire.transform.rotation = Quaternion.Euler(euler);
				//	//partenaire.transform.localPosition = center + new Vector3(sexOffsetX, 0.0f, 0.0f);
				//	//transform.localPosition = partenaire.transform.localPosition - partenaire.transform.forward * sexOffsetX;
				//	partenaire.destination = center + new Vector3(sexOffsetX, 0.0f, 0.0f);
				//	destination = partenaire.destination - partenaire.transform.forward * sexOffsetX;

				//	frontPosition = true;
				//	partenaire.frontPosition = false;

				//	SetState(CAT_STATE.FUCK, delay);
				//	partenaire.SetState(CAT_STATE.FUCK);

				//	ParticleSystem ps = Instantiate(Interface.Instance.psHeartExpose, transform.parent);
				//	ps.transform.localPosition = center;
				//	ps.transform.localScale = new Vector3(0.4f, 0.4f, 0.4f);
				//	Destroy(ps.gameObject, ps.main.duration);

				//	if (Settings.mode == MODES.ADULT_HUG_WITH_MOSAICS && !Settings.no_mosaic)
				//	{
				//		sexyMosaic = Instantiate(StatePlay.Instance.sexyMosaicPrefab, partenaire.transform.parent.position + destination, Quaternion.identity);
				//		Destroy(sexyMosaic.gameObject, 3.0f);
				//	}
				//}
				break;
			}

			case CAT_STATE.FUCK:
			{
				//Vector3 move = destination - transform.localPosition;
				//move.y = 0.0f;

				//if (move.magnitude > 0.0001f)
				//{
				//	Vector3 displace = move.normalized * 2.0f * Time.deltaTime;

				//	if (displace.magnitude < move.magnitude)
				//	{
				//		transform.localPosition += move.normalized * 2.0f * Time.deltaTime;
				//	}
				//	else
				//	{
				//		transform.localPosition = destination;
				//	}
				//}

				////transform.localPosition = (destination + 9f*transform.localPosition) /10.0f;

				//if (alarm < Time.time)
				//{
				//	Vector3 center = 0.5f * (partenaire.transform.localPosition + transform.localPosition);

				//	destination = center + transform.forward * 0.6f;
				//	partenaire.destination = center - transform.forward * 0.6f;

				//	if (!Auras.noContagious && (Cat.Properties.sick || partenaire.Cat.Properties.sick))
				//	{
				//		Cat.Properties.BecameSick();
				//		partenaire.Cat.Properties.BecameSick();

				//		ShowBulle(SPRITE_BULLE.BULLE_7_SICK);
				//		partenaire.ShowBulle(SPRITE_BULLE.BULLE_7_SICK);
				//	}

				//	Vector3 direction = partenaire.transform.eulerAngles;
				//	direction.y += 180.0f;
				//	transform.eulerAngles = direction;

				//	if (statePlay.catModels.Count < 100)
				//	{
				//		// moins envie de sex now

				//		Cat.Properties.love = Mathf.Clamp01(Cat.Properties.love - 0.5f);
				//		partenaire.Cat.Properties.love = Mathf.Clamp01(partenaire.Cat.Properties.love - 0.5f);

				//		// On fait le bébé

				//		int numberOfBabies;
				//		bool forceDarkNight = false;

				//		if (rabbit.IsLegendary || partenaire.rabbit.IsLegendary)
				//		{
				//			//if (!Data.Instance.IsUnlocked(CAT_COLOR.EPIQUE_DARKKNIGHT) &&
				//			//	((rabbit.apparence.Color == CAT_COLOR.NORMAL_KNIGHT && partenaire.rabbit.apparence.Color == CAT_COLOR.RARE_PRINCESS) ||
				//			//	(rabbit.apparence.Color == CAT_COLOR.RARE_PRINCESS && partenaire.rabbit.apparence.Color == CAT_COLOR.NORMAL_KNIGHT)))
				//			//{
				//			//	forceDarkNight = true;
				//			//	numberOfBabies = 1;
				//			//}
				//			//else
				//			{
				//				numberOfBabies = 0;
				//			}
				//		}
				//		else
				//		{
				//			numberOfBabies = Random.value < 0.01f ? 2 : 1;
				//		}

				//		Data.Instance.stats.MakeBabies += numberOfBabies;

				//		for (int n = 0; n < numberOfBabies; n++)
				//		{
				//			Rabbit child = null;

				//			if (forceDarkNight)
				//			{
				//				//child = Rabbit.CreateNewLegendary(CAT_COLOR.EPIQUE_DARKKNIGHT, 0.0);
				//			}
				//			else
				//			{
				//				Apparence apparence = new Apparence(rabbit.apparence, partenaire.rabbit.apparence, Data.NbUnlocked < 20);

				//				if (Data.Instance.IsMutationReady())
				//				{
				//					if (apparence.Shape == CAT_SHAPE.NONE)
				//					{
				//						CAT_SHAPE shape = Data.Instance.GetNextUnlockedShape();
				//						CAT_COLOR shapeColor = Apparence.GetRandomColorBut(apparence.Color);

				//						apparence.Set(apparence.Color, shapeColor, shape);
				//					}
				//					else
				//					{
				//						apparence.Shape = Data.Instance.GetNextUnlockedShape();
				//					}

				//					CollectionDialog.showPastille = apparence.Shape;
				//					ActionBar.showPastille = true;

				//					Victory victory = GameObject.Instantiate(Interface.Instance.victoryPrefab);
				//					child = new Rabbit(apparence, 0.0);
				//					victory.Add(child);
				//					victory.Init(1.0f);
				//					//if (apparence.Shape == CAT_SHAPE.FLOWER)
				//					//{
				//					//	victory.DoAfter(() =>
				//					//	{
				//					//		Farmer farmer = Farmer.window != null ? Farmer.window : Instantiate(Interface.Instance.farmer);
				//					//		farmer.Say(DIALOG.STANDARD, Local.Get("TUTO15_1"));
				//					//		farmer.Say(DIALOG.STANDARD, Local.Get("TUTO15_2"));
				//					//		farmer.Say(DIALOG.STANDARD, Local.Get("TUTO15_3"));
				//					//		farmer.Do(() =>
				//					//		{
				//					//			for (int i = 0; i < 3; i++)
				//					//			{
				//					//				Consumable consumable = new Consumable(Consumable.TYPE.LOLLIPOP);
				//					//				Data.Instance.Add(consumable);
				//					//				StatePlay.Instance.Pop(consumable);
				//					//			}
				//					//		});
				//					//	});
				//					//}
				//				}
				//				else if (Data.NbUnlocked > 15 && Random.value < 0.001f)
				//				{
				//					// Legendary!!!!

				//					Victory victory = GameObject.Instantiate(Interface.Instance.victoryPrefab);
				//					child = Rabbit.CreateNewLegendary(Data.Instance.GetRandomAvailableLockedLegendary(), 0.0);
				//					victory.Add(child);
				//					victory.Init(1.0f);
				//				}
				//				else
				//				{
				//					child = new Rabbit(apparence, 0.0);
				//				}
				//			}



				//			if (!forceDarkNight)
				//			{
				//				if (Random.value < 0.33f && (rabbit.HasSkin() || partenaire.rabbit.HasSkin()))
				//				{
				//					if (Random.value < 0.5f)
				//					{
				//						child.skin1 = rabbit.skin1;
				//						child.skin2 = rabbit.skin2;
				//						child.skin3 = rabbit.skin3;
				//					}
				//					else
				//					{
				//						child.skin1 = partenaire.rabbit.skin1;
				//						child.skin2 = partenaire.rabbit.skin2;
				//						child.skin3 = partenaire.rabbit.skin3;
				//					}
				//				}
				//				else if (Random.value < 0.01f)
				//				{
				//					child.skin1 = (SKIN_TYPE)Random.Range(0, (int)SKIN_TYPE.COUNT);
				//				}
				//			}

				//			CatModel childModel = Instantiate(statePlay.catPrefab, transform.parent);
				//			//childModel.Init(child, statePlay);
				//			//childModel.transform.localPosition = center + n * Vector3.left * 0.1f;
				//			//childModel.SetState(CAT_STATE.IDLE, 2.0f);
				//			//childModel.UpdateSize();
				//			//childModel.Refresh();

				//			//statePlay.catModels.Add(childModel);
				//			Data.Instance.AddRabbit(child);
				//		}

				//		// Save the new born
				//		Data.Save();

				//		ParticleSystem ps = Instantiate(Interface.Instance.psHeartExpose, transform.parent);
				//		ps.transform.localPosition = center;
				//		ps.transform.localScale = Vector3.one * 0.3f;
				//		Destroy(ps.gameObject, ps.main.duration);

				//		/*Debug.Log("Data.NbUnlocked=" + Data.NbUnlocked);
				//		switch (Data.NbUnlocked)
				//		{
				//			case 4:
				//			{
				//				Farmer farmer = Instantiate(Interface.Instance.farmer);
				//				farmer.Say(DIALOG.STANDARD, Local.Get("TUTO12_1"));
				//				farmer.Say(DIALOG.STANDARD, Local.Get("TUTO12_2"));
				//				break;
				//			}
				//			case 5:
				//			case 6:
				//			{
				//				Farmer farmer = Instantiate(Interface.Instance.farmer);
				//				farmer.Say(DIALOG.STANDARD, Local.Get("TUTO14_1"));
				//				farmer.Say(DIALOG.STANDARD, Local.Get("TUTO14_2"));
				//				farmer.Say(DIALOG.STANDARD, Local.Get("TUTO14_3"));
				//				farmer.Do(() =>
				//				{
				//					Tutorial.SetArrow(StatePlay.Instance.actionBar.catalogButton.transform);
				//				});
				//				break;
				//			}
				//		}*/
				//	}

				//	partenaire.SetState(CAT_STATE.WALKING, Random.Range(2.0f, 3.0f));

				//	SetState(CAT_STATE.WALKING, Random.Range(2.0f, 3.0f));
				//}

				break;
			}

			case CAT_STATE.HIDE:
			{
				if (alarm < Time.time)
				{
					model.gameObject.SetActive(true);
					SetState(CAT_STATE.IDLE);
				}

				break;
			}
		}
	}

	//---------------------------------------------------------------------------------------------

	private void Update1Sec()
	{
		if (State != CAT_STATE.DEAD)
		{
			UpdateSize();
		}

		//if (rabbit.apparence.Color == CAT_COLOR.DEATH && deathFace != ClockUI.IsNight() > 0.2)
		//{
		//	if (legendaryBack != null)
		//	{
		//		Destroy(legendaryBack);
		//		legendaryBack = null;
		//	}
		//	if (legendaryHead != null)
		//	{
		//		Destroy(legendaryHead);
		//		legendaryHead = null;
		//	}

		//	// Force Refresh to Change Angel/Death
		//	Refresh();
		//	StatePlay.PlayFX(Interface.Instance.psExplode, transform.position);

		//	previousState = CAT_STATE.INVALID;
		//	UpdateAnimation(State);
		//	return;
		//}

		//if (rabbit.apparence.Color == CAT_COLOR.EPIQUE_CLOWN && deathFace != (ClockUI.Hour == 0))
		//{
		//	if (legendaryBack != null)
		//	{
		//		Destroy(legendaryBack);
		//		legendaryBack = null;
		//	}
		//	if (legendaryHead != null)
		//	{
		//		Destroy(legendaryHead);
		//		legendaryHead = null;
		//	}

		//	// Force Refresh to Change Angel/Death
		//	Refresh();
		//	StatePlay.PlayFX(Interface.Instance.psExplode, transform.position);

		//	previousState = CAT_STATE.INVALID;
		//	UpdateAnimation(State);
		//	return;
		//}

		//if (/*deathFace && */State == CAT_STATE.IDLE)
		//{
		//	if (statePlay.FindRabbitModel(CAT_STATE.DEAD) == null)
		//	{
		//		RabbitModel destRabbit = statePlay.NearestRabbit(this);

		//		if (destRabbit != null)
		//		{
		//			if (Vector3.Distance(destRabbit.transform.position, transform.position) < 1.0f)
		//			{
		//				// Ok, on a atteint un lapin à manger
		//				destRabbit.Kill(true);
		//			}
		//			else
		//			{
		//				destination = destRabbit.transform.position;

		//				transform.LookAt(destination, Vector3.up);

		//				destination -= statePlay.transformRabbits.position;
		//				destination /= statePlay.transformRabbits.lossyScale.x;

		//				SetState(CAT_STATE.WALKING, Random.Range(3f, 10f));
		//			}
		//		}
		//	}
		//}

		//dirtyVal.x = Mathf.Min(Cat.Properties.dirty * 3.0f, 1.0f);
		//material.SetVector("_Dirty", dirtyVal);

		//if (Cat.Properties.life <= 0.0f || Cat.Properties.zombie)
		//{
		//	if (State != CAT_STATE.DEAD)
		//	{
		//		Kill(false);
		//	}
		//}
		//else
		//{
		//	RefreshBulle();
		//}

		//if (Cat.Properties.sick && sickPS == null)
		//{
		//	sickPS = Instantiate(Interface.Instance.psSickEffect, model.transform);
		//	sickPS.transform.localPosition = Vector3.zero;
		//}

		//if (washPS != null)
		//{
		//	if (Cat.Properties.dirty < 0.35f)
		//	{
		//		Cat.Properties.dirty += 0.02f;
		//	}
		//	else
		//	{
		//		Cat.Properties.dirty = 1.0f;
		//		Destroy(washPS);
		//		washPS = null;
		//	}
		//}
	}

	//---------------------------------------------------------------------------------------------

	public void Destroy(float delay = 0.0f)
	{
		if (partenaire != null)
		{
			partenaire.partenaire = null;
			partenaire.SetState(CAT_STATE.WALKING);
			partenaire = null;
		}

		//Data.Instance.Remove(Cat);

		Destroy(gameObject, delay);
		//statePlay.catModels.Remove(this);
	}

	//---------------------------------------------------------------------------------------------

	public void ForeTPose()
	{
		SkinnedMeshRenderer[] renderers = GetComponentsInChildren<SkinnedMeshRenderer>();

		Mesh[] bakedMeshes = new Mesh[renderers.Length];
		Bounds combinedBounds = new Bounds();

		// 1. Bake meshes et calcule le cube englobant global
		for (int i = 0; i < renderers.Length; i++)
		{
			SkinnedMeshRenderer skinnedMesh = renderers[i];
			Mesh bakedMesh = new Mesh();

			// Force le skinning à la pose par défaut (souvent la T-Pose)
			skinnedMesh.BakeMesh(bakedMesh);

			// Appliquer le mesh "baked" dans la pose par défaut si besoin :
			//skinnedMesh.GetComponent<MeshFilter>().mesh = bakedMesh;
		}
	}

	//---------------------------------------------------------------------------------------------

	bool CheckItem()
	{
		float distance = float.MaxValue;
		//ItemField nearestItemField = null;

		/*if (statePlay == null)
		{
			return false;
		}*/

		//if (rabbit.apparence.Color == CAT_COLOR.EPIQUE_FLY)
		//{
		//	// find shits
		//	if (Shit.Shits.Count > 0)
		//	{
		//		Shit shit = Shit.Shits[0];

		//		if (Vector3.Distance(transform.position, shit.transform.position) < 1.0f)
		//		{
		//			shit.Destroy();
		//			return true;
		//		}
		//	}
		//}
		//else if (rabbit.apparence.Color == CAT_COLOR.DEATH)
		//{
		//	// find grave
		//	RabbitModel grave = statePlay.FindDeadRabbitModel();

		//	if (grave != null)
		//	{
		//		if (Vector3.Distance(transform.position, grave.transform.position) < 1.0f)
		//		{
		//			transform.rotation = grave.transform.rotation;

		//			SetState(CAT_STATE.POSE, 2.0f);

		//			StatePlay.PlayFX(Interface.Instance.psHoly, transform.position + Vector3.up * 0.1f);
		//			grave.Resurect();
		//			return true;
		//		}
		//	}
		//}


		/*foreach (ItemField itemField in statePlay.itemFields)
		{
			if (itemField != null && itemField.GetItem().IsEat())
			{
				float newDistance = Vector3.SqrMagnitude(itemField.transform.position - transform.position);
				if (distance > newDistance)
				{
					distance = newDistance;
					nearestItemField = itemField;
				}
			}
		}*/

		/*if (nearestItemField == null || distance > StatePlay.DISTANCE_TAKE) // || (carrotModel.carrot. != Carrot.STATE.PLANTE && carrotModel.State != Carrot.STATE.POSE))
		{
			return false;
		}*/

		// Ok, let's eat!

		/*if (BeginApply(nearestItemField.GetItem()))
		{
			//statePlay.itemFields.Remove(nearestItemField);
			Destroy(nearestItemField.gameObject);
		}*/

		return true;
	}


}

//------------------------------------------------------------------------------------------------

#if UNITY_EDITOR
[CustomEditor(typeof(CatModel))]
public class CatModelEditorScript : Editor
{
	public override void OnInspectorGUI()
	{
		DrawDefaultInspector();

		GUILayout.Space(5);

		CatModel catModel = (CatModel)target;

		if (GUILayout.Button("Randomize"))
		{
			catModel.Cat.Apparence.Randomize();
			catModel.Apply();
		}

		if (GUILayout.Button("Randomize Linear"))
		{
			catModel.Cat.Apparence.Randomize(true);
			catModel.Apply();
		}

		if (GUILayout.Button("Apply"))
		{
			catModel.Apply();
		}

		/*if (GUILayout.Button("Bake"))
		{
			PositionTextureBaker positionTextureBaker = catModel.GetComponent<PositionTextureBaker>();

			positionTextureBaker.BakeFilledPositionMaps();
		}

		if (GUILayout.Button("GenerateT3D"))
		{
			PositionTextureBaker positionTextureBaker = catModel.GetComponent<PositionTextureBaker>();

			positionTextureBaker.GenerateT3D();
		}

		if (GUILayout.Button("T Pose"))
		{
			catModel.ForeTPose();
		}*/
	}
}
#endif
