using System;
using UnityEngine;

namespace RenderHeads.Media.AVProVideo
{
	[RequireComponent(typeof(MeshRenderer))]
	[RequireComponent(typeof(MeshFilter))]
	[AddComponentMenu("AVPro Video/Cubemap Cube (VR)", 400)]
	[HelpURL("http://renderheads.com/product/avpro-video/")]
	public class CubemapCube : MonoBehaviour
	{
		public MediaPlayer Player
		{
			get
			{
				return this._mediaPlayer;
			}
			set
			{
				this._mediaPlayer = value;
			}
		}

		private void Awake()
		{
			if (CubemapCube._propApplyGamma == 0)
			{
				CubemapCube._propApplyGamma = Shader.PropertyToID("_ApplyGamma");
			}
			if (CubemapCube._propUseYpCbCr == 0)
			{
				CubemapCube._propUseYpCbCr = Shader.PropertyToID("_UseYpCbCr");
			}
			if (CubemapCube._propChromaTex == 0)
			{
				CubemapCube._propChromaTex = Shader.PropertyToID("_ChromaTex");
			}
		}

		private void Start()
		{
			if (this._mesh == null)
			{
				this._mesh = new Mesh();
				this._mesh.MarkDynamic();
				MeshFilter component = base.GetComponent<MeshFilter>();
				if (component != null)
				{
					component.mesh = this._mesh;
				}
				this._renderer = base.GetComponent<MeshRenderer>();
				if (this._renderer != null)
				{
					this._renderer.material = this._material;
				}
				this.BuildMesh();
			}
		}

		private void OnDestroy()
		{
			if (this._mesh != null)
			{
				MeshFilter component = base.GetComponent<MeshFilter>();
				if (component != null)
				{
					component.mesh = null;
				}
				UnityEngine.Object.Destroy(this._mesh);
				this._mesh = null;
			}
			if (this._renderer != null)
			{
				this._renderer.material = null;
				this._renderer = null;
			}
		}

		private void LateUpdate()
		{
			if (Application.isPlaying)
			{
				if (this._mediaPlayer != null && this._mediaPlayer.Control != null)
				{
					if (this._mediaPlayer.TextureProducer != null)
					{
						Texture texture = (this._mediaPlayer.FrameResampler != null && this._mediaPlayer.FrameResampler.OutputTexture != null) ? this._mediaPlayer.FrameResampler.OutputTexture[0] : null;
						Texture texture2 = (!this._mediaPlayer.m_Resample) ? this._mediaPlayer.TextureProducer.GetTexture(0) : texture;
						bool flag = this._mediaPlayer.TextureProducer.RequiresVerticalFlip();
						if (this._texture != texture2 || this._verticalFlip != flag || (texture2 != null && (this._textureWidth != texture2.width || this._textureHeight != texture2.height)))
						{
							this._texture = texture2;
							if (texture2 != null)
							{
								this.UpdateMeshUV(texture2.width, texture2.height, flag);
							}
						}
						if (this._renderer.material.HasProperty(CubemapCube._propApplyGamma) && this._mediaPlayer.Info != null)
						{
							Helper.SetupGammaMaterial(this._renderer.material, this._mediaPlayer.Info.PlayerSupportsLinearColorSpace());
						}
						if (this._renderer.material.HasProperty(CubemapCube._propUseYpCbCr) && this._mediaPlayer.TextureProducer.GetTextureCount() == 2)
						{
							this._renderer.material.EnableKeyword("USE_YPCBCR");
							Texture texture3 = (this._mediaPlayer.FrameResampler != null && this._mediaPlayer.FrameResampler.OutputTexture != null) ? this._mediaPlayer.FrameResampler.OutputTexture[1] : null;
							this._renderer.material.SetTexture(CubemapCube._propChromaTex, (!this._mediaPlayer.m_Resample) ? this._mediaPlayer.TextureProducer.GetTexture(1) : texture3);
						}
					}
					this._renderer.material.mainTexture = this._texture;
				}
				else
				{
					this._renderer.material.mainTexture = null;
				}
			}
		}

		private void BuildMesh()
		{
			Vector3 b = new Vector3(-0.5f, -0.5f, -0.5f);
			Vector3[] array = new Vector3[]
			{
				new Vector3(0f, -1f, 0f) - b,
				new Vector3(0f, 0f, 0f) - b,
				new Vector3(0f, 0f, -1f) - b,
				new Vector3(0f, -1f, -1f) - b,
				new Vector3(0f, 0f, 0f) - b,
				new Vector3(-1f, 0f, 0f) - b,
				new Vector3(-1f, 0f, -1f) - b,
				new Vector3(0f, 0f, -1f) - b,
				new Vector3(-1f, 0f, 0f) - b,
				new Vector3(-1f, -1f, 0f) - b,
				new Vector3(-1f, -1f, -1f) - b,
				new Vector3(-1f, 0f, -1f) - b,
				new Vector3(-1f, -1f, 0f) - b,
				new Vector3(0f, -1f, 0f) - b,
				new Vector3(0f, -1f, -1f) - b,
				new Vector3(-1f, -1f, -1f) - b,
				new Vector3(0f, -1f, -1f) - b,
				new Vector3(0f, 0f, -1f) - b,
				new Vector3(-1f, 0f, -1f) - b,
				new Vector3(-1f, -1f, -1f) - b,
				new Vector3(-1f, -1f, 0f) - b,
				new Vector3(-1f, 0f, 0f) - b,
				new Vector3(0f, 0f, 0f) - b,
				new Vector3(0f, -1f, 0f) - b
			};
			Matrix4x4 matrix4x = Matrix4x4.TRS(Vector3.zero, Quaternion.AngleAxis(-90f, Vector3.right), Vector3.one);
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = matrix4x.MultiplyPoint(array[i]);
			}
			this._mesh.vertices = array;
			this._mesh.triangles = new int[]
			{
				0,
				1,
				2,
				0,
				2,
				3,
				4,
				5,
				6,
				4,
				6,
				7,
				8,
				9,
				10,
				8,
				10,
				11,
				12,
				13,
				14,
				12,
				14,
				15,
				16,
				17,
				18,
				16,
				18,
				19,
				20,
				21,
				22,
				20,
				22,
				23
			};
			this._mesh.normals = new Vector3[]
			{
				new Vector3(-1f, 0f, 0f),
				new Vector3(-1f, 0f, 0f),
				new Vector3(-1f, 0f, 0f),
				new Vector3(-1f, 0f, 0f),
				new Vector3(0f, -1f, 0f),
				new Vector3(0f, -1f, 0f),
				new Vector3(0f, -1f, 0f),
				new Vector3(0f, -1f, 0f),
				new Vector3(1f, 0f, 0f),
				new Vector3(1f, 0f, 0f),
				new Vector3(1f, 0f, 0f),
				new Vector3(1f, 0f, 0f),
				new Vector3(0f, 1f, 0f),
				new Vector3(0f, 1f, 0f),
				new Vector3(0f, 1f, 0f),
				new Vector3(0f, 1f, 0f),
				new Vector3(0f, 0f, 1f),
				new Vector3(0f, 0f, 1f),
				new Vector3(0f, 0f, 1f),
				new Vector3(0f, 0f, 1f),
				new Vector3(0f, 0f, -1f),
				new Vector3(0f, 0f, -1f),
				new Vector3(0f, 0f, -1f),
				new Vector3(0f, 0f, -1f)
			};
			this.UpdateMeshUV(512, 512, false);
		}

		private void UpdateMeshUV(int textureWidth, int textureHeight, bool flipY)
		{
			this._textureWidth = textureWidth;
			this._textureHeight = textureHeight;
			this._verticalFlip = flipY;
			float num = (float)textureWidth;
			float num2 = (float)textureHeight;
			float num3 = num / 3f;
			float num4 = Mathf.Floor((this.expansion_coeff * num3 - num3) / 2f);
			float num5 = num4 / num;
			float num6 = num4 / num2;
			Vector2[] array = null;
			if (this._layout == CubemapCube.Layout.Facebook360Capture)
			{
				array = new Vector2[]
				{
					new Vector2(0.333333343f + num5, 0.5f - num6),
					new Vector2(0.6666667f - num5, 0.5f - num6),
					new Vector2(0.6666667f - num5, num6),
					new Vector2(0.333333343f + num5, num6),
					new Vector2(0.333333343f + num5, 1f - num6),
					new Vector2(0.6666667f - num5, 1f - num6),
					new Vector2(0.6666667f - num5, 0.5f + num6),
					new Vector2(0.333333343f + num5, 0.5f + num6),
					new Vector2(num5, 0.5f - num6),
					new Vector2(0.333333343f - num5, 0.5f - num6),
					new Vector2(0.333333343f - num5, num6),
					new Vector2(num5, num6),
					new Vector2(0.6666667f + num5, 1f - num6),
					new Vector2(1f - num5, 1f - num6),
					new Vector2(1f - num5, 0.5f + num6),
					new Vector2(0.6666667f + num5, 0.5f + num6),
					new Vector2(0.6666667f + num5, num6),
					new Vector2(0.6666667f + num5, 0.5f - num6),
					new Vector2(1f - num5, 0.5f - num6),
					new Vector2(1f - num5, num6),
					new Vector2(0.333333343f - num5, 1f - num6),
					new Vector2(0.333333343f - num5, 0.5f + num6),
					new Vector2(num5, 0.5f + num6),
					new Vector2(num5, 1f - num6)
				};
			}
			else if (this._layout == CubemapCube.Layout.FacebookTransform32)
			{
				array = new Vector2[]
				{
					new Vector2(0.333333343f + num5, 1f - num6),
					new Vector2(0.6666667f - num5, 1f - num6),
					new Vector2(0.6666667f - num5, 0.5f + num6),
					new Vector2(0.333333343f + num5, 0.5f + num6),
					new Vector2(0.333333343f + num5, 0.5f - num6),
					new Vector2(0.6666667f - num5, 0.5f - num6),
					new Vector2(0.6666667f - num5, num6),
					new Vector2(0.333333343f + num5, num6),
					new Vector2(num5, 1f - num6),
					new Vector2(0.333333343f - num5, 1f - num6),
					new Vector2(0.333333343f - num5, 0.5f + num6),
					new Vector2(num5, 0.5f + num6),
					new Vector2(0.6666667f + num5, 0.5f - num6),
					new Vector2(1f - num5, 0.5f - num6),
					new Vector2(1f - num5, num6),
					new Vector2(0.6666667f + num5, num6),
					new Vector2(num5, num6),
					new Vector2(num5, 0.5f - num6),
					new Vector2(0.333333343f - num5, 0.5f - num6),
					new Vector2(0.333333343f - num5, num6),
					new Vector2(1f - num5, 1f - num6),
					new Vector2(1f - num5, 0.5f + num6),
					new Vector2(0.6666667f + num5, 0.5f + num6),
					new Vector2(0.6666667f + num5, 1f - num6)
				};
			}
			if (flipY)
			{
				for (int i = 0; i < array.Length; i++)
				{
					array[i].y = 1f - array[i].y;
				}
			}
			this._mesh.uv = array;
			this._mesh.UploadMeshData(false);
		}

		private Mesh _mesh;

		protected MeshRenderer _renderer;

		[SerializeField]
		protected Material _material;

		[SerializeField]
		private MediaPlayer _mediaPlayer;

		[SerializeField]
		private float expansion_coeff = 1.01f;

		[SerializeField]
		private CubemapCube.Layout _layout;

		private Texture _texture;

		private bool _verticalFlip;

		private int _textureWidth;

		private int _textureHeight;

		private static int _propApplyGamma;

		private static int _propUseYpCbCr;

		private const string PropChromaTexName = "_ChromaTex";

		private static int _propChromaTex;

		public enum Layout
		{
			FacebookTransform32,
			Facebook360Capture
		}
	}
}
