using System;
using System.IO;
using UnityEngine;

namespace TriLib
{
	public static class Texture2DUtils
	{
		public static Texture2D LoadTextureFromFile(IntPtr scene, string path, string name, Material material, string propertyName, ref bool checkAlphaChannel, TextureWrapMode textureWrapMode = TextureWrapMode.Repeat, string basePath = null, TextureLoadHandle onTextureLoaded = null, TextureCompression textureCompression = TextureCompression.None, string textureFileNameWithoutExtension = null, bool isNormalMap = false)
		{
			if (scene == IntPtr.Zero || string.IsNullOrEmpty(path))
			{
				return null;
			}
			int width = 0;
			int height = 0;
			string text;
			byte[] array;
			bool isRawData;
			if (!Texture2DUtils.LoadEmbeddedTextureData(scene, path, out text, out array, out isRawData, out width, out height))
			{
				string text2 = null;
				text = path;
				array = FileUtils.LoadFileData(text);
				if (array.Length == 0 && basePath != null)
				{
					text = Path.Combine(basePath, path);
					array = FileUtils.LoadFileData(text);
				}
				if (array.Length == 0)
				{
					text2 = FileUtils.GetFilename(path);
					text = text2;
					array = FileUtils.LoadFileData(text);
				}
				if (array.Length == 0 && basePath != null && text2 != null)
				{
					text = Path.Combine(basePath, text2);
					array = FileUtils.LoadFileData(text);
				}
				if (array.Length == 0)
				{
					return null;
				}
			}
			Texture2D tempTexture2D;
			if (Texture2DUtils.ApplyTextureData(array, isRawData, out tempTexture2D, width, height))
			{
				return Texture2DUtils.ProccessTextureData(tempTexture2D, name, material, propertyName, ref checkAlphaChannel, textureWrapMode, text, onTextureLoaded, textureCompression, isNormalMap);
			}
			return null;
		}

		public static Texture2D LoadTextureFromMemory(byte[] data, string path, Material material, string propertyName, ref bool checkAlphaChannel, TextureWrapMode textureWrapMode = TextureWrapMode.Repeat, TextureLoadHandle onTextureLoaded = null, TextureCompression textureCompression = TextureCompression.None, bool isNormalMap = false, bool isRawData = false, int width = 0, int height = 0)
		{
			if (data.Length == 0 || string.IsNullOrEmpty(path))
			{
				return null;
			}
			Texture2D tempTexture2D;
			if (Texture2DUtils.ApplyTextureData(data, isRawData, out tempTexture2D, width, height))
			{
				return Texture2DUtils.ProccessTextureData(tempTexture2D, StringUtils.GenerateUniqueName(path.GetHashCode()), material, propertyName, ref checkAlphaChannel, textureWrapMode, null, onTextureLoaded, textureCompression, isNormalMap);
			}
			return null;
		}

		public static bool ApplyTextureData(byte[] data, bool isRawData, out Texture2D tempTexture2D, int width = 0, int height = 0)
		{
			if (data.Length == 0)
			{
				tempTexture2D = null;
				return false;
			}
			if (isRawData)
			{
				try
				{
					tempTexture2D = new Texture2D(width, height, TextureFormat.ARGB32, true);
					tempTexture2D.LoadRawTextureData(data);
					tempTexture2D.Apply();
					return true;
				}
				catch
				{
				}
			}
			tempTexture2D = new Texture2D(2, 2, TextureFormat.RGBA32, true);
			return tempTexture2D.LoadImage(data);
		}

		public static bool LoadEmbeddedTextureData(IntPtr scene, string path, out string finalPath, out byte[] data, out bool isRawData, out int width, out int height)
		{
			if (scene != IntPtr.Zero && !string.IsNullOrEmpty(path))
			{
				IntPtr intPtr = AssimpInterop.aiScene_GetEmbeddedTexture(scene, path);
				if (intPtr != IntPtr.Zero)
				{
					isRawData = !AssimpInterop.aiMaterial_IsEmbeddedTextureCompressed(scene, intPtr);
					uint uintSize = AssimpInterop.aiMaterial_GetEmbeddedTextureDataSize(scene, intPtr, !isRawData);
					data = AssimpInterop.aiMaterial_GetEmbeddedTextureData(scene, intPtr, uintSize);
					width = AssimpInterop.aiMaterial_GetEmbeddedTextureWidth(intPtr);
					height = AssimpInterop.aiMaterial_GetEmbeddedTextureHeight(intPtr);
					finalPath = Path.GetFileNameWithoutExtension(path);
					return true;
				}
			}
			finalPath = null;
			data = new byte[0];
			isRawData = false;
			width = 0;
			height = 0;
			return false;
		}

		public static Texture2D ProccessTextureData(Texture2D tempTexture2D, string name, Material material, string propertyName, ref bool checkAlphaChannel, TextureWrapMode textureWrapMode = TextureWrapMode.Repeat, string finalPath = null, TextureLoadHandle onTextureLoaded = null, TextureCompression textureCompression = TextureCompression.None, bool isNormalMap = false)
		{
			if (tempTexture2D == null)
			{
				return null;
			}
			tempTexture2D.name = name;
			tempTexture2D.wrapMode = textureWrapMode;
			Color32[] pixels = tempTexture2D.GetPixels32();
			Texture2D texture2D;
			if (isNormalMap)
			{
				texture2D = new Texture2D(tempTexture2D.width, tempTexture2D.height, TextureFormat.ARGB32, true);
				for (int i = 0; i < pixels.Length; i++)
				{
					Color32 color = pixels[i];
					color.a = color.r;
					color.r = 0;
					color.b = 0;
					pixels[i] = color;
				}
				texture2D.SetPixels32(pixels);
				texture2D.Apply();
			}
			else
			{
				texture2D = new Texture2D(tempTexture2D.width, tempTexture2D.height, TextureFormat.ARGB32, true);
				texture2D.SetPixels32(pixels);
				texture2D.Apply();
				if (textureCompression != TextureCompression.None)
				{
					tempTexture2D.Compress(textureCompression == TextureCompression.HighQuality);
				}
			}
			if (checkAlphaChannel)
			{
				checkAlphaChannel = false;
				foreach (Color32 color2 in pixels)
				{
					if (color2.a != 255)
					{
						checkAlphaChannel = true;
						break;
					}
				}
			}
			if (material != null)
			{
				material.SetTexture(propertyName, texture2D);
			}
			if (onTextureLoaded != null)
			{
				onTextureLoaded(finalPath, material, propertyName, texture2D);
			}
			return texture2D;
		}

		public static Texture2D ScaleTexture(Texture2D source, int targetWidth, int targetHeight)
		{
			Texture2D texture2D = new Texture2D(targetWidth, targetHeight, source.format, true);
			Color[] pixels = texture2D.GetPixels(0);
			float num = 1f / (float)targetWidth;
			float num2 = 1f / (float)targetHeight;
			for (int i = 0; i < pixels.Length; i++)
			{
				pixels[i] = source.GetPixelBilinear(num * ((float)i % (float)targetWidth), num2 * Mathf.Floor((float)(i / targetWidth)));
			}
			texture2D.SetPixels(pixels, 0);
			texture2D.Apply();
			return texture2D;
		}

		public static bool IsPowerOfTwo(float number)
		{
			float f = Mathf.Log(number, 2f);
			float num = Mathf.Pow(2f, Mathf.Round(f));
			return num == number;
		}
	}
}
