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

namespace RenderHeads.Media.AVProVideo
{
	[ExecuteInEditMode]
	[HelpURL("http://renderheads.com/product/avpro-video/")]
	[AddComponentMenu("AVPro Video/Display uGUI", 200)]
	public class DisplayUGUI : MaskableGraphic
	{
		protected override void Awake()
		{
			if (DisplayUGUI._propAlphaPack == 0)
			{
				DisplayUGUI._propStereo = Shader.PropertyToID("Stereo");
				DisplayUGUI._propAlphaPack = Shader.PropertyToID("AlphaPack");
				DisplayUGUI._propVertScale = Shader.PropertyToID("_VertScale");
				DisplayUGUI._propApplyGamma = Shader.PropertyToID("_ApplyGamma");
				DisplayUGUI._propUseYpCbCr = Shader.PropertyToID("_UseYpCbCr");
				DisplayUGUI._propChromaTex = Shader.PropertyToID("_ChromaTex");
			}
			if (DisplayUGUI._shaderAlphaPacking == null)
			{
				DisplayUGUI._shaderAlphaPacking = Shader.Find("AVProVideo/UI/Transparent Packed");
				if (DisplayUGUI._shaderAlphaPacking == null)
				{
					Debug.LogWarning("[AVProVideo] Missing shader AVProVideo/UI/Transparent Packed");
				}
			}
			if (DisplayUGUI._shaderStereoPacking == null)
			{
				DisplayUGUI._shaderStereoPacking = Shader.Find("AVProVideo/UI/Stereo");
				if (DisplayUGUI._shaderStereoPacking == null)
				{
					Debug.LogWarning("[AVProVideo] Missing shader AVProVideo/UI/Stereo");
				}
			}
			base.Awake();
		}

		protected override void Start()
		{
			this._userMaterial = (this.m_Material != null);
			base.Start();
		}

		protected override void OnDestroy()
		{
			if (this._material != null)
			{
				this.material = null;
				UnityEngine.Object.Destroy(this._material);
				this._material = null;
			}
			base.OnDestroy();
		}

		private Shader GetRequiredShader()
		{
			Shader shader = null;
			StereoPacking stereoPacking = this._mediaPlayer.m_StereoPacking;
			if (stereoPacking != StereoPacking.None)
			{
				if (stereoPacking == StereoPacking.LeftRight || stereoPacking == StereoPacking.TopBottom)
				{
					shader = DisplayUGUI._shaderStereoPacking;
				}
			}
			AlphaPacking alphaPacking = this._mediaPlayer.m_AlphaPacking;
			if (alphaPacking != AlphaPacking.None)
			{
				if (alphaPacking == AlphaPacking.LeftRight || alphaPacking == AlphaPacking.TopBottom)
				{
					shader = DisplayUGUI._shaderAlphaPacking;
				}
			}
			if (shader == null && this._mediaPlayer.Info != null && QualitySettings.activeColorSpace == ColorSpace.Linear && !this._mediaPlayer.Info.PlayerSupportsLinearColorSpace())
			{
				shader = DisplayUGUI._shaderAlphaPacking;
			}
			if (shader == null && this._mediaPlayer.TextureProducer != null && this._mediaPlayer.TextureProducer.GetTextureCount() == 2)
			{
				shader = DisplayUGUI._shaderAlphaPacking;
			}
			return shader;
		}

		public override Texture mainTexture
		{
			get
			{
				Texture result = Texture2D.whiteTexture;
				if (this.HasValidTexture())
				{
					Texture texture = (this._mediaPlayer.FrameResampler != null && this._mediaPlayer.FrameResampler.OutputTexture != null) ? this._mediaPlayer.FrameResampler.OutputTexture[0] : null;
					result = ((!this._mediaPlayer.m_Resample) ? this._mediaPlayer.TextureProducer.GetTexture(0) : texture);
				}
				else if (this._noDefaultDisplay)
				{
					result = null;
				}
				else if (this._defaultTexture != null)
				{
					result = this._defaultTexture;
				}
				return result;
			}
		}

		public bool HasValidTexture()
		{
			return this._mediaPlayer != null && this._mediaPlayer.TextureProducer != null && this._mediaPlayer.TextureProducer.GetTexture(0) != null;
		}

		private void UpdateInternalMaterial()
		{
			if (this._mediaPlayer != null)
			{
				Shader x = null;
				if (this._material != null)
				{
					x = this._material.shader;
				}
				Shader requiredShader = this.GetRequiredShader();
				if (x != requiredShader)
				{
					if (this._material != null)
					{
						this.material = null;
						UnityEngine.Object.Destroy(this._material);
						this._material = null;
					}
					if (requiredShader != null)
					{
						this._material = new Material(requiredShader);
					}
				}
				this.material = this._material;
			}
		}

		private void LateUpdate()
		{
			if (this._setNativeSize)
			{
				this.SetNativeSize();
			}
			if (this._lastTexture != this.mainTexture)
			{
				this._lastTexture = this.mainTexture;
				this.SetVerticesDirty();
			}
			if (this.HasValidTexture() && this.mainTexture != null && (this.mainTexture.width != this._lastWidth || this.mainTexture.height != this._lastHeight))
			{
				this._lastWidth = this.mainTexture.width;
				this._lastHeight = this.mainTexture.height;
				this.SetVerticesDirty();
			}
			if (!this._userMaterial && Application.isPlaying)
			{
				this.UpdateInternalMaterial();
			}
			if (this.material != null && this._mediaPlayer != null)
			{
				if (this.material.HasProperty(DisplayUGUI._propUseYpCbCr) && this._mediaPlayer.TextureProducer != null && this._mediaPlayer.TextureProducer.GetTextureCount() == 2)
				{
					this.material.EnableKeyword("USE_YPCBCR");
					Texture texture = (this._mediaPlayer.FrameResampler != null && this._mediaPlayer.FrameResampler.OutputTexture != null) ? this._mediaPlayer.FrameResampler.OutputTexture[1] : null;
					this.material.SetTexture(DisplayUGUI._propChromaTex, (!this._mediaPlayer.m_Resample) ? this._mediaPlayer.TextureProducer.GetTexture(1) : texture);
				}
				if (this.material.HasProperty(DisplayUGUI._propAlphaPack))
				{
					Helper.SetupAlphaPackedMaterial(this.material, this._mediaPlayer.m_AlphaPacking);
					if (this._flipY && this._mediaPlayer.m_AlphaPacking != AlphaPacking.None)
					{
						this.material.SetFloat(DisplayUGUI._propVertScale, -1f);
					}
					else
					{
						this.material.SetFloat(DisplayUGUI._propVertScale, 1f);
					}
				}
				if (this.material.HasProperty(DisplayUGUI._propStereo))
				{
					Helper.SetupStereoMaterial(this.material, this._mediaPlayer.m_StereoPacking, this._mediaPlayer.m_DisplayDebugStereoColorTint);
				}
				if (this.material.HasProperty(DisplayUGUI._propApplyGamma) && this._mediaPlayer.Info != null)
				{
					Helper.SetupGammaMaterial(this.material, this._mediaPlayer.Info.PlayerSupportsLinearColorSpace());
				}
			}
			this.SetMaterialDirty();
		}

		public MediaPlayer CurrentMediaPlayer
		{
			get
			{
				return this._mediaPlayer;
			}
			set
			{
				if (this._mediaPlayer != value)
				{
					this._mediaPlayer = value;
					this.SetMaterialDirty();
				}
			}
		}

		public Rect uvRect
		{
			get
			{
				return this.m_UVRect;
			}
			set
			{
				if (this.m_UVRect == value)
				{
					return;
				}
				this.m_UVRect = value;
				this.SetVerticesDirty();
			}
		}

		[ContextMenu("Set Native Size")]
		public override void SetNativeSize()
		{
			Texture mainTexture = this.mainTexture;
			if (mainTexture != null)
			{
				int num = Mathf.RoundToInt((float)mainTexture.width * this.uvRect.width);
				int num2 = Mathf.RoundToInt((float)mainTexture.height * this.uvRect.height);
				if (this._mediaPlayer != null)
				{
					if (this._mediaPlayer.m_AlphaPacking == AlphaPacking.LeftRight || this._mediaPlayer.m_StereoPacking == StereoPacking.LeftRight)
					{
						num /= 2;
					}
					else if (this._mediaPlayer.m_AlphaPacking == AlphaPacking.TopBottom || this._mediaPlayer.m_StereoPacking == StereoPacking.TopBottom)
					{
						num2 /= 2;
					}
				}
				base.rectTransform.anchorMax = base.rectTransform.anchorMin;
				base.rectTransform.sizeDelta = new Vector2((float)num, (float)num2);
			}
		}

		protected override void OnPopulateMesh(VertexHelper vh)
		{
			vh.Clear();
			this._OnFillVBO(this._vertices);
			vh.AddUIVertexStream(this._vertices, DisplayUGUI.QuadIndices);
		}

		[Obsolete("This method is not called from Unity 5.2 and above")]
		protected override void OnFillVBO(List<UIVertex> vbo)
		{
			this._OnFillVBO(vbo);
		}

		private void _OnFillVBO(List<UIVertex> vbo)
		{
			this._flipY = false;
			if (this.HasValidTexture())
			{
				this._flipY = this._mediaPlayer.TextureProducer.RequiresVerticalFlip();
			}
			Rect uvrect = this.m_UVRect;
			Vector4 drawingDimensions = this.GetDrawingDimensions(this._scaleMode, ref uvrect);
			vbo.Clear();
			UIVertex simpleVert = UIVertex.simpleVert;
			simpleVert.color = this.color;
			simpleVert.position = new Vector2(drawingDimensions.x, drawingDimensions.y);
			simpleVert.uv0 = new Vector2(uvrect.xMin, uvrect.yMin);
			if (this._flipY)
			{
				simpleVert.uv0 = new Vector2(uvrect.xMin, 1f - uvrect.yMin);
			}
			vbo.Add(simpleVert);
			simpleVert.position = new Vector2(drawingDimensions.x, drawingDimensions.w);
			simpleVert.uv0 = new Vector2(uvrect.xMin, uvrect.yMax);
			if (this._flipY)
			{
				simpleVert.uv0 = new Vector2(uvrect.xMin, 1f - uvrect.yMax);
			}
			vbo.Add(simpleVert);
			simpleVert.position = new Vector2(drawingDimensions.z, drawingDimensions.w);
			simpleVert.uv0 = new Vector2(uvrect.xMax, uvrect.yMax);
			if (this._flipY)
			{
				simpleVert.uv0 = new Vector2(uvrect.xMax, 1f - uvrect.yMax);
			}
			vbo.Add(simpleVert);
			simpleVert.position = new Vector2(drawingDimensions.z, drawingDimensions.y);
			simpleVert.uv0 = new Vector2(uvrect.xMax, uvrect.yMin);
			if (this._flipY)
			{
				simpleVert.uv0 = new Vector2(uvrect.xMax, 1f - uvrect.yMin);
			}
			vbo.Add(simpleVert);
		}

		private Vector4 GetDrawingDimensions(ScaleMode scaleMode, ref Rect uvRect)
		{
			Vector4 zero = Vector4.zero;
			if (this.mainTexture != null)
			{
				Vector4 zero2 = Vector4.zero;
				Vector2 vector = new Vector2((float)this.mainTexture.width, (float)this.mainTexture.height);
				if (this._mediaPlayer != null)
				{
					if (this._mediaPlayer.m_AlphaPacking == AlphaPacking.LeftRight || this._mediaPlayer.m_StereoPacking == StereoPacking.LeftRight)
					{
						vector.x /= 2f;
					}
					else if (this._mediaPlayer.m_AlphaPacking == AlphaPacking.TopBottom || this._mediaPlayer.m_StereoPacking == StereoPacking.TopBottom)
					{
						vector.y /= 2f;
					}
				}
				Rect pixelAdjustedRect = base.GetPixelAdjustedRect();
				int num = Mathf.RoundToInt(vector.x);
				int num2 = Mathf.RoundToInt(vector.y);
				Vector4 vector2 = new Vector4(zero2.x / (float)num, zero2.y / (float)num2, ((float)num - zero2.z) / (float)num, ((float)num2 - zero2.w) / (float)num2);
				if (vector.sqrMagnitude > 0f)
				{
					if (scaleMode == ScaleMode.ScaleToFit)
					{
						float num3 = vector.x / vector.y;
						float num4 = pixelAdjustedRect.width / pixelAdjustedRect.height;
						if (num3 > num4)
						{
							float height = pixelAdjustedRect.height;
							pixelAdjustedRect.height = pixelAdjustedRect.width * (1f / num3);
							pixelAdjustedRect.y += (height - pixelAdjustedRect.height) * base.rectTransform.pivot.y;
						}
						else
						{
							float width = pixelAdjustedRect.width;
							pixelAdjustedRect.width = pixelAdjustedRect.height * num3;
							pixelAdjustedRect.x += (width - pixelAdjustedRect.width) * base.rectTransform.pivot.x;
						}
					}
					else if (scaleMode == ScaleMode.ScaleAndCrop)
					{
						float num5 = vector.x / vector.y;
						float num6 = pixelAdjustedRect.width / pixelAdjustedRect.height;
						if (num6 > num5)
						{
							float num7 = num5 / num6;
							uvRect = new Rect(0f, (1f - num7) * 0.5f, 1f, num7);
						}
						else
						{
							float num8 = num6 / num5;
							uvRect = new Rect(0.5f - num8 * 0.5f, 0f, num8, 1f);
						}
					}
				}
				zero = new Vector4(pixelAdjustedRect.x + pixelAdjustedRect.width * vector2.x, pixelAdjustedRect.y + pixelAdjustedRect.height * vector2.y, pixelAdjustedRect.x + pixelAdjustedRect.width * vector2.z, pixelAdjustedRect.y + pixelAdjustedRect.height * vector2.w);
			}
			return zero;
		}

		[SerializeField]
		public MediaPlayer _mediaPlayer;

		[SerializeField]
		public Rect m_UVRect = new Rect(0f, 0f, 1f, 1f);

		[SerializeField]
		public bool _setNativeSize;

		[SerializeField]
		public ScaleMode _scaleMode = ScaleMode.ScaleToFit;

		[SerializeField]
		public bool _noDefaultDisplay = true;

		[SerializeField]
		public bool _displayInEditor = true;

		[SerializeField]
		public Texture _defaultTexture;

		private int _lastWidth;

		private int _lastHeight;

		private bool _flipY;

		private Texture _lastTexture;

		private static Shader _shaderStereoPacking;

		private static Shader _shaderAlphaPacking;

		private static int _propAlphaPack;

		private static int _propVertScale;

		private static int _propStereo;

		private static int _propApplyGamma;

		private static int _propUseYpCbCr;

		private const string PropChromaTexName = "_ChromaTex";

		private static int _propChromaTex;

		private bool _userMaterial = true;

		private Material _material;

		private List<UIVertex> _vertices = new List<UIVertex>(4);

		private static List<int> QuadIndices = new List<int>(new int[]
		{
			0,
			1,
			2,
			2,
			3,
			0
		});
	}
}
