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

public class ArcTeleport : MonoBehaviour
{
	private void Start()
	{
		this.m_nBackTrailCount = this.m_nTrailCount;
		this.m_trWarpCircle = base.transform.Find("WarpCircle");
		NDebug.Assert(this.m_trWarpCircle != null, "WarpCircleが見つかりません。");
		this.m_Circle_Size = this.m_trWarpCircle.localScale;
		this.m_trWarpCircle.gameObject.SetActive(false);
		this.m_Line_Obj = new GameObject();
		this.m_Line_Obj.name = "Teleport_Line";
		this.m_Line_Obj.AddComponent<SkinnedMeshRenderer>();
		SkinnedMeshRenderer component = this.m_Line_Obj.GetComponent<SkinnedMeshRenderer>();
		component.sharedMesh = new Mesh();
		component.sharedMesh.name = "Line_Mesh";
		this.Mesh_Setting(component);
		this.Bone_Setting(component);
		component.material = new Material(Resources.Load<Shader>(this.m_Line_Shader_Path));
		this.m_Line_Tex = Resources.Load<Texture>(this.m_Line_Texture_Path);
		this.m_Line_Tex_Gray = Resources.Load<Texture>(this.m_Gray_Texture_Path);
		component.material.SetTexture("_MainTex", this.m_Line_Tex);
		this.m_Line_Material = component.material;
		component.sharedMesh.RecalculateNormals();
		component.sharedMesh.RecalculateBounds();
		this.m_Line_Obj.transform.parent = base.transform;
		this.m_Line_Obj.SetActive(false);
	}

	private void Mesh_Setting(SkinnedMeshRenderer render)
	{
		Vector3[] array = new Vector3[this.m_nTrailCount * 4];
		Vector2[] array2 = new Vector2[this.m_nTrailCount * 4];
		List<int> list = new List<int>();
		int i;
		for (i = 0; i < this.m_nTrailCount; i++)
		{
			for (int j = 0; j < 4; j++)
			{
				array[i * 4 + j].x = Mathf.Cos(3.14159274f * (float)j) * this.m_Line_Width / 2f * (float)(1 - j / 2);
				array[i * 4 + j].y = Mathf.Cos(3.14159274f * (float)j) * this.m_Line_Width / 2f * (float)(j / 2);
				array[i * 4 + j].z = this.m_fLineLength * ((float)i / (float)(this.m_nTrailCount - 1)) - this.m_fLineLength / 2f;
				array2[i * 4 + j].x = (float)i / (float)(this.m_nTrailCount - 1);
				array2[i * 4 + j].y = (float)(j % 2);
			}
			if (i != 0)
			{
				int k;
				for (k = 0; k < 2; k++)
				{
					int[] source = new int[]
					{
						0,
						1,
						5,
						0,
						5,
						4
					};
					list.AddRange(from e in source
					select e + k * 2 + (i - 1) * 4);
				}
			}
		}
		render.sharedMesh.vertices = array;
		render.sharedMesh.uv = array2;
		render.sharedMesh.triangles = list.ToArray();
	}

	private void Bone_Setting(SkinnedMeshRenderer render)
	{
		this.m_Line_Bones = new Transform[this.m_nTrailCount];
		Matrix4x4[] array = new Matrix4x4[this.m_nTrailCount];
		BoneWeight[] array2 = new BoneWeight[this.m_nTrailCount * 4];
		for (int i = 0; i < this.m_nTrailCount; i++)
		{
			GameObject gameObject = new GameObject();
			this.m_Line_Bones[i] = gameObject.transform;
			this.m_Line_Bones[i].name = "Line_Bone";
			this.m_Line_Bones[i].parent = this.m_Line_Obj.transform;
			this.m_Line_Bones[i].position = Vector3.forward * (this.m_fLineLength * ((float)i / (float)(this.m_nBackTrailCount - 1)) - this.m_fLineLength / 2f);
			array[i] = this.m_Line_Bones[i].worldToLocalMatrix * this.m_Line_Obj.transform.localToWorldMatrix;
			for (int j = 0; j < 4; j++)
			{
				array2[i * 4 + j] = new BoneWeight
				{
					boneIndex0 = i,
					weight0 = 1f
				};
			}
		}
		render.bones = this.m_Line_Bones;
		render.sharedMesh.bindposes = array;
		render.sharedMesh.boneWeights = array2;
	}

	public void SetCallBackOnMove(ArcTeleport.dgOnMove f_dgMove)
	{
		this.m_dgOnMove = f_dgMove;
	}

	public void WarpSelecting()
	{
		this.m_bPush = true;
	}

	public bool IsWarpSelecting()
	{
		return this.m_bPush;
	}

	public void WarpDicide()
	{
		this.m_bPush = false;
	}

	public void WarpCancel()
	{
		this.m_bBackPush = (this.m_bPush = false);
	}

	private void OnEnable()
	{
		this.WarpCancel();
	}

	private void OnDisable()
	{
		this.WarpCancel();
	}

	private IEnumerator Circle_Animation()
	{
		this.m_trWarpCircle.localScale = Vector3.forward * this.m_Circle_Size.z;
		float timer = 0f;
		for (;;)
		{
			timer += Time.deltaTime;
			if (timer >= this.m_Anime_Time)
			{
				break;
			}
			this.m_trWarpCircle.localScale = Vector3.forward * this.m_Circle_Size.z + new Vector3(this.m_Circle_Size.x, this.m_Circle_Size.y, 0f) * timer / this.m_Anime_Time;
			yield return null;
		}
		yield break;
		yield break;
	}

	private Vector3 Circle_Angle()
	{
		Vector3 result = Vector3.zero;
		Vector3 toDirection = this.m_trWarpCircle.position - GameMain.Instance.MainCamera.GetPos();
		toDirection.y = 0f;
		toDirection.Normalize();
		result = Quaternion.FromToRotation(Vector3.forward, toDirection).eulerAngles;
		result.x = (result.z = 0f);
		return result;
	}

	private IEnumerator Line_Flash()
	{
		float timer = 0f;
		Color line_color = Color.white;
		string tex_name = this.m_Line_Tex.name;
		for (;;)
		{
			timer += Time.deltaTime;
			float time_rate = Mathf.Abs(Mathf.Cos(0.0174532924f * (180f * (timer / this.m_Flash_Time))));
			if (!this.m_trWarpCircle.gameObject.activeSelf)
			{
				if (tex_name != this.m_Line_Tex_Gray.name)
				{
					this.m_Line_Material.SetTexture("_MainTex", this.m_Line_Tex_Gray);
					tex_name = this.m_Line_Tex_Gray.name;
				}
			}
			else if (tex_name != this.m_Line_Tex.name)
			{
				this.m_Line_Material.SetTexture("_MainTex", this.m_Line_Tex);
				tex_name = this.m_Line_Tex.name;
			}
			line_color.a = Mathf.Lerp(1f, this.m_Min_Alpha, time_rate);
			this.m_Line_Material.SetColor("_Color", line_color);
			yield return null;
		}
		yield break;
	}

	private void Update()
	{
		bool flag = false;
		if (GameMain.Instance.MainCamera.IsFadeProc())
		{
			this.m_bBackHit = (this.m_bBackPush = (this.m_bPush = false));
			base.StopCoroutine("Line_Flash");
			this.m_Line_Obj.SetActive(false);
			return;
		}
		if (this.m_bPush)
		{
			if (this.m_nBackTrailCount != this.m_nTrailCount)
			{
				this.m_nBackTrailCount = this.m_nTrailCount;
			}
			if (!this.m_Line_Obj.activeSelf)
			{
				base.StartCoroutine("Line_Flash");
			}
			this.m_Line_Obj.SetActive(true);
			Vector3 normalized = this.m_trParent.forward.normalized;
			Debug.DrawLine(this.m_trParent.position, this.m_trParent.position + normalized * 1f, Color.green);
			Vector3 vector = new Vector3(normalized.x, 0f, normalized.z);
			Vector3 normalized2 = vector.normalized;
			Debug.DrawLine(this.m_trParent.position, this.m_trParent.position + normalized2 * 1f, Color.cyan);
			float num = Vector3.Angle(normalized, normalized2);
			if (normalized.y < normalized2.y)
			{
				num *= -1f;
			}
			Vector3 zero = Vector3.zero;
			float num2 = Vector3.Angle(Vector3.forward, normalized2);
			if (normalized2.x < 0f)
			{
				num2 *= -1f;
			}
			Quaternion rotation = Quaternion.Euler(0f, num2, 0f);
			Vector3 zero2 = Vector3.zero;
			float num3 = this.m_Defo_Display_Length;
			for (float num4 = this.m_fLineSplitLength; num4 < this.m_fLineLength; num4 += this.m_fLineSplitLength)
			{
				float num5 = this.m_fVelocity * Mathf.Cos(num * 0.0174532924f) * num4;
				float num6 = this.m_fVelocity * Mathf.Sin(num * 0.0174532924f) * num4 - 0.5f * this.m_fGravity * (num4 * num4);
				Vector3 vector2 = this.m_trParent.position + rotation * zero;
				Vector3 vector3 = this.m_trParent.position + rotation * new Vector3(0f, num6, num5);
				Debug.DrawLine(vector2, vector3);
				zero.Set(0f, num6, num5);
				if (!flag)
				{
					this.m_ray.origin = vector2;
					this.m_ray.direction = vector3 - vector2;
					if (Physics.Raycast(this.m_ray, out this.m_hit, Vector3.Distance(vector2, vector3), 512))
					{
						flag = true;
						this.m_vHitPos = this.m_hit.point;
						this.m_trWarpCircle.transform.rotation = Quaternion.Euler(this.m_Fixed_Angle);
						if (!this.m_trWarpCircle.gameObject.activeSelf)
						{
							base.StartCoroutine("Circle_Animation");
						}
						this.m_trWarpCircle.gameObject.SetActive(true);
						this.m_trWarpCircle.position = this.m_vHitPos;
						num3 = num4;
					}
				}
			}
			if (this.m_nTrailCount > 0)
			{
				float num7 = num3 / (float)this.m_nTrailCount;
				if (num7 <= 0f)
				{
					num7 = 1f;
				}
				zero = Vector3.zero;
				float num8 = num7;
				for (int i = 0; i < this.m_nTrailCount; i++)
				{
					num8 += num7;
					float num9 = this.m_fVelocity * Mathf.Cos(num * 0.0174532924f) * num8;
					float num10 = this.m_fVelocity * Mathf.Sin(num * 0.0174532924f) * num8 - 0.5f * this.m_fGravity * (num8 * num8);
					Vector3 vector4 = this.m_trParent.position + rotation * zero;
					Vector3 end = this.m_trParent.position + rotation * new Vector3(0f, num10, num9);
					Debug.DrawLine(vector4, end, Color.blue);
					zero.Set(0f, num10, num9);
					this.m_Line_Bones[i].position = vector4;
				}
			}
		}
		else
		{
			if (this.m_bBackPush && this.m_bBackHit && this.m_dgOnMove != null)
			{
				this.m_dgOnMove(this.m_vHitPos, this.Circle_Angle());
			}
			base.StopCoroutine("Line_Flash");
			this.m_Line_Obj.SetActive(false);
		}
		if (!flag)
		{
			this.m_trWarpCircle.localScale = this.m_Circle_Size;
			this.m_trWarpCircle.gameObject.SetActive(false);
			base.StopCoroutine("Circle_Animation");
		}
		this.m_bBackHit = flag;
		this.m_bBackPush = this.m_bPush;
	}

	public bool m_bPush;

	private bool m_bBackPush;

	public Transform m_trParent;

	public float m_fGravity = 0.98f;

	public float m_fVelocity = 100f;

	public float m_fLineLength = 10f;

	public float m_fLineSplitLength = 0.1f;

	public int m_nTrailCount = 10;

	private int m_nBackTrailCount;

	public ArcTeleport.dgOnMove m_dgOnMove;

	private Vector3 m_vHitPos;

	private Ray m_ray = default(Ray);

	private RaycastHit m_hit;

	private bool m_bBackHit;

	private Transform m_trWarpCircle;

	[SerializeField]
	[Header("ワープサークルの固定角度")]
	private Vector3 m_Fixed_Angle = Vector3.right * -90f;

	[SerializeField]
	[Header("サークルのアニメーション時間")]
	private float m_Anime_Time = 0.75f;

	private Vector3 m_Circle_Size;

	private string m_Line_Shader_Path = "Shaders/Telepot_Line";

	private GameObject m_Line_Obj;

	private Transform[] m_Line_Bones;

	private string m_Line_Texture_Path = "SteamVR/ArcTeleport";

	private string m_Gray_Texture_Path = "SteamVR/ArcTeleport_Gray";

	private Texture m_Line_Tex;

	private Texture m_Line_Tex_Gray;

	[SerializeField]
	[Header("ラインの横幅")]
	private float m_Line_Width = 0.1f;

	[SerializeField]
	[Header("表示するラインの長さの基準値")]
	private float m_Defo_Display_Length = 5.5f;

	[SerializeField]
	[Header("点滅時間")]
	private float m_Flash_Time = 1.5f;

	[SerializeField]
	[Range(0f, 1f)]
	private float m_Min_Alpha = 0.4f;

	private Material m_Line_Material;

	public delegate void dgOnMove(Vector3 f_vPosWorld, Vector3 f_vRotWorld);
}
