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

public class KasaiUtility
{
	public static IEnumerator FadeCoroutine(CanvasGroup canvas, bool is_fadeout, float fade_time = 0.5f, Action end_action = null, bool auto_setting = true, bool liner_valiable = true)
	{
		float timer = 0f;
		if (auto_setting)
		{
			if (is_fadeout)
			{
				if (!canvas.gameObject.activeSelf)
				{
					yield break;
				}
				canvas.interactable = false;
			}
			else
			{
				canvas.gameObject.SetActive(true);
			}
		}
		for (;;)
		{
			timer += Time.deltaTime;
			if (liner_valiable)
			{
				canvas.alpha = ((!is_fadeout) ? Mathf.Clamp01(timer / fade_time) : (1f - Mathf.Clamp01(timer / fade_time)));
			}
			else
			{
				canvas.alpha = KasaiUtility.SinRate01(timer, fade_time, is_fadeout, false);
			}
			if (timer > fade_time)
			{
				break;
			}
			yield return null;
		}
		if (end_action != null)
		{
			end_action();
		}
		if (auto_setting)
		{
			if (!is_fadeout)
			{
				canvas.interactable = true;
			}
			else
			{
				canvas.gameObject.SetActive(false);
			}
		}
		yield break;
		yield break;
	}

	public static IEnumerator FadeCoroutine(UIPanel ui_panel, bool is_fadeout, float fade_time = 0.5f, Action end_action = null, bool auto_setting = true, bool liner_valiable = true)
	{
		float timer = 0f;
		if (auto_setting)
		{
			if (is_fadeout)
			{
				if (!ui_panel.gameObject.activeSelf)
				{
					yield break;
				}
			}
			else
			{
				ui_panel.gameObject.SetActive(true);
			}
		}
		for (;;)
		{
			timer += Time.deltaTime;
			if (liner_valiable)
			{
				ui_panel.alpha = ((!is_fadeout) ? Mathf.Clamp01(timer / fade_time) : (1f - Mathf.Clamp01(timer / fade_time)));
			}
			else
			{
				ui_panel.alpha = KasaiUtility.SinRate01(timer, fade_time, is_fadeout, false);
			}
			if (timer > fade_time)
			{
				break;
			}
			yield return null;
		}
		if (end_action != null)
		{
			end_action();
		}
		if (auto_setting && is_fadeout)
		{
			ui_panel.gameObject.SetActive(false);
		}
		yield break;
		yield break;
	}

	public static IEnumerator TimeCroutine(float time_rimmit, Action<float> update_call, Action end_call = null)
	{
		float timer = 0f;
		for (;;)
		{
			timer += Time.deltaTime;
			if (update_call != null)
			{
				update_call(timer);
			}
			if (timer > time_rimmit)
			{
				break;
			}
			yield return null;
		}
		if (end_call != null)
		{
			end_call();
		}
		yield break;
		yield break;
	}

	public static IEnumerator CharaLoadWait(Action end_call)
	{
		while (GameMain.Instance.CharacterMgr.IsBusy())
		{
			yield return null;
		}
		yield return null;
		if (end_call != null)
		{
			end_call();
		}
		yield break;
	}

	public static float SinRate01(float current_time, float total_time, bool is_reverse = false, bool allow_timeover = false)
	{
		float rate = (!allow_timeover) ? Mathf.Clamp01(current_time / total_time) : (current_time / total_time);
		return KasaiUtility.SinRate01(rate, is_reverse);
	}

	public static float SinRate01(float rate, bool is_reverse = false)
	{
		if (!is_reverse)
		{
			return Mathf.Sin(rate * 90f * 0.0174532924f);
		}
		return 1f - Mathf.Sin(rate * 90f * 0.0174532924f);
	}

	public static float CosRate11(float current_time, float total_time, bool is_abs = false, bool is_reverse = false, bool allow_timeover = false)
	{
		float num = (!allow_timeover) ? Mathf.Clamp01(current_time / total_time) : (current_time / total_time);
		if (is_abs)
		{
			if (is_reverse)
			{
				return 1f - Mathf.Abs(Mathf.Cos(num * 180f * 0.0174532924f));
			}
			return Mathf.Abs(Mathf.Cos(num * 180f * 0.0174532924f));
		}
		else
		{
			if (is_reverse)
			{
				return -Mathf.Cos(num * 180f * 0.0174532924f);
			}
			return Mathf.Cos(num * 180f * 0.0174532924f);
		}
	}

	public static float DistanceIgnoreY(Vector3 a, Vector3 b)
	{
		a.y = (b.y = 0f);
		return Vector3.Distance(a, b);
	}

	public static Vector2 AngleDirection(float angle)
	{
		Vector2 zero = Vector2.zero;
		zero.x = Mathf.Cos(angle * 0.0174532924f);
		zero.y = Mathf.Sin(angle * 0.0174532924f);
		return zero;
	}

	public static void CsvRead(string file_name, Action<CsvParser, int, int> read_callback, int first_x = 0, int first_y = 1, Action not_exist_call = null)
	{
		if (file_name.IndexOf(".nei") < 0)
		{
			file_name += ".nei";
		}
		if (!GameUty.FileSystem.IsExistentFile(file_name))
		{
			if (not_exist_call != null)
			{
				not_exist_call();
				return;
			}
			NDebug.Assert("表がありません。" + file_name, false);
		}
		using (AFileBase afileBase = GameUty.FileSystem.FileOpen(file_name))
		{
			using (CsvParser csvParser = new CsvParser())
			{
				bool condition = csvParser.Open(afileBase);
				NDebug.Assert(condition, file_name + "\nopen failed.");
				for (int i = first_y; i < csvParser.max_cell_y; i++)
				{
					if (csvParser.IsCellToExistData(0, i))
					{
						for (int j = first_x; j < csvParser.max_cell_x; j++)
						{
							if (csvParser.IsCellToExistData(j, i))
							{
								if (read_callback != null)
								{
									read_callback(csvParser, j, i);
								}
							}
						}
					}
				}
			}
		}
	}

	public static void CsvReadY(string file_name, Action<CsvParser, int> read_callback, int first_y = 1, Action not_exist_call = null)
	{
		if (file_name.IndexOf(".nei") < 0)
		{
			file_name += ".nei";
		}
		if (!GameUty.FileSystem.IsExistentFile(file_name))
		{
			if (not_exist_call != null)
			{
				not_exist_call();
				return;
			}
			NDebug.Assert("表がありません。" + file_name, false);
		}
		using (AFileBase afileBase = GameUty.FileSystem.FileOpen(file_name))
		{
			using (CsvParser csvParser = new CsvParser())
			{
				bool condition = csvParser.Open(afileBase);
				NDebug.Assert(condition, file_name + "\nopen failed.");
				for (int i = first_y; i < csvParser.max_cell_y; i++)
				{
					if (csvParser.IsCellToExistData(0, i))
					{
						if (read_callback != null)
						{
							read_callback(csvParser, i);
						}
					}
				}
			}
		}
	}

	public static void CsvReadAll(string file_name, Action<CsvParser> read_callback, Action not_exist_call = null)
	{
		if (file_name.IndexOf(".nei") < 0)
		{
			file_name += ".nei";
		}
		if (!GameUty.FileSystem.IsExistentFile(file_name))
		{
			if (not_exist_call != null)
			{
				not_exist_call();
				return;
			}
			NDebug.Assert("表がありません。" + file_name, false);
		}
		using (AFileBase afileBase = GameUty.FileSystem.FileOpen(file_name))
		{
			using (CsvParser csvParser = new CsvParser())
			{
				bool condition = csvParser.Open(afileBase);
				NDebug.Assert(condition, file_name + "\nopen failed.");
				if (read_callback != null)
				{
					read_callback(csvParser);
				}
			}
		}
	}

	public static void DrawAxis(Vector3 pos, Quaternion rot, Color x_color, Color y_color, Color z_color, float line_length = 0.0625f)
	{
		Debug.DrawLine(pos, pos + rot * Vector3.right * line_length, x_color);
		Debug.DrawLine(pos, pos + rot * Vector3.up * line_length, y_color);
		Debug.DrawLine(pos, pos + rot * Vector3.forward * line_length, z_color);
	}

	public static void DrawAxis(Vector3 pos, Quaternion rot, float line_length = 0.0625f)
	{
		KasaiUtility.DrawAxis(pos, rot, Color.red, Color.green, Color.blue, line_length);
	}

	public static void DrawObjAxis(Transform obj_trans, Color x_color, Color y_color, Color z_color, float line_length = 0.0625f)
	{
		KasaiUtility.DrawAxis(obj_trans.position, obj_trans.rotation, x_color, y_color, z_color, line_length);
	}

	public static void DrawObjAxis(Transform obj_trans, float ray_length = 0.0625f)
	{
		KasaiUtility.DrawObjAxis(obj_trans, Color.red, Color.green, Color.blue, ray_length);
	}

	public static Vector3 Bezier(Vector3 p0, Vector3 p1, Vector3 c, float t)
	{
		Vector3 a = Vector3.Lerp(p0, c, t);
		Vector3 b = Vector3.Lerp(c, p1, t);
		return Vector3.Lerp(a, b, t);
	}

	public static Vector3 Hermite(Vector3 p0, Vector3 p1, Vector3 v0, Vector3 v1, float t)
	{
		Vector3 a = 2f * p0 + -2f * p1 + v0 + v1;
		Vector3 a2 = -3f * p0 + 3f * p1 + -2f * v0 - v1;
		float num = t * t;
		float d = num * t;
		return a * d + a2 * num + v0 * t + p0;
	}

	public static Vector3 Catmul(List<Vector3> point_list, float t)
	{
		if (point_list.Count == 0)
		{
			return Vector3.zero;
		}
		if (point_list.Count == 1)
		{
			return point_list[0];
		}
		float num = (float)(point_list.Count - 1) * t;
		int num2 = Mathf.FloorToInt(num);
		float t2 = num - (float)num2;
		if (num2 >= point_list.Count - 1)
		{
			num2 = point_list.Count - 2;
			t2 = 1f;
		}
		Vector3 p = point_list[num2];
		Vector3 p2 = point_list[num2 + 1];
		Vector3 v = Vector3.zero;
		if (num2 > 0)
		{
			v = 0.5f * (point_list[num2 + 1] - point_list[num2 - 1]);
		}
		else
		{
			v = point_list[num2 + 1] - point_list[num2];
		}
		Vector3 v2 = Vector3.zero;
		if (num2 < point_list.Count - 2)
		{
			v2 = 0.5f * (point_list[num2 + 2] - point_list[num2]);
		}
		else
		{
			v2 = point_list[num2 + 1] - point_list[num2];
		}
		return KasaiUtility.Hermite(p, p2, v, v2, t2);
	}

	public static Vector3 Vec3Multiply(Vector3 a, Vector3 b)
	{
		Vector3 zero = Vector3.zero;
		zero.x = a.x * b.x;
		zero.y = a.y * b.y;
		zero.z = a.z * b.z;
		return zero;
	}

	public static Vector3 Vec3Parse(string str, char split_ch = ',')
	{
		string[] array = str.Split(new char[]
		{
			split_ch
		});
		Vector3 zero = Vector3.zero;
		zero.x = float.Parse(array[0]);
		zero.y = float.Parse(array[1]);
		zero.z = float.Parse(array[2]);
		return zero;
	}

	public static Vector3 AngleRimmit360(Vector3 orijin_angle)
	{
		Func<float, float> func = delegate(float angle)
		{
			if (Mathf.Abs(angle) > 360f)
			{
				if (angle < 0f)
				{
					angle += 360f;
				}
				else
				{
					angle -= 360f;
				}
			}
			return angle;
		};
		orijin_angle.x = func(orijin_angle.x);
		orijin_angle.y = func(orijin_angle.y);
		orijin_angle.z = func(orijin_angle.z);
		return orijin_angle;
	}
}
