using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;

namespace Crysome.Client.Util;

internal static class ShellSmallIconPng
{
	private struct SHFILEINFO
	{
		public IntPtr hIcon;

		public int iIcon;

		public uint dwAttributes;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
		public string szDisplayName;

		[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
		public string szTypeName;
	}

	private const uint SHGFI_ICON = 256u;

	private const uint SHGFI_SMALLICON = 1u;

	private const uint SHGFI_USEFILEATTRIBUTES = 16u;

	private const uint FILE_ATTRIBUTE_DIRECTORY = 16u;

	[DllImport("shell32.dll", CharSet = CharSet.Auto)]
	private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, ref SHFILEINFO psfi, uint cbFileInfo, uint uFlags);

	[DllImport("user32.dll", CharSet = CharSet.Auto)]
	private static extern bool DestroyIcon(IntPtr hIcon);

	public static byte[] TryGetPng(string fullPath, bool isDirectory)
	{
		if (string.IsNullOrEmpty(fullPath))
		{
			return null;
		}
		try
		{
			if (!isDirectory && File.Exists(fullPath))
			{
				using (Icon icon = Icon.ExtractAssociatedIcon(fullPath))
				{
					if (icon == null)
					{
						return null;
					}
					return IconToPng(icon);
				}
			}
			SHFILEINFO psfi = default(SHFILEINFO);
			uint dwFileAttributes = (isDirectory ? 16u : 0u);
			if (SHGetFileInfo(fullPath, dwFileAttributes, ref psfi, (uint)Marshal.SizeOf<SHFILEINFO>(), 273u) == IntPtr.Zero || psfi.hIcon == IntPtr.Zero)
			{
				return null;
			}
			IntPtr hIcon = psfi.hIcon;
			try
			{
				using Icon icon2 = Icon.FromHandle(hIcon);
				using Icon ico = (Icon)icon2.Clone();
				return IconToPng(ico);
			}
			finally
			{
				DestroyIcon(hIcon);
			}
		}
		catch
		{
			return null;
		}
	}

	private static byte[] IconToPng(Icon ico)
	{
		using Bitmap bitmap = ico.ToBitmap();
		using MemoryStream memoryStream = new MemoryStream();
		bitmap.Save(memoryStream, ImageFormat.Png);
		return memoryStream.ToArray();
	}
}
