using System;
using System.Text;
using QCRPG.Framework;

namespace QCRPG.TSL.FM.Packets;

public class IoControl : PacketBase
{
	public class UserFieldsWrapper
	{
		public enum MonoStereoSwitchEnum
		{
			DISABLE,
			ENABLE,
			InvalidMonoStereoSwitchValue
		}

		public static class MonoStereoSwitchInfo
		{
			public static MonoStereoSwitchEnum ValueToMonoStereoSwitch(uint value)
			{
				return value switch
				{
					0u => MonoStereoSwitchEnum.DISABLE, 
					1u => MonoStereoSwitchEnum.ENABLE, 
					_ => MonoStereoSwitchEnum.InvalidMonoStereoSwitchValue, 
				};
			}

			public static uint MonoStereoSwitchToValue(MonoStereoSwitchEnum enumItem)
			{
				return enumItem switch
				{
					MonoStereoSwitchEnum.DISABLE => 0u, 
					MonoStereoSwitchEnum.ENABLE => 1u, 
					_ => uint.MaxValue, 
				};
			}

			public static string MonoStereoSwitchToString(MonoStereoSwitchEnum enumItem)
			{
				return enumItem switch
				{
					MonoStereoSwitchEnum.DISABLE => "Disable mono-stereo switching future", 
					MonoStereoSwitchEnum.ENABLE => "Enable mono-stereo switching future", 
					_ => "Invalid MonoStereoSwitch Value", 
				};
			}

			public static string MonoStereoSwitchToDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("0x0 = Disable mono-stereo switching future");
				stringBuilder.AppendLine("0x1 = Enable mono-stereo switching future");
				return stringBuilder.ToString();
			}
		}

		public enum AntennaEnum
		{
			WIRED_HEADSET,
			PWB_ANTENNA,
			InvalidAntennaValue
		}

		public static class AntennaInfo
		{
			public static AntennaEnum ValueToAntenna(uint value)
			{
				return value switch
				{
					0u => AntennaEnum.WIRED_HEADSET, 
					1u => AntennaEnum.PWB_ANTENNA, 
					_ => AntennaEnum.InvalidAntennaValue, 
				};
			}

			public static uint AntennaToValue(AntennaEnum enumItem)
			{
				return enumItem switch
				{
					AntennaEnum.WIRED_HEADSET => 0u, 
					AntennaEnum.PWB_ANTENNA => 1u, 
					_ => uint.MaxValue, 
				};
			}

			public static string AntennaToString(AntennaEnum enumItem)
			{
				return enumItem switch
				{
					AntennaEnum.WIRED_HEADSET => "Wired headset", 
					AntennaEnum.PWB_ANTENNA => "PWB antenna", 
					_ => "Invalid Antenna Value", 
				};
			}

			public static string AntennaToDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("0x0 = Wired headset");
				stringBuilder.AppendLine("0x1 = PWB antenna");
				return stringBuilder.ToString();
			}
		}

		public enum InterferenceBlendingEnum
		{
			DISABLE,
			ENABLE,
			InvalidInterferenceBlendingValue
		}

		public static class InterferenceBlendingInfo
		{
			public static InterferenceBlendingEnum ValueToInterferenceBlending(uint value)
			{
				return value switch
				{
					0u => InterferenceBlendingEnum.DISABLE, 
					1u => InterferenceBlendingEnum.ENABLE, 
					_ => InterferenceBlendingEnum.InvalidInterferenceBlendingValue, 
				};
			}

			public static uint InterferenceBlendingToValue(InterferenceBlendingEnum enumItem)
			{
				return enumItem switch
				{
					InterferenceBlendingEnum.DISABLE => 0u, 
					InterferenceBlendingEnum.ENABLE => 1u, 
					_ => uint.MaxValue, 
				};
			}

			public static string InterferenceBlendingToString(InterferenceBlendingEnum enumItem)
			{
				return enumItem switch
				{
					InterferenceBlendingEnum.DISABLE => "Disable blending feature which varies with interference level", 
					InterferenceBlendingEnum.ENABLE => "Enable blending feature which varies with interference level", 
					_ => "Invalid InterferenceBlending Value", 
				};
			}

			public static string InterferenceBlendingToDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("0x0 = Disable blending feature which varies with interference level");
				stringBuilder.AppendLine("0x1 = Enable blending feature which varies with interference level");
				return stringBuilder.ToString();
			}
		}

		public enum SignalBlendingEnum
		{
			DISABLE,
			ENABLE,
			InvalidSignalBlendingValue
		}

		public static class SignalBlendingInfo
		{
			public static SignalBlendingEnum ValueToSignalBlending(uint value)
			{
				return value switch
				{
					0u => SignalBlendingEnum.DISABLE, 
					1u => SignalBlendingEnum.ENABLE, 
					_ => SignalBlendingEnum.InvalidSignalBlendingValue, 
				};
			}

			public static uint SignalBlendingToValue(SignalBlendingEnum enumItem)
			{
				return enumItem switch
				{
					SignalBlendingEnum.DISABLE => 0u, 
					SignalBlendingEnum.ENABLE => 1u, 
					_ => uint.MaxValue, 
				};
			}

			public static string SignalBlendingToString(SignalBlendingEnum enumItem)
			{
				return enumItem switch
				{
					SignalBlendingEnum.DISABLE => "Disable blending feature which varies with main signal strength", 
					SignalBlendingEnum.ENABLE => "Enable blending feature which varies with main signal strength", 
					_ => "Invalid SignalBlending Value", 
				};
			}

			public static string SignalBlendingToDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("0x0 = Disable blending feature which varies with main signal strength");
				stringBuilder.AppendLine("0x1 = Enable blending feature which varies with main signal strength");
				return stringBuilder.ToString();
			}
		}

		public enum MonoStereoModeEnum
		{
			AUTO_DECODE,
			FORCE_MONO,
			InvalidMonoStereoModeValue
		}

		public static class MonoStereoModeInfo
		{
			public static MonoStereoModeEnum ValueToMonoStereoMode(uint value)
			{
				return value switch
				{
					0u => MonoStereoModeEnum.AUTO_DECODE, 
					1u => MonoStereoModeEnum.FORCE_MONO, 
					_ => MonoStereoModeEnum.InvalidMonoStereoModeValue, 
				};
			}

			public static uint MonoStereoModeToValue(MonoStereoModeEnum enumItem)
			{
				return enumItem switch
				{
					MonoStereoModeEnum.AUTO_DECODE => 0u, 
					MonoStereoModeEnum.FORCE_MONO => 1u, 
					_ => uint.MaxValue, 
				};
			}

			public static string MonoStereoModeToString(MonoStereoModeEnum enumItem)
			{
				return enumItem switch
				{
					MonoStereoModeEnum.AUTO_DECODE => "Auto mono-stereo decode", 
					MonoStereoModeEnum.FORCE_MONO => "Force mono", 
					_ => "Invalid MonoStereoMode Value", 
				};
			}

			public static string MonoStereoModeToDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("0x0 = Auto mono-stereo decode");
				stringBuilder.AppendLine("0x1 = Force mono");
				return stringBuilder.ToString();
			}
		}

		public enum SoftMuteEnum
		{
			DISABLE,
			ENABLE,
			InvalidSoftMuteValue
		}

		public static class SoftMuteInfo
		{
			public static SoftMuteEnum ValueToSoftMute(uint value)
			{
				return value switch
				{
					0u => SoftMuteEnum.DISABLE, 
					1u => SoftMuteEnum.ENABLE, 
					_ => SoftMuteEnum.InvalidSoftMuteValue, 
				};
			}

			public static uint SoftMuteToValue(SoftMuteEnum enumItem)
			{
				return enumItem switch
				{
					SoftMuteEnum.DISABLE => 0u, 
					SoftMuteEnum.ENABLE => 1u, 
					_ => uint.MaxValue, 
				};
			}

			public static string SoftMuteToString(SoftMuteEnum enumItem)
			{
				return enumItem switch
				{
					SoftMuteEnum.DISABLE => "Soft mute disabled", 
					SoftMuteEnum.ENABLE => "Soft mute enabled", 
					_ => "Invalid SoftMute Value", 
				};
			}

			public static string SoftMuteToDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("0x0 = Soft mute disabled");
				stringBuilder.AppendLine("0x1 = Soft mute enabled");
				return stringBuilder.ToString();
			}
		}

		public enum HardMuteEnum
		{
			NO_HARD_MUTE,
			LEFT_CHANNEL_MUTED,
			RIGHT_CHANNEL_MUTED,
			BOTH_CHANNELS_MUTED,
			InvalidHardMuteValue
		}

		public static class HardMuteInfo
		{
			public static HardMuteEnum ValueToHardMute(uint value)
			{
				return value switch
				{
					0u => HardMuteEnum.NO_HARD_MUTE, 
					1u => HardMuteEnum.LEFT_CHANNEL_MUTED, 
					2u => HardMuteEnum.RIGHT_CHANNEL_MUTED, 
					3u => HardMuteEnum.BOTH_CHANNELS_MUTED, 
					_ => HardMuteEnum.InvalidHardMuteValue, 
				};
			}

			public static uint HardMuteToValue(HardMuteEnum enumItem)
			{
				return enumItem switch
				{
					HardMuteEnum.NO_HARD_MUTE => 0u, 
					HardMuteEnum.LEFT_CHANNEL_MUTED => 1u, 
					HardMuteEnum.RIGHT_CHANNEL_MUTED => 2u, 
					HardMuteEnum.BOTH_CHANNELS_MUTED => 3u, 
					_ => uint.MaxValue, 
				};
			}

			public static string HardMuteToString(HardMuteEnum enumItem)
			{
				return enumItem switch
				{
					HardMuteEnum.NO_HARD_MUTE => "No hard mute", 
					HardMuteEnum.LEFT_CHANNEL_MUTED => "Left channel hard muted", 
					HardMuteEnum.RIGHT_CHANNEL_MUTED => "Right channel hard muted", 
					HardMuteEnum.BOTH_CHANNELS_MUTED => "Left and right channels hard muted", 
					_ => "Invalid HardMute Value", 
				};
			}

			public static string HardMuteToDescription()
			{
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine("0x0 = No hard mute");
				stringBuilder.AppendLine("0x1 = Left channel hard muted");
				stringBuilder.AppendLine("0x2 = Right channel hard muted");
				stringBuilder.AppendLine("0x3 = Left and right channels hard muted");
				return stringBuilder.ToString();
			}
		}

		private const uint _RegisterAddress = 9u;

		private uint _MonoStereoSwitch;

		private uint _Antenna;

		private uint _InterferenceBlending;

		private uint _SignalBlending;

		private uint _MonoStereoMode;

		private uint _SoftMute;

		private uint _HardMute;

		public uint RegisterAddress => 9u;

		public uint MonoStereoSwitch
		{
			get
			{
				return _MonoStereoSwitch;
			}
			set
			{
				if (value > 1)
				{
					throw new Exception("Maximum possible value for MonoStereoSwitch is 0x1");
				}
				_MonoStereoSwitch = value;
			}
		}

		public uint Antenna
		{
			get
			{
				return _Antenna;
			}
			set
			{
				if (value > 1)
				{
					throw new Exception("Maximum possible value for Antenna is 0x1");
				}
				_Antenna = value;
			}
		}

		public uint InterferenceBlending
		{
			get
			{
				return _InterferenceBlending;
			}
			set
			{
				if (value > 1)
				{
					throw new Exception("Maximum possible value for InterferenceBlending is 0x1");
				}
				_InterferenceBlending = value;
			}
		}

		public uint SignalBlending
		{
			get
			{
				return _SignalBlending;
			}
			set
			{
				if (value > 1)
				{
					throw new Exception("Maximum possible value for SignalBlending is 0x1");
				}
				_SignalBlending = value;
			}
		}

		public uint MonoStereoMode
		{
			get
			{
				return _MonoStereoMode;
			}
			set
			{
				if (value > 1)
				{
					throw new Exception("Maximum possible value for MonoStereoMode is 0x1");
				}
				_MonoStereoMode = value;
			}
		}

		public uint SoftMute
		{
			get
			{
				return _SoftMute;
			}
			set
			{
				if (value > 1)
				{
					throw new Exception("Maximum possible value for SoftMute is 0x1");
				}
				_SoftMute = value;
			}
		}

		public uint HardMute
		{
			get
			{
				return _HardMute;
			}
			set
			{
				if (value > 3)
				{
					throw new Exception("Maximum possible value for HardMute is 0x3");
				}
				_HardMute = value;
			}
		}

		public RegisterMapEnum GetRegisterAddressAsRegisterMapEnum()
		{
			return RegisterMapInfo.ValueToRegisterMap(9u);
		}

		public MonoStereoSwitchEnum GetMonoStereoSwitchAsMonoStereoSwitchEnum()
		{
			return MonoStereoSwitchInfo.ValueToMonoStereoSwitch(_MonoStereoSwitch);
		}

		public void SetMonoStereoSwitchAsMonoStereoSwitchEnum(MonoStereoSwitchEnum enumItem)
		{
			MonoStereoSwitch = MonoStereoSwitchInfo.MonoStereoSwitchToValue(enumItem);
		}

		public AntennaEnum GetAntennaAsAntennaEnum()
		{
			return AntennaInfo.ValueToAntenna(_Antenna);
		}

		public void SetAntennaAsAntennaEnum(AntennaEnum enumItem)
		{
			Antenna = AntennaInfo.AntennaToValue(enumItem);
		}

		public InterferenceBlendingEnum GetInterferenceBlendingAsInterferenceBlendingEnum()
		{
			return InterferenceBlendingInfo.ValueToInterferenceBlending(_InterferenceBlending);
		}

		public void SetInterferenceBlendingAsInterferenceBlendingEnum(InterferenceBlendingEnum enumItem)
		{
			InterferenceBlending = InterferenceBlendingInfo.InterferenceBlendingToValue(enumItem);
		}

		public SignalBlendingEnum GetSignalBlendingAsSignalBlendingEnum()
		{
			return SignalBlendingInfo.ValueToSignalBlending(_SignalBlending);
		}

		public void SetSignalBlendingAsSignalBlendingEnum(SignalBlendingEnum enumItem)
		{
			SignalBlending = SignalBlendingInfo.SignalBlendingToValue(enumItem);
		}

		public MonoStereoModeEnum GetMonoStereoModeAsMonoStereoModeEnum()
		{
			return MonoStereoModeInfo.ValueToMonoStereoMode(_MonoStereoMode);
		}

		public void SetMonoStereoModeAsMonoStereoModeEnum(MonoStereoModeEnum enumItem)
		{
			MonoStereoMode = MonoStereoModeInfo.MonoStereoModeToValue(enumItem);
		}

		public SoftMuteEnum GetSoftMuteAsSoftMuteEnum()
		{
			return SoftMuteInfo.ValueToSoftMute(_SoftMute);
		}

		public void SetSoftMuteAsSoftMuteEnum(SoftMuteEnum enumItem)
		{
			SoftMute = SoftMuteInfo.SoftMuteToValue(enumItem);
		}

		public HardMuteEnum GetHardMuteAsHardMuteEnum()
		{
			return HardMuteInfo.ValueToHardMute(_HardMute);
		}

		public void SetHardMuteAsHardMuteEnum(HardMuteEnum enumItem)
		{
			HardMute = HardMuteInfo.HardMuteToValue(enumItem);
		}
	}

	private Type[] expectedResponseTypes = new Type[0];

	private PacketInfoBase info;

	public UserFieldsWrapper _UserFields = new UserFieldsWrapper();

	public override PacketType Type => PacketType.Command;

	public override Type[] ExpectedResponseTypes => expectedResponseTypes;

	public override PacketInfoBase Info
	{
		get
		{
			if (info == null)
			{
				info = new IoControlInfo(this);
			}
			return info;
		}
	}

	public UserFieldsWrapper UserFields => _UserFields;

	protected override bool FromBitBuilder(ref BitBuilder bitBuilder)
	{
		if (bitBuilder.RemoveBitsAsUint(8) != UserFields.RegisterAddress)
		{
			return false;
		}
		UserFields.MonoStereoSwitch = bitBuilder.RemoveBitsAsUint(1);
		UserFields.Antenna = bitBuilder.RemoveBitsAsUint(1);
		UserFields.InterferenceBlending = bitBuilder.RemoveBitsAsUint(1);
		UserFields.SignalBlending = bitBuilder.RemoveBitsAsUint(1);
		UserFields.MonoStereoMode = bitBuilder.RemoveBitsAsUint(1);
		UserFields.SoftMute = bitBuilder.RemoveBitsAsUint(1);
		UserFields.HardMute = bitBuilder.RemoveBitsAsUint(2);
		if (bitBuilder.GetNumberOfBits() > 7)
		{
			return false;
		}
		return true;
	}

	public override string ToBitString()
	{
		BitBuilder bitBuilder = new BitBuilder();
		bitBuilder.AddBitsAsUint(UserFields.RegisterAddress, 8);
		bitBuilder.AddBitsAsUint(UserFields.MonoStereoSwitch, 1);
		bitBuilder.AddBitsAsUint(UserFields.Antenna, 1);
		bitBuilder.AddBitsAsUint(UserFields.InterferenceBlending, 1);
		bitBuilder.AddBitsAsUint(UserFields.SignalBlending, 1);
		bitBuilder.AddBitsAsUint(UserFields.MonoStereoMode, 1);
		bitBuilder.AddBitsAsUint(UserFields.SoftMute, 1);
		bitBuilder.AddBitsAsUint(UserFields.HardMute, 2);
		return bitBuilder.ToString();
	}
}
