using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public class Dealer : Hand
{
	public static Dealer Instance { get; private set; }

	public bool NeedCardMove
	{
		get
		{
			return !this.m_IsCardMove && this.m_TableCards.Count >= 3;
		}
	}

	public Vector3 LastCardPos
	{
		get
		{
			if (this.m_TableCards.Count == 4)
			{
				return base.transform.position;
			}
			int num = this.m_TableCards.Count - 1;
			return this.m_TableCards[num - 1].transform.position + this.m_CardOffset;
		}
	}

	private void Awake()
	{
		Dealer.Instance = this;
	}

	private void OnDestroy()
	{
		foreach (GameObject gameObject in this.m_TableCards)
		{
			if (gameObject)
			{
				UnityEngine.Object.DestroyImmediate(gameObject);
			}
		}
	}

	public void CheckSurrender()
	{
		this.m_IsForceWin = false;
	}

	public override void ResetHand()
	{
		base.ResetHand();
		this.m_IsForceWin = false;
		this.m_IsCardMove = false;
	}

	public void CardMove()
	{
		this.m_IsCardMove = true;
		base.StartCoroutine(this.CardMoveCoroutine());
	}

	private IEnumerator CardMoveCoroutine()
	{
		yield return null;
		Func<Vector3, Vector3> maid_local = (Vector3 pos) => BjMotionControl.Instance.TargetMaid.transform.InverseTransformPoint(pos);
		Vector3 last_hand = maid_local(BjMotionControl.Instance.RightHandPos());
		bool move_start = false;
		int lap_count = 1;
		List<Transform> move_card = new List<Transform>();
		List<Vector3> orijin_pos = new List<Vector3>();
		Transform target = this.m_TableCards[this.m_TableCards.Count - lap_count].transform;
		Vector3 next_pos = target.position;
		float length = 0f;
		for (;;)
		{
			Vector3 now_hand = maid_local(BjMotionControl.Instance.RightHandPos());
			Vector3 card_local = (move_card.Count == 0) ? Vector3.zero : maid_local(move_card.Last<Transform>().position);
			if (!move_start)
			{
				if (last_hand.x < now_hand.x)
				{
					move_start = true;
					lap_count++;
					move_card.Add(target);
					orijin_pos.Add(target.position);
					target.SetParent(BjMotionControl.Instance.RightHand, true);
					target = this.m_TableCards[this.m_TableCards.Count - lap_count].transform;
					next_pos = target.position + base.transform.TransformDirection(Vector3.right) * this.m_RecetCardX;
					length = maid_local(next_pos).x - maid_local(move_card.Last<Transform>().position).x;
					BlackjackGame.Instance.CardSe.Play();
				}
			}
			else
			{
				for (int i = 0; i < move_card.Count; i++)
				{
					move_card[i].eulerAngles = CardDeck.Instance.FlipupAngle;
				}
				if (lap_count <= this.m_TableCards.Count)
				{
					float num = 1f - Mathf.Clamp01(Mathf.Max(maid_local(next_pos).x - card_local.x, 0f) / length);
					for (int j = 0; j < move_card.Count; j++)
					{
						Vector3 position = move_card[j].position;
						position.x = orijin_pos[j].x;
						position.y = Mathf.Lerp(orijin_pos[j].y, orijin_pos[j].y + 0.001f, num);
						position.z = Mathf.Min(next_pos.z, position.z);
						move_card[j].position = position;
					}
					if (num == 1f)
					{
						lap_count++;
						for (int k = 0; k < orijin_pos.Count; k++)
						{
							orijin_pos[k] = move_card[k].position;
						}
						move_card.Add(target);
						orijin_pos.Add(target.position);
						target.SetParent(BjMotionControl.Instance.RightHand, true);
						if (lap_count <= this.m_TableCards.Count)
						{
							target = this.m_TableCards[this.m_TableCards.Count - lap_count].transform;
							next_pos = target.position + base.transform.TransformDirection(Vector3.right) * this.m_RecetCardX;
							length = maid_local(next_pos).x - card_local.x;
							BlackjackGame.Instance.CardSe.Play();
						}
					}
				}
				else
				{
					for (int l = 0; l < move_card.Count; l++)
					{
						Vector3 position2 = move_card[l].position;
						position2.x = orijin_pos[l].x;
						position2.y = orijin_pos[l].y;
						if (l + 1 < move_card.Count)
						{
							position2.z = Mathf.Min(position2.z, move_card[l + 1].position.z - this.m_RecetCardX);
						}
						move_card[l].position = position2;
					}
					if (now_hand.x > maid_local(base.transform.TransformPoint(Vector3.left * this.m_MaxMoveX)).x)
					{
						break;
					}
				}
			}
			last_hand = now_hand;
			yield return null;
		}
		base.ResetNextPosition();
		foreach (Transform transform in move_card)
		{
			transform.SetParent(base.transform, true);
		}
		yield break;
		yield break;
	}

	public bool IsEnded()
	{
		return base.CurrentScore > 16 || this.m_IsForceWin || this.m_TableCards.Count >= 7;
	}

	protected override Card.CardState GetCardState()
	{
		if (this.m_TableCards.Count == 0 || this.m_TableCards.Count > 1)
		{
			return Card.CardState.FlipUp;
		}
		return Card.CardState.FlipDown;
	}

	public bool HasFacedownCard()
	{
		return this.m_TableCards.Count == 2 && this.m_HandCardData[this.m_TableCards[1]].CurrentState == Card.CardState.FlipDown;
	}

	public GameObject GetFacedownCard()
	{
		GameObject result = null;
		if (this.HasFacedownCard())
		{
			result = this.m_TableCards[1];
		}
		return result;
	}

	public bool IsNatural21()
	{
		bool flag = this.m_HandCardData[this.m_TableCards[0]].CardData.GetValue() + this.m_HandCardData[this.m_TableCards[1]].CardData.GetValue() == 11;
		bool flag2 = this.m_HandCardData[this.m_TableCards[0]].CardData.CardRank == CardData.Rank.Ace || this.m_HandCardData[this.m_TableCards[1]].CardData.CardRank == CardData.Rank.Ace;
		return this.m_TableCards.Count == 2 && flag && flag2;
	}

	public bool MayHaveNatural21()
	{
		return this.HasFacedownCard() && this.m_HandCardData[this.m_TableCards[0]].CardData.CardRank == CardData.Rank.Ace;
	}

	public bool HasBlackjack()
	{
		Card card = this.m_HandCardData[this.GetFacedownCard()];
		return card.CardData.GetValue() == 10;
	}

	public void SetCardOffset()
	{
		this.m_CardOffset = this.m_TableCards[1].transform.position - this.m_TableCards[0].transform.position;
	}

	private const int m_CardMax = 7;

	private const float m_Cardlap = 0.001f;

	public const int CardRecetNum = 3;

	public const int SetOffsetNum = 5;

	private bool m_IsForceWin;

	private bool m_IsCardMove;

	[SerializeField]
	private float m_MaxMoveX = 0.5f;

	[SerializeField]
	private float m_RecetCardX = 0.02f;
}
