using System;
using System.Collections.Generic;
using QCRPG.Framework;

namespace QCRPG.TSL.FM.Packets;

public class ReadRdsAlternativeFrequencyResponse : PacketBase
{
	public class UserFieldsWrapper
	{
		private uint _Undefined1;

		private uint _FrequencyRelativeToBand;

		private uint _ProgramIdentification;

		private uint _NumberOfAlternateFrequencies;

		private List<AlternateFrequencyListSubField> _AlternateFrequencyListList = new List<AlternateFrequencyListSubField>();

		public uint Undefined1
		{
			get
			{
				return _Undefined1;
			}
			set
			{
				if (value > 127)
				{
					throw new Exception("Maximum possible value for Undefined1 is 0x7F");
				}
				_Undefined1 = value;
			}
		}

		public uint FrequencyRelativeToBand
		{
			get
			{
				return _FrequencyRelativeToBand;
			}
			set
			{
				if (value > 511)
				{
					throw new Exception("Maximum possible value for FrequencyRelativeToBand is 0x1FF");
				}
				_FrequencyRelativeToBand = value;
			}
		}

		public uint ProgramIdentification
		{
			get
			{
				return _ProgramIdentification;
			}
			set
			{
				if (value > 65535)
				{
					throw new Exception("Maximum possible value for ProgramIdentification is 0xFFFF");
				}
				_ProgramIdentification = value;
			}
		}

		public uint NumberOfAlternateFrequencies
		{
			get
			{
				return _NumberOfAlternateFrequencies;
			}
			set
			{
				if (value > 255)
				{
					throw new Exception("Maximum possible value for NumberOfAlternateFrequencies is 0xFF");
				}
				_NumberOfAlternateFrequencies = value;
				while (_AlternateFrequencyListList.Count < _NumberOfAlternateFrequencies)
				{
					_AlternateFrequencyListList.Add(new AlternateFrequencyListSubField());
				}
				while (_AlternateFrequencyListList.Count > _NumberOfAlternateFrequencies)
				{
					_AlternateFrequencyListList.RemoveAt(_AlternateFrequencyListList.Count - 1);
				}
			}
		}

		public List<AlternateFrequencyListSubField> AlternateFrequencyListList => _AlternateFrequencyListList;
	}

	public class AlternateFrequencyListSubField
	{
		private uint _AlternateFrequencyCode;

		public uint AlternateFrequencyCode
		{
			get
			{
				return _AlternateFrequencyCode;
			}
			set
			{
				if (value > 255)
				{
					throw new Exception("Maximum possible value for AlternateFrequencyCode is 0xFF");
				}
				_AlternateFrequencyCode = value;
			}
		}

		public bool FromBitBuilder(ref BitBuilder bitBuilder)
		{
			AlternateFrequencyCode = bitBuilder.RemoveBitsAsUint(8);
			return true;
		}

		public string ToBitString()
		{
			BitBuilder bitBuilder = new BitBuilder();
			bitBuilder.AddBitsAsUint(AlternateFrequencyCode, 8);
			return bitBuilder.ToString();
		}
	}

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

	private PacketInfoBase info;

	public UserFieldsWrapper _UserFields = new UserFieldsWrapper();

	public override PacketType Type => PacketType.Response;

	public override Type[] ExpectedResponseTypes => expectedResponseTypes;

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

	public UserFieldsWrapper UserFields => _UserFields;

	protected override bool FromBitBuilder(ref BitBuilder bitBuilder)
	{
		UserFields.Undefined1 = bitBuilder.RemoveBitsAsUint(7);
		UserFields.FrequencyRelativeToBand = bitBuilder.RemoveBitsAsUint(9);
		UserFields.ProgramIdentification = bitBuilder.RemoveBitsAsUint(16);
		UserFields.NumberOfAlternateFrequencies = bitBuilder.RemoveBitsAsUint(8);
		for (int i = 0; i < UserFields.AlternateFrequencyListList.Count; i++)
		{
			UserFields.AlternateFrequencyListList[i].FromBitBuilder(ref bitBuilder);
		}
		if (bitBuilder.GetNumberOfBits() > 7)
		{
			return false;
		}
		return true;
	}

	public override string ToBitString()
	{
		BitBuilder bitBuilder = new BitBuilder();
		bitBuilder.AddBitsAsUint(UserFields.Undefined1, 7);
		bitBuilder.AddBitsAsUint(UserFields.FrequencyRelativeToBand, 9);
		bitBuilder.AddBitsAsUint(UserFields.ProgramIdentification, 16);
		bitBuilder.AddBitsAsUint(UserFields.NumberOfAlternateFrequencies, 8);
		for (int i = 0; i < UserFields.AlternateFrequencyListList.Count; i++)
		{
			bitBuilder.AddBitsAsString(UserFields.AlternateFrequencyListList[i].ToBitString());
		}
		return bitBuilder.ToString();
	}

	public override List<string> GetWarnings()
	{
		List<string> list = new List<string>();
		if (UserFields.NumberOfAlternateFrequencies > 25)
		{
			list.Add("Maximum allowed value for Number Of Alternate Frequencies is 0x19");
		}
		return list;
	}
}
