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

[Serializable]
public class Class3dScreenOverlay
{
	[Serializable]
	public class Overlay
	{
		public enum PostFilmMode
		{
			None,
			Lerp,
			Add,
			Mul,
			VignetteLerp,
			VignetteAdd,
			VignetteMul,
			Monochrome,
			ScreenBlend,
			VignetteScreenBlend
		}

		public enum LayerMode
		{
			Color,
			UVMovie,
			UVMovieNoScale
		}

		public enum ColorBlend
		{
			None,
			Lerp,
			Additive,
			Multiply
		}

		public static readonly string[] SHADER_KEYWORD_MODE = new string[10] { "MODE_NONE", "MODE_LERP", "MODE_ADD", "MODE_MUL", "MODE_VIGNETTE_LERP", "MODE_VIGNETTE_ADD", "MODE_VIGNETTE_MUL", "MODE_MONOCHROME", "MODE_SCREENBLEND", "MODE_VIGNETT_SCREENBLEND" };

		public static readonly string[] SHADER_KEYWORD_BLEND = new string[5] { "COLOR_ONLY", "BLEND_NONE", "BLEND_LERP", "BLEND_ADD", "BLEND_MUL" };

		public const float DEFAULT_DEPTH_CLIP = 2f;

		public PostFilmMode postFilmMode;

		public float postFilmPower;

		public float depthPower;

		public float DepthClip = 2f;

		public Vector2 postFilmOffsetParam = Vector2.zero;

		public Vector4 postFilmOptionParam = Vector4.zero;

		public Color postFilmColor0 = Color.black;

		public Color postFilmColor1 = Color.black;

		public Color postFilmColor2 = Color.black;

		public Color postFilmColor3 = Color.black;

		public bool inverseVignette;

		public LayerMode layerMode;

		public ColorBlend colorBlend;

		public int movieResId;

		private bool _isExistMovieMask;

		private Texture _movieTexture;

		private Texture _movieMaskTexture;

		private Vector2 _movieTextureScale = Vector2.one;

		private Vector2 _movieTextureOffset = Vector2.zero;

		public float colorBlendFactor;

		public Vector4 RollParameter;

		public Vector4 ScaleParameter = Vector4.one;

		private bool _isUVMovieNoScale;

		public bool IsEnableDepth = true;

		public void SetMovieInfo(Texture texMovie, Texture texMask, Vector2 scale, Vector2 offset)
		{
			_movieTexture = texMovie;
			_movieMaskTexture = texMask;
			_movieTextureScale = scale;
			_movieTextureOffset = offset;
			_isExistMovieMask = !(texMask == null);
		}

		public void SetScale(Vector2 scale)
		{
			ScaleParameter.x = 1f / scale.x;
			ScaleParameter.y = 1f / scale.y;
		}

		public void SetRollAngle(float angle)
		{
			RollParameter.x = Mathf.Sin(angle * (float)Math.PI / 180f);
			RollParameter.y = Mathf.Cos(angle * (float)Math.PI / 180f);
		}

		public Overlay()
		{
			SetRollAngle(0f);
		}

		private static void SetShaderKeyword(int id, string[] _arrKeywords, Material mtrl)
		{
			for (int i = 0; i < _arrKeywords.Length; i++)
			{
				if (id != i)
				{
					mtrl.DisableKeyword(_arrKeywords[i]);
				}
			}
			if (0 < id && id < _arrKeywords.Length)
			{
				mtrl.EnableKeyword(_arrKeywords[id]);
			}
		}

		public void Update(Material mtrl, RenderTexture mainTexture)
		{
			if (mtrl == null)
			{
				return;
			}
			SetShaderKeyword((int)postFilmMode, SHADER_KEYWORD_MODE, mtrl);
			switch (layerMode)
			{
			case LayerMode.Color:
				SetShaderKeyword((int)layerMode, SHADER_KEYWORD_BLEND, mtrl);
				break;
			case LayerMode.UVMovie:
			case LayerMode.UVMovieNoScale:
				SetShaderKeyword((int)layerMode + (int)colorBlend, SHADER_KEYWORD_BLEND, mtrl);
				if (_movieTexture != null)
				{
					mtrl.SetTexture("_texMovie", _movieTexture);
					float num = 0f;
					float num2 = (float)mainTexture.width / num;
					float num3 = (float)mainTexture.height / num;
					float num4 = 7f;
					float num5 = 3f;
					if (2.3333333f > num2 / num3)
					{
						num4 *= Mathf.Ceil(num2 / num4);
						num5 *= Mathf.Ceil(num3 / num5);
					}
					ScaleParameter.z = num2 / num4;
					ScaleParameter.w = num3 / num5;
				}
				break;
			}
			_isUVMovieNoScale = layerMode == LayerMode.UVMovieNoScale;
			if (_isExistMovieMask && _movieMaskTexture != null)
			{
				mtrl.SetTexture("_texMovieMask", _movieMaskTexture);
			}
			mtrl.SetVector("_movieScale", _movieTextureScale);
			mtrl.SetVector("_movieOffset", _movieTextureOffset);
			mtrl.SetFloat("_colorBlendFactor", colorBlendFactor);
		}

		public bool IsDepthValid()
		{
			if (!IsEnableDepth)
			{
				return false;
			}
			return IsValid();
		}

		public bool IsValid()
		{
			bool result = true;
			switch (postFilmMode)
			{
			case PostFilmMode.Monochrome:
				result = postFilmColor0.a > 0f;
				break;
			case PostFilmMode.None:
				result = false;
				break;
			default:
				result = postFilmPower > 0f;
				break;
			case PostFilmMode.Mul:
			case PostFilmMode.VignetteLerp:
			case PostFilmMode.VignetteMul:
				break;
			}
			return result;
		}

		public void Blit(RenderTexture source, RenderTexture destination, Material material, int pass)
		{
			if (inverseVignette)
			{
				pass++;
			}
			Update(material, source);
			Vector4 value = new Vector4(postFilmOffsetParam.x, postFilmOffsetParam.y);
			material.SetFloat("_PostFilmPower", postFilmPower);
			material.SetFloat("_DepthPower", depthPower);
			float value2 = ((!(DepthClip > 1.5f)) ? (1.5f - DepthClip) : 0f);
			material.SetFloat("_DepthClip", value2);
			material.SetVector("_PostFilmOffsetParam", value);
			material.SetVector("_PostFilmOptionParam", postFilmOptionParam);
			material.SetColor("_PostFilmColor0", postFilmColor0);
			material.SetColor("_PostFilmColor1", postFilmColor1);
			material.SetColor("_PostFilmColor2", postFilmColor2);
			material.SetColor("_PostFilmColor3", postFilmColor3);
			RollParameter.z = (float)source.width / (float)source.height;
			material.SetVector("_PostFilmRollParameter", RollParameter);
			material.SetVector("_PostFilmScaleParameter", ScaleParameter);
			material.SetFloat("_PostFilmIsUVMovieNoScale", _isUVMovieNoScale ? 1f : 0f);
			material.SetFloat("_PostFilmIsInverseVignette", inverseVignette ? 1f : 0f);
			material.SetFloat("_PostFilmIsAlphaMasking", _isExistMovieMask ? 1f : 0f);
			material.SetFloat("_PostFilmIsWithoutDepth", IsEnableDepth ? 0f : 1f);
			Graphics.Blit(source, destination, material, pass);
		}
	}

	[SerializeField]
	[Header("Screen Overlay - First layer")]
	private Overlay _overlay1 = new Overlay();

	[SerializeField]
	[Header("Screen Overlay - Second layer")]
	private Overlay _overlay2 = new Overlay();

	[SerializeField]
	[Header("Screen Overlay - Third layer")]
	private Overlay _overlay3 = new Overlay();

	public bool IsScreenOverlay = true;

	public Overlay Overlay1 => _overlay1;

	public Overlay Overlay2 => _overlay2;

	public Overlay Overlay3 => _overlay3;

	public bool IsEnable
	{
		get
		{
			if (!_overlay1.IsValid() && !_overlay2.IsValid())
			{
				return _overlay3.IsValid();
			}
			return true;
		}
	}

	public bool IsUseDepthTexture
	{
		get
		{
			if (!_overlay1.IsDepthValid() && !_overlay2.IsDepthValid())
			{
				return _overlay3.IsDepthValid();
			}
			return true;
		}
	}

	public void PostFilmBlit(RenderTexture source, RenderTexture destination, Material material, int defaultPass, int filmPass1st, int filmPass2nd)
	{
		if (material == null || !IsScreenOverlay)
		{
			Graphics.Blit(source, destination);
			return;
		}
		bool num = Overlay1.IsValid();
		bool flag = Overlay2.IsValid();
		bool flag2 = Overlay3.IsValid();
		RenderTexture renderTexture = destination;
		RenderTexture source2 = source;
		if (flag || flag2)
		{
			renderTexture = RenderTexture.GetTemporary(source.width, source.height, source.depth);
		}
		if (num)
		{
			Overlay1.Blit(source2, renderTexture, material, filmPass1st);
		}
		else if (defaultPass >= 0)
		{
			Graphics.Blit(source2, renderTexture, material, defaultPass);
		}
		else
		{
			Graphics.Blit(source2, renderTexture);
		}
		source2 = renderTexture;
		renderTexture = destination;
		if (flag)
		{
			if (flag2)
			{
				renderTexture = RenderTexture.GetTemporary(source.width, source.height, source.depth);
			}
			Overlay2.Blit(source2, renderTexture, material, filmPass2nd);
			if (source2 != source)
			{
				RenderTexture.ReleaseTemporary(source2);
				source2 = renderTexture;
				renderTexture = destination;
			}
		}
		if (flag2)
		{
			Overlay3.Blit(source2, renderTexture, material, filmPass2nd);
			if (source2 != source)
			{
				RenderTexture.ReleaseTemporary(source2);
				source2 = renderTexture;
				renderTexture = destination;
			}
		}
	}

	public static void SetShaderVariantKeyword(List<string> keywordList)
	{
		keywordList.AddRange(Overlay.SHADER_KEYWORD_MODE);
		keywordList.AddRange(Overlay.SHADER_KEYWORD_BLEND);
	}
}
