using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using UnityEngine;

namespace RenderHeads.Media.AVProVideo
{
	public static class Helper
	{
		public static string GetName(Platform platform)
		{
			return platform.ToString();
		}

		public static string GetErrorMessage(ErrorCode code)
		{
			string text = string.Empty;
			if (code != ErrorCode.None)
			{
				if (code != ErrorCode.LoadFailed)
				{
					if (code == ErrorCode.DecodeFailed)
					{
						text = "Decode failed.  Possible codec not supported, video resolution too high or insufficient system resources.";
					}
				}
				else
				{
					text = "Loading failed.  Codec not supported or video resolution too high or insufficient system resources.";
					if (SystemInfo.operatingSystem.StartsWith("Windows XP") || SystemInfo.operatingSystem.StartsWith("Windows Vista"))
					{
						text += " NOTE: Windows XP and Vista don't have native support for H.264 codec.  Consider using an older codec such as DivX or installing 3rd party codecs such as LAV Filters.";
					}
				}
			}
			else
			{
				text = "No Error";
			}
			return text;
		}

		public static string[] GetPlatformNames()
		{
			return new string[]
			{
				Helper.GetName(Platform.Windows),
				Helper.GetName(Platform.MacOSX),
				Helper.GetName(Platform.iOS),
				Helper.GetName(Platform.tvOS),
				Helper.GetName(Platform.Android),
				Helper.GetName(Platform.WindowsPhone),
				Helper.GetName(Platform.WindowsUWP),
				Helper.GetName(Platform.WebGL),
				Helper.GetName(Platform.PS4)
			};
		}

		public static void LogInfo(string message, UnityEngine.Object context = null)
		{
			if (context == null)
			{
				Debug.Log("[AVProVideo] " + message);
			}
			else
			{
				Debug.Log("[AVProVideo] " + message, context);
			}
		}

		public static string GetTimeString(float totalSeconds, bool showMilliseconds = false)
		{
			int num = Mathf.FloorToInt(totalSeconds / 3600f);
			float num2 = (float)num * 60f * 60f;
			int num3 = Mathf.FloorToInt((totalSeconds - num2) / 60f);
			num2 += (float)num3 * 60f;
			int num4 = Mathf.FloorToInt(totalSeconds - num2);
			string result;
			if (num <= 0)
			{
				if (showMilliseconds)
				{
					int num5 = (int)((totalSeconds - Mathf.Floor(totalSeconds)) * 1000f);
					result = string.Format("{0:00}:{1:00}:{2:000}", num3, num4, num5);
				}
				else
				{
					result = string.Format("{0:00}:{1:00}", num3, num4);
				}
			}
			else if (showMilliseconds)
			{
				int num6 = (int)((totalSeconds - Mathf.Floor(totalSeconds)) * 1000f);
				result = string.Format("{2}:{0:00}:{1:00}:{3:000}", new object[]
				{
					num3,
					num4,
					num,
					num6
				});
			}
			else
			{
				result = string.Format("{2}:{0:00}:{1:00}", num3, num4, num);
			}
			return result;
		}

		public static Orientation GetOrientation(float[] t)
		{
			Orientation result = Orientation.Landscape;
			if (t[0] == 0f && t[1] == 1f && t[2] == -1f && t[3] == 0f)
			{
				result = Orientation.Portrait;
			}
			else if (t[0] == 0f && t[1] == -1f && t[2] == 1f && t[3] == 0f)
			{
				result = Orientation.PortraitFlipped;
			}
			else if (t[0] == 1f && t[1] == 0f && t[2] == 0f && t[3] == 1f)
			{
				result = Orientation.Landscape;
			}
			else if (t[0] == -1f && t[1] == 0f && t[2] == 0f && t[3] == -1f)
			{
				result = Orientation.LandscapeFlipped;
			}
			return result;
		}

		public static Matrix4x4 GetMatrixForOrientation(Orientation ori)
		{
			Matrix4x4 matrix4x = Matrix4x4.TRS(new Vector3(0f, 1f, 0f), Quaternion.Euler(0f, 0f, -90f), Vector3.one);
			Matrix4x4 matrix4x2 = Matrix4x4.TRS(new Vector3(1f, 0f, 0f), Quaternion.Euler(0f, 0f, 90f), Vector3.one);
			Matrix4x4 matrix4x3 = Matrix4x4.TRS(new Vector3(1f, 1f, 0f), Quaternion.identity, new Vector3(-1f, -1f, 1f));
			Matrix4x4 result = Matrix4x4.identity;
			switch (ori)
			{
			case Orientation.LandscapeFlipped:
				result = matrix4x3;
				break;
			case Orientation.Portrait:
				result = matrix4x;
				break;
			case Orientation.PortraitFlipped:
				result = matrix4x2;
				break;
			}
			return result;
		}

		public static void SetupStereoMaterial(Material material, StereoPacking packing, bool displayDebugTinting)
		{
			material.DisableKeyword("STEREO_CUSTOM_UV");
			material.DisableKeyword("STEREO_TOP_BOTTOM");
			material.DisableKeyword("STEREO_LEFT_RIGHT");
			material.DisableKeyword("MONOSCOPIC");
			switch (packing)
			{
			case StereoPacking.TopBottom:
				material.EnableKeyword("STEREO_TOP_BOTTOM");
				break;
			case StereoPacking.LeftRight:
				material.EnableKeyword("STEREO_LEFT_RIGHT");
				break;
			case StereoPacking.CustomUV:
				material.EnableKeyword("STEREO_CUSTOM_UV");
				break;
			}
			if (displayDebugTinting)
			{
				material.EnableKeyword("STEREO_DEBUG");
			}
			else
			{
				material.DisableKeyword("STEREO_DEBUG");
			}
		}

		public static void SetupAlphaPackedMaterial(Material material, AlphaPacking packing)
		{
			material.DisableKeyword("ALPHAPACK_TOP_BOTTOM");
			material.DisableKeyword("ALPHAPACK_LEFT_RIGHT");
			material.DisableKeyword("ALPHAPACK_NONE");
			if (packing != AlphaPacking.None)
			{
				if (packing != AlphaPacking.TopBottom)
				{
					if (packing == AlphaPacking.LeftRight)
					{
						material.EnableKeyword("ALPHAPACK_LEFT_RIGHT");
					}
				}
				else
				{
					material.EnableKeyword("ALPHAPACK_TOP_BOTTOM");
				}
			}
		}

		public static void SetupGammaMaterial(Material material, bool playerSupportsLinear)
		{
			if (QualitySettings.activeColorSpace == ColorSpace.Linear && !playerSupportsLinear)
			{
				material.EnableKeyword("APPLY_GAMMA");
			}
			else
			{
				material.DisableKeyword("APPLY_GAMMA");
			}
		}

		public static int ConvertTimeSecondsToFrame(float seconds, float frameRate)
		{
			return Mathf.FloorToInt(frameRate * seconds);
		}

		public static float ConvertFrameToTimeSeconds(int frame, float frameRate)
		{
			float num = 1f / frameRate;
			return (float)frame * num + num * 0.5f;
		}

		public static void DrawTexture(Rect screenRect, Texture texture, ScaleMode scaleMode, AlphaPacking alphaPacking, Material material)
		{
			if (Event.current.type == EventType.Repaint)
			{
				float num = (float)texture.width;
				float num2 = (float)texture.height;
				if (alphaPacking != AlphaPacking.LeftRight)
				{
					if (alphaPacking == AlphaPacking.TopBottom)
					{
						num2 *= 0.5f;
					}
				}
				else
				{
					num *= 0.5f;
				}
				float num3 = num / num2;
				Rect sourceRect = new Rect(0f, 0f, 1f, 1f);
				if (scaleMode != ScaleMode.ScaleAndCrop)
				{
					if (scaleMode != ScaleMode.ScaleToFit)
					{
						if (scaleMode != ScaleMode.StretchToFill)
						{
						}
					}
					else
					{
						float num4 = screenRect.width / screenRect.height;
						if (num4 > num3)
						{
							float num5 = num3 / num4;
							screenRect = new Rect(screenRect.xMin + screenRect.width * (1f - num5) * 0.5f, screenRect.yMin, num5 * screenRect.width, screenRect.height);
						}
						else
						{
							float num6 = num4 / num3;
							screenRect = new Rect(screenRect.xMin, screenRect.yMin + screenRect.height * (1f - num6) * 0.5f, screenRect.width, num6 * screenRect.height);
						}
					}
				}
				else
				{
					float num7 = screenRect.width / screenRect.height;
					if (num7 > num3)
					{
						float num8 = num3 / num7;
						sourceRect = new Rect(0f, (1f - num8) * 0.5f, 1f, num8);
					}
					else
					{
						float num9 = num7 / num3;
						sourceRect = new Rect(0.5f - num9 * 0.5f, 0f, num9, 1f);
					}
				}
				Graphics.DrawTexture(screenRect, texture, sourceRect, 0, 0, 0, 0, GUI.color, material);
			}
		}

		public static Texture2D GetReadableTexture(Texture inputTexture, bool requiresVerticalFlip, Orientation ori, Texture2D targetTexture)
		{
			Texture2D texture2D = targetTexture;
			RenderTexture active = RenderTexture.active;
			int width = inputTexture.width;
			int height = inputTexture.height;
			RenderTexture temporary = RenderTexture.GetTemporary(width, height, 0, RenderTextureFormat.ARGB32);
			if (ori == Orientation.Landscape)
			{
				if (!requiresVerticalFlip)
				{
					Graphics.Blit(inputTexture, temporary);
				}
				else
				{
					GL.PushMatrix();
					RenderTexture.active = temporary;
					GL.LoadPixelMatrix(0f, (float)temporary.width, 0f, (float)temporary.height);
					Rect sourceRect = new Rect(0f, 0f, 1f, 1f);
					Rect screenRect = new Rect(0f, -1f, (float)temporary.width, (float)temporary.height);
					Graphics.DrawTexture(screenRect, inputTexture, sourceRect, 0, 0, 0, 0);
					GL.PopMatrix();
					GL.InvalidateState();
				}
			}
			if (texture2D == null)
			{
				texture2D = new Texture2D(width, height, TextureFormat.ARGB32, false);
			}
			RenderTexture.active = temporary;
			texture2D.ReadPixels(new Rect(0f, 0f, (float)width, (float)height), 0, 0, false);
			texture2D.Apply(false, false);
			RenderTexture.ReleaseTemporary(temporary);
			RenderTexture.active = active;
			return texture2D;
		}

		private static int ParseTimeToMs(string text)
		{
			int result = 0;
			string[] array = text.Split(new char[]
			{
				':',
				','
			});
			if (array.Length == 4)
			{
				int num = int.Parse(array[0]);
				int num2 = int.Parse(array[1]);
				int num3 = int.Parse(array[2]);
				int num4 = int.Parse(array[3]);
				result = num4 + (num3 + (num2 + num * 60) * 60) * 1000;
			}
			return result;
		}

		public static List<Subtitle> LoadSubtitlesSRT(string data)
		{
			List<Subtitle> list = null;
			if (!string.IsNullOrEmpty(data))
			{
				data = data.Trim();
				Regex regex = new Regex("\n\r|\r\n|\n|\r");
				string[] array = regex.Split(data);
				if (array.Length >= 3)
				{
					list = new List<Subtitle>(256);
					int num = 0;
					int num2 = 0;
					Subtitle subtitle = null;
					for (int i = 0; i < array.Length; i++)
					{
						if (num2 == 0)
						{
							subtitle = new Subtitle();
							subtitle.index = num;
						}
						else if (num2 == 1)
						{
							string[] array2 = array[i].Split(new string[]
							{
								" --> "
							}, StringSplitOptions.RemoveEmptyEntries);
							if (array2.Length == 2)
							{
								subtitle.timeStartMs = Helper.ParseTimeToMs(array2[0]);
								subtitle.timeEndMs = Helper.ParseTimeToMs(array2[1]);
							}
						}
						else if (!string.IsNullOrEmpty(array[i]))
						{
							if (num2 == 2)
							{
								subtitle.text = array[i];
							}
							else
							{
								Subtitle subtitle2 = subtitle;
								subtitle2.text = subtitle2.text + "\n" + array[i];
							}
						}
						if (string.IsNullOrEmpty(array[i]) && num2 > 1)
						{
							list.Add(subtitle);
							num2 = 0;
							num++;
							subtitle = null;
						}
						else
						{
							num2++;
						}
					}
					if (subtitle != null)
					{
						list.Add(subtitle);
					}
				}
				else
				{
					Debug.LogWarning("[AVProVideo] SRT format doesn't appear to be valid");
				}
			}
			return list;
		}

		public const string ScriptVersion = "1.7.5";
	}
}
