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

namespace ToonyColorsPro.Runtime
{
	// Token: 0x02000118 RID: 280
	[ExecuteInEditMode]
	public class PlanarReflection : MonoBehaviour
	{
		// Token: 0x17000064 RID: 100
		// (get) Token: 0x060016B2 RID: 5810 RVA: 0x001A05B2 File Offset: 0x0019E7B2
		private static int ShaderID_ReflectionTex
		{
			get
			{
				if (PlanarReflection._ShaderID_ReflectionTex < 0)
				{
					PlanarReflection._ShaderID_ReflectionTex = Shader.PropertyToID("_ReflectionTex");
				}
				return PlanarReflection._ShaderID_ReflectionTex;
			}
		}

		// Token: 0x17000065 RID: 101
		// (get) Token: 0x060016B3 RID: 5811 RVA: 0x001A05D0 File Offset: 0x0019E7D0
		private static int ShaderID_ReflectionDepthTex
		{
			get
			{
				if (PlanarReflection._ShaderID_ReflectionDepthTex < 0)
				{
					PlanarReflection._ShaderID_ReflectionDepthTex = Shader.PropertyToID("_ReflectionDepthTex");
				}
				return PlanarReflection._ShaderID_ReflectionDepthTex;
			}
		}

		// Token: 0x17000066 RID: 102
		// (get) Token: 0x060016B4 RID: 5812 RVA: 0x001A05EE File Offset: 0x0019E7EE
		private static int ShaderID_ReflectivePlaneY
		{
			get
			{
				if (PlanarReflection._ShaderID_ReflectivePlaneY < 0)
				{
					PlanarReflection._ShaderID_ReflectivePlaneY = Shader.PropertyToID("_ReflectivePlaneY");
				}
				return PlanarReflection._ShaderID_ReflectivePlaneY;
			}
		}

		// Token: 0x17000067 RID: 103
		// (get) Token: 0x060016B5 RID: 5813 RVA: 0x001A060C File Offset: 0x0019E80C
		private static int ShaderID_ReflectionDepthRange
		{
			get
			{
				if (PlanarReflection._ShaderID_ReflectionDepthRange < 0)
				{
					PlanarReflection._ShaderID_ReflectionDepthRange = Shader.PropertyToID("_ReflectionDepthRange");
				}
				return PlanarReflection._ShaderID_ReflectionDepthRange;
			}
		}

		// Token: 0x17000068 RID: 104
		// (get) Token: 0x060016B6 RID: 5814 RVA: 0x001A062A File Offset: 0x0019E82A
		private static int ShaderID_UseReflectionDepth
		{
			get
			{
				if (PlanarReflection._ShaderID_UseReflectionDepth < 0)
				{
					PlanarReflection._ShaderID_UseReflectionDepth = Shader.PropertyToID("_UseReflectionDepth");
				}
				return PlanarReflection._ShaderID_UseReflectionDepth;
			}
		}

		// Token: 0x060016B7 RID: 5815 RVA: 0x001A0648 File Offset: 0x0019E848
		private void OnValidate()
		{
			this.UpdateRenderTexture();
		}

		// Token: 0x060016B8 RID: 5816 RVA: 0x001A0650 File Offset: 0x0019E850
		private void OnEnable()
		{
			this.UpdateRenderTexture();
			this.RemoveBuffer();
		}

		// Token: 0x060016B9 RID: 5817 RVA: 0x001A065E File Offset: 0x0019E85E
		private void OnDisable()
		{
			this.ClearRenderTexture();
			this.RemoveBuffer();
		}

		// Token: 0x060016BA RID: 5818 RVA: 0x001A066C File Offset: 0x0019E86C
		private void UpdateRenderTexture()
		{
			if (this.reflectionRenderTexture != null)
			{
				this.ClearRenderTexture();
			}
			this.reflectionRenderTexture = new RenderTexture(this.textureSize, this.textureSize, 16, this.renderTextureFormat, RenderTextureReadWrite.sRGB);
			this.reflectionRenderTexture.name = "Planar Reflection for " + base.GetInstanceID().ToString();
			this.reflectionRenderTexture.hideFlags = HideFlags.DontSaveInEditor | HideFlags.DontSaveInBuild;
			this.reflectionLightsTexture = new RenderTexture(this.textureSize, this.textureSize, 16, this.renderTextureFormat, RenderTextureReadWrite.sRGB);
			this.reflectionLightsTextureTemp1 = new RenderTexture(this.textureSize / 2, this.textureSize / 2, 16, this.renderTextureFormat, RenderTextureReadWrite.sRGB);
			this.reflectionLightsTextureTemp2 = new RenderTexture(this.textureSize / 2, this.textureSize / 2, 16, this.renderTextureFormat, RenderTextureReadWrite.sRGB);
			this.reflectionLightsTextureTemp3 = new RenderTexture(this.textureSize / 2, this.textureSize / 2, 16, this.renderTextureFormat, RenderTextureReadWrite.sRGB);
			this.reflectionRenderTexture.hideFlags = HideFlags.DontSaveInEditor | HideFlags.DontSaveInBuild;
		}

		// Token: 0x060016BB RID: 5819 RVA: 0x001A0778 File Offset: 0x0019E978
		private void ClearRenderTexture()
		{
			if (this.reflectionRenderTexture != null)
			{
				this.reflectionRenderTexture.Release();
				this.reflectionLightsTexture.Release();
				this.reflectionLightsTextureTemp1.Release();
				this.reflectionLightsTextureTemp2.Release();
				this.reflectionLightsTextureTemp3.Release();
				Object.DestroyImmediate(this.reflectionRenderTexture);
			}
		}

		// Token: 0x060016BC RID: 5820 RVA: 0x001A07D5 File Offset: 0x0019E9D5
		private void RemoveBuffer()
		{
			if (this.opaqueBuffer != null && this.reflectionCamera)
			{
				this.reflectionCamera.RemoveCommandBuffer(CameraEvent.AfterForwardOpaque, this.opaqueBuffer);
			}
			this.opaqueBuffer = null;
		}

		// Token: 0x060016BD RID: 5821 RVA: 0x001A0808 File Offset: 0x0019EA08
		public bool TestPlanesAABBInternalFast(Vector3 pt, float radius)
		{
			for (int i = 0; i < this.planes.Length; i++)
			{
				Vector3 normal = this.planes[i].normal;
				float distance = this.planes[i].distance;
				Vector3 vector;
				Vector3 vector2;
				if (normal.x < 0f)
				{
					vector.x = pt.x - radius;
					vector2.x = pt.x + radius;
				}
				else
				{
					vector.x = pt.x + radius;
					vector2.x = pt.x - radius;
				}
				if (normal.y < 0f)
				{
					vector.y = pt.y - radius;
					vector2.y = pt.y + radius;
				}
				else
				{
					vector.y = pt.y + radius;
					vector2.y = pt.y - radius;
				}
				if (normal.z < 0f)
				{
					vector.z = pt.z - radius;
					vector2.z = pt.z + radius;
				}
				else
				{
					vector.z = pt.z + radius;
					vector2.z = pt.z - radius;
				}
				if (normal.x * vector.x + normal.y * vector.y + normal.z * vector.z + distance < 0f)
				{
					return false;
				}
			}
			return true;
		}

		// Token: 0x060016BE RID: 5822 RVA: 0x001A096C File Offset: 0x0019EB6C
		public void BeforeImageEffects()
		{
			if (!this.reflectionCamera)
			{
				this.GetCamera();
			}
			if (!Links.x)
			{
				return;
			}
			if (this.moonlights == null && Links.x.worldCamera)
			{
				this.moonlights = Links.x.cameraEffects.moonlights;
			}
			if (this.moonlights == null)
			{
				return;
			}
			if (this.reflectionCamera)
			{
				if (this.opaqueBuffer == null)
				{
					this.opaqueBuffer = new CommandBuffer();
					this.opaqueBuffer.name = "ReflectionLights";
					this.reflectionCamera.AddCommandBuffer(CameraEvent.AfterForwardOpaque, this.opaqueBuffer);
				}
				this.opaqueBuffer.Clear();
				RenderTargetIdentifier renderTargetIdentifier = new RenderTargetIdentifier(this.reflectionLightsTexture);
				RenderTargetIdentifier renderTargetIdentifier2 = BuiltinRenderTextureType.CameraTarget;
				if (!this.lightMaterial)
				{
					this.lightMaterial = new Material(Shader.Find("Hidden/ReflectionLights"));
				}
				if (!this.blurMaterial)
				{
					this.blurMaterial = new Material(Shader.Find("Hidden/FastBlur"));
				}
				this.opaqueBuffer.SetRenderTarget(renderTargetIdentifier, BuiltinRenderTextureType.CameraTarget);
				this.opaqueBuffer.ClearRenderTarget(false, true, Color.black);
				this.matrix = default(Matrix4x4);
				Quaternion quaternion = Quaternion.Euler(0f, 0f, 0f);
				this.matrix.SetTRS(Vector3.zero, Quaternion.Euler(-45f, -135f, 0f), new Vector3(0f, 0f, 0f));
				this.matrix.SetRow(3, new Vector4(0f, 0f, 0f, 1f));
				Vector4 vector = new Vector4(0f, 0f, 0f, 1f);
				Vector3 vector2 = Vector3.zero;
				new Vector4(0f, 0f, 0f, 0f);
				Color color = new Color(0f, 0f, 0f, 0f);
				Vector3 zero = Vector3.zero;
				for (int i = 0; i < this.moonlights.Count; i++)
				{
					Light light = this.moonlights[i];
					if (light)
					{
						Transform transform = light.transform;
						if (this.TestPlanesAABBInternalFast(transform.position, light.range * 1.2f))
						{
							vector2 = transform.position;
							vector.x = vector2.x;
							vector.y = vector2.y;
							vector.z = vector2.z;
							float num = light.range / 2f;
							zero.x = num;
							zero.y = num;
							zero.z = num;
							this.matrix.SetTRS(vector, quaternion, zero);
							color = light.color;
							color.a = 1f;
							this.opaqueBuffer.SetGlobalVector("_ReflectionLightColor", color);
							this.opaqueBuffer.DrawMesh(this.sphereMesh, this.matrix, this.lightMaterial, 0, 0);
						}
					}
				}
				int num2 = 2;
				float num3 = 1f / (1f * (float)(1 << num2));
				this.blurMaterial.SetVector("_Parameter", new Vector4(this.blurSize * num3, -this.blurSize * num3, 0f, 0f));
				int num4 = ((this.blurType == PlanarReflection.BlurType.StandardGauss) ? 0 : 2);
				float num5 = 1f;
				this.blurMaterial.SetVector("_Parameter", new Vector4(this.blurSize * num3 + num5, -this.blurSize * num3 - num5, 0f, 0f));
				this.opaqueBuffer.Blit(this.reflectionLightsTexture, this.reflectionLightsTextureTemp2, this.blurMaterial, 1 + num4);
				this.opaqueBuffer.Blit(this.reflectionLightsTextureTemp2, this.reflectionLightsTextureTemp3, this.blurMaterial, 2 + num4);
				this.opaqueBuffer.SetGlobalTexture("_ReflectionLights", this.reflectionLightsTextureTemp3);
				this.opaqueBuffer.Blit(this.reflectionLightsTextureTemp3, renderTargetIdentifier2, this.lightMaterial, 1);
			}
		}

		// Token: 0x060016BF RID: 5823 RVA: 0x001A0DBD File Offset: 0x0019EFBD
		private void Update()
		{
			if (this.reflectionCamera)
			{
				this.planes = GeometryUtility.CalculateFrustumPlanes(this.reflectionCamera);
			}
			this.BeforeImageEffects();
		}

		// Token: 0x060016C0 RID: 5824 RVA: 0x001A0DE3 File Offset: 0x0019EFE3
		public void BeginCameraRendering_Bultin(Camera camera)
		{
			if (!base.enabled)
			{
				return;
			}
			if ((camera.cameraType & (CameraType.Game | CameraType.SceneView)) == (CameraType)0)
			{
				return;
			}
			this.GetCamera();
			if (Links.x)
			{
				this.RenderPlanarReflection(Links.x.worldCamera);
			}
		}

		// Token: 0x060016C1 RID: 5825 RVA: 0x001A0E1C File Offset: 0x0019F01C
		public void GetCamera()
		{
			if (!Links.x)
			{
				return;
			}
			if (!Links.x.worldCamera)
			{
				return;
			}
			if (this.reflectionCamera == null)
			{
				GameObject gameObject = GameObject.Find("Planar Reflection Camera");
				if (gameObject)
				{
					this.reflectionCamera = gameObject.GetComponent<Camera>();
				}
				if (gameObject)
				{
					gameObject.transform.parent = base.transform;
				}
			}
			if (this.reflectionCamera == null)
			{
				GameObject gameObject2 = new GameObject("Planar Reflection Camera", new Type[] { typeof(Camera) });
				this.reflectionCamera = gameObject2.GetComponent<Camera>();
				this.reflectionCamera.enabled = false;
				this.reflectionCamera.CopyFrom(Links.x.worldCamera);
				if (gameObject2)
				{
					gameObject2.transform.parent = base.transform;
				}
				this.UpdateRenderTexture();
				this.reflectionCamera.targetTexture = this.reflectionRenderTexture;
			}
		}

		// Token: 0x060016C2 RID: 5826 RVA: 0x001A0F18 File Offset: 0x0019F118
		public void RenderPlanarReflection(Camera worldCamera)
		{
			if (worldCamera == null)
			{
				return;
			}
			if (this.reflectionCamera == null)
			{
				return;
			}
			base.GetComponent<Renderer>();
			if (PlanarReflection.s_InsideRendering)
			{
				return;
			}
			PlanarReflection.s_InsideRendering = true;
			Vector3 position = base.transform.position;
			Vector3 up = base.transform.up;
			int pixelLightCount = QualitySettings.pixelLightCount;
			if (this.disablePixelLights)
			{
				QualitySettings.pixelLightCount = 0;
			}
			this.reflectionCamera.CopyFrom(worldCamera);
			this.reflectionCamera.allowMSAA = false;
			if (this.useCustomBackgroundColor)
			{
				this.reflectionCamera.clearFlags = CameraClearFlags.Color;
				this.reflectionCamera.backgroundColor = this.backgroundColor;
			}
			if (Links.x && Links.x.main)
			{
				this.clipPlaneOffset = Links.x.main.tr.position.y;
			}
			float num = -Vector3.Dot(up, position) - this.clipPlaneOffset;
			Vector4 vector = new Vector4(up.x, up.y, up.z, num);
			Matrix4x4 zero = Matrix4x4.zero;
			PlanarReflection.CalculateReflectionMatrix(ref zero, vector);
			Vector3 position2 = worldCamera.transform.position;
			Vector3 vector2 = zero.MultiplyPoint(position2);
			this.reflectionCamera.worldToCameraMatrix = worldCamera.worldToCameraMatrix * zero;
			Vector4 vector3 = this.CameraSpacePlane(this.reflectionCamera, position, up, 1f);
			Matrix4x4 matrix4x = worldCamera.CalculateObliqueMatrix(vector3);
			this.reflectionCamera.projectionMatrix = matrix4x;
			this.reflectionCamera.targetTexture = this.reflectionRenderTexture;
			this.reflectionCamera.cullingMask = ~(1 << base.gameObject.layer) & this.reflectLayers.value;
			GL.invertCulling = true;
			this.reflectionCamera.transform.position = vector2;
			Vector3 eulerAngles = worldCamera.transform.eulerAngles;
			this.reflectionCamera.transform.eulerAngles = new Vector3(0f, eulerAngles.y, eulerAngles.z);
			QualitySettings.shadows = ShadowQuality.Disable;
			this.reflectionCamera.RenderWithShader(this.reflectionReplaceShader, "RenderType");
			QualitySettings.shadows = ShadowQuality.All;
			this.reflectionCamera.transform.position = position2;
			GL.invertCulling = false;
			Shader.SetGlobalTexture("_ReflectionTexture", this.reflectionRenderTexture);
			if (this.disablePixelLights)
			{
				QualitySettings.pixelLightCount = pixelLightCount;
			}
			PlanarReflection.s_InsideRendering = false;
		}

		// Token: 0x060016C3 RID: 5827 RVA: 0x001A1174 File Offset: 0x0019F374
		private Vector4 CameraSpacePlane(Camera cam, Vector3 pos, Vector3 normal, float sideSign)
		{
			Vector3 vector = pos + normal * this.clipPlaneOffset;
			Matrix4x4 worldToCameraMatrix = this.reflectionCamera.worldToCameraMatrix;
			Vector3 vector2 = worldToCameraMatrix.MultiplyPoint(vector);
			Vector3 vector3 = worldToCameraMatrix.MultiplyVector(normal).normalized * sideSign;
			return new Vector4(vector3.x, vector3.y, vector3.z, -Vector3.Dot(vector2, vector3));
		}

		// Token: 0x060016C4 RID: 5828 RVA: 0x001A11E4 File Offset: 0x0019F3E4
		private static void CalculateReflectionMatrix(ref Matrix4x4 reflectionMat, Vector4 plane)
		{
			reflectionMat.m00 = 1f - 2f * plane[0] * plane[0];
			reflectionMat.m01 = -2f * plane[0] * plane[1];
			reflectionMat.m02 = -2f * plane[0] * plane[2];
			reflectionMat.m03 = -2f * plane[3] * plane[0];
			reflectionMat.m10 = -2f * plane[1] * plane[0];
			reflectionMat.m11 = 1f - 2f * plane[1] * plane[1];
			reflectionMat.m12 = -2f * plane[1] * plane[2];
			reflectionMat.m13 = -2f * plane[3] * plane[1];
			reflectionMat.m20 = -2f * plane[2] * plane[0];
			reflectionMat.m21 = -2f * plane[2] * plane[1];
			reflectionMat.m22 = 1f - 2f * plane[2] * plane[2];
			reflectionMat.m23 = -2f * plane[3] * plane[2];
			reflectionMat.m30 = 0f;
			reflectionMat.m31 = 0f;
			reflectionMat.m32 = 0f;
			reflectionMat.m33 = 1f;
		}

		// Token: 0x040026CE RID: 9934
		public int textureSize = 1024;

		// Token: 0x040026CF RID: 9935
		public RenderTextureFormat renderTextureFormat = RenderTextureFormat.Default;

		// Token: 0x040026D0 RID: 9936
		public LayerMask reflectLayers = -1;

		// Token: 0x040026D1 RID: 9937
		public bool disablePixelLights;

		// Token: 0x040026D2 RID: 9938
		public float clipPlaneOffset = 0.07f;

		// Token: 0x040026D3 RID: 9939
		[Range(0f, 10f)]
		public float blurSize = 3f;

		// Token: 0x040026D4 RID: 9940
		[Range(1f, 4f)]
		public int blurIterations = 2;

		// Token: 0x040026D5 RID: 9941
		public PlanarReflection.BlurType blurType;

		// Token: 0x040026D6 RID: 9942
		[Space]
		public bool useCustomBackgroundColor;

		// Token: 0x040026D7 RID: 9943
		public Color backgroundColor = Color.black;

		// Token: 0x040026D8 RID: 9944
		public Camera reflectionCamera;

		// Token: 0x040026D9 RID: 9945
		private RenderTexture reflectionRenderTexture;

		// Token: 0x040026DA RID: 9946
		private RenderTexture reflectionLightsTexture;

		// Token: 0x040026DB RID: 9947
		private RenderTexture reflectionLightsTextureTemp1;

		// Token: 0x040026DC RID: 9948
		private RenderTexture reflectionLightsTextureTemp2;

		// Token: 0x040026DD RID: 9949
		private RenderTexture reflectionLightsTextureTemp3;

		// Token: 0x040026DE RID: 9950
		public Shader reflectionReplaceShader;

		// Token: 0x040026DF RID: 9951
		private Material lightMaterial;

		// Token: 0x040026E0 RID: 9952
		private Material blurMaterial;

		// Token: 0x040026E1 RID: 9953
		private CommandBuffer opaqueBuffer;

		// Token: 0x040026E2 RID: 9954
		private static bool s_InsideRendering;

		// Token: 0x040026E3 RID: 9955
		private Mesh screenQuad;

		// Token: 0x040026E4 RID: 9956
		public Mesh sphereMesh;

		// Token: 0x040026E5 RID: 9957
		private List<Light> moonlights;

		// Token: 0x040026E6 RID: 9958
		private Matrix4x4 matrix;

		// Token: 0x040026E7 RID: 9959
		private Plane[] planes = new Plane[0];

		// Token: 0x040026E8 RID: 9960
		private static int _ShaderID_ReflectionTex = -1;

		// Token: 0x040026E9 RID: 9961
		private static int _ShaderID_ReflectionDepthTex = -1;

		// Token: 0x040026EA RID: 9962
		private static int _ShaderID_ReflectivePlaneY = -1;

		// Token: 0x040026EB RID: 9963
		private static int _ShaderID_ReflectionDepthRange = -1;

		// Token: 0x040026EC RID: 9964
		private static int _ShaderID_UseReflectionDepth = -1;

		// Token: 0x0200026B RID: 619
		public enum BlurType
		{
			// Token: 0x040034C6 RID: 13510
			StandardGauss,
			// Token: 0x040034C7 RID: 13511
			SgxGauss
		}
	}
}
