using System;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using DebugToolInstrumentInterface;
using QC.QMSLPhone;
using Qualcomm_ModemRFA;

namespace QFDT_Components;

public partial class FTM_GSM_RF : UserControl, IComponentConnector
{
	public delegate void SendDebugMessage(MessageLevel level, string message);

	private enum Chain
	{
		C0,
		C2,
		C4
	}

	public enum BandChain
	{
		GSM_850,
		GSM_900,
		DCS_1800,
		PCS_1900,
		C2_GSM_850,
		C2_GSM_900,
		C2_DCS_1800,
		C2_PCS_1900,
		C4_GSM_850,
		C4_GSM_900,
		C4_DCS_1800,
		C4_PCS_1900
	}

	public delegate void SetComponentAttributeCB<T, T2>(T set_component, SetAttribute attr, T2 value);

	public delegate string GetTextBoxValueCB();

	public delegate int? GetComboBoxSelectedIndexCB();

	public SendDebugMessage DebugMessageCB;

	public Phone phone;

	public ISignalGenerator pSG;

	public ISpectrumAnalyzer pSA;

	private GSM_Bands selectedBand = GSM_Bands.GSM_Band_Cell_850;

	private Chain selectedChain;

	public bool bContinuousFlag;

	private Thread thread;

	private ushort? m_channel = null;

	private double? m_DLLevel = null;

	public void Register_DebugMessageCB(SendDebugMessage me)
	{
		DebugMessageCB = me;
	}

	public FTM_GSM_RF()
	{
		InitializeComponent();
	}

	private FTM_Mode_Id_Enum getModeIDFromChain(Chain chain)
	{
		return chain switch
		{
			Chain.C0 => FTM_Mode_Id_Enum.FTM_MODE_ID_GSM, 
			Chain.C2 => FTM_Mode_Id_Enum.FTM_MODE_ID_GSM_C2, 
			_ => FTM_Mode_Id_Enum.FTM_MODE_ID_GSM_C4, 
		};
	}

	private void GSM_C0_Tx_On_Click(object sender, RoutedEventArgs e)
	{
		if (GSM_C0_Mode.SelectedIndex == -1)
		{
			DebugMessageCB(MessageLevel.FAIL, base.Resources["SelectTx"].ToString());
		}
		else if (phone != null)
		{
			phone.FTM_SET_MODE_ID(getModeIDFromChain(selectedChain));
			phone.FTM_SET_MODE(selectedBand);
			phone.FTM_SET_CHAN(Convert.ToUInt16(Channel.Text));
			phone.Set_Tranmit_Burst(0, Modulation_Data_Source.FTM_GSM_TX_DATA_SOURCE_PSDRND, 0, 0uL, IsInfiniteDuration.Count_bursts);
			phone.FTM_SET_TX_ON();
			phone.FTM_SET_GSM_LINEAR_PA_RANGE(0, Convert.ToUInt16(Range.Text));
			phone.FTM_GSM_SET_LINEAR_RGI(0, Convert.ToUInt16(RGI.Text), 1);
			phone.Set_Transmit_Cont(0, Modulation_Data_Source.FTM_GSM_TX_DATA_SOURCE_PSDRND, 0, 0uL, IsInfiniteDuration.Count_bursts);
			DebugMessageCB(MessageLevel.SUCCESS, string.Concat(base.Resources["SetTXon"].ToString(), " ", selectedChain.ToString(), " ", base.Resources["Band"].ToString(), ": ", selectedBand.ToString(), base.Resources["Channel"], ": ", Channel.Text));
			if (pSA != null)
			{
				double centerFrequency = phone.Band_Helper_CalculateULFrequency((ushort)CalV4Parser.ModeIDToQMSLBandHelperBandClass((int)selectedBand), Convert.ToUInt16(Channel.Text));
				pSA.SetupMeasurement(Technology.GSM);
				pSA.SetCenterFrequency(centerFrequency);
				pSA.SetSpan(10.0);
				pSA.SetReferenceLevel(25.0);
				GSM_Power.Text = pSA.GetPower();
			}
		}
	}

	private void GSM_C0_Mode_SelectionChanged(object sender, SelectionChangedEventArgs e)
	{
		ComboBox comboBox = (ComboBox)sender;
		if (comboBox != null && comboBox.SelectedValue != null)
		{
			if (comboBox.SelectedValue.ToString() == BandChain.GSM_850.ToString())
			{
				selectedBand = GSM_Bands.GSM_Band_Cell_850;
				selectedChain = Chain.C0;
				Channel.Text = "190";
			}
			else if (comboBox.SelectedValue.ToString() == BandChain.GSM_900.ToString())
			{
				selectedBand = GSM_Bands.GSM_Band_EGSM_900;
				selectedChain = Chain.C0;
				Channel.Text = "37";
			}
			else if (comboBox.SelectedValue.ToString() == BandChain.DCS_1800.ToString())
			{
				selectedBand = GSM_Bands.GSM_Band_DCS_1800;
				selectedChain = Chain.C0;
				Channel.Text = "700";
			}
			else if (comboBox.SelectedValue.ToString() == BandChain.PCS_1900.ToString())
			{
				selectedBand = GSM_Bands.GSM_Band_PCS_1900;
				selectedChain = Chain.C0;
				Channel.Text = "661";
			}
			else if (comboBox.SelectedValue.ToString() == BandChain.C2_GSM_850.ToString())
			{
				selectedBand = GSM_Bands.GSM_Band_Cell_850;
				selectedChain = Chain.C2;
				Channel.Text = "190";
			}
			else if (comboBox.SelectedValue.ToString() == BandChain.C2_GSM_900.ToString())
			{
				selectedBand = GSM_Bands.GSM_Band_EGSM_900;
				selectedChain = Chain.C2;
				Channel.Text = "37";
			}
			else if (comboBox.SelectedValue.ToString() == BandChain.C2_DCS_1800.ToString())
			{
				selectedBand = GSM_Bands.GSM_Band_DCS_1800;
				selectedChain = Chain.C2;
				Channel.Text = "700";
			}
			else if (comboBox.SelectedValue.ToString() == BandChain.C2_PCS_1900.ToString())
			{
				selectedBand = GSM_Bands.GSM_Band_PCS_1900;
				selectedChain = Chain.C2;
				Channel.Text = "661";
			}
			else if (comboBox.SelectedValue.ToString() == BandChain.C4_GSM_850.ToString())
			{
				selectedBand = GSM_Bands.GSM_Band_Cell_850;
				selectedChain = Chain.C4;
				Channel.Text = "190";
			}
			else if (comboBox.SelectedValue.ToString() == BandChain.C4_GSM_900.ToString())
			{
				selectedBand = GSM_Bands.GSM_Band_EGSM_900;
				selectedChain = Chain.C4;
				Channel.Text = "37";
			}
			else if (comboBox.SelectedValue.ToString() == BandChain.C4_DCS_1800.ToString())
			{
				selectedBand = GSM_Bands.GSM_Band_DCS_1800;
				selectedChain = Chain.C4;
				Channel.Text = "700";
			}
			else if (comboBox.SelectedValue.ToString() == BandChain.C4_PCS_1900.ToString())
			{
				selectedBand = GSM_Bands.GSM_Band_PCS_1900;
				selectedChain = Chain.C4;
				Channel.Text = "661";
			}
		}
	}

	private void ClearAllTextBoxesRelatedToBand()
	{
		Channel.Text = "";
		Tx.Text = "";
		Rx.Text = "";
	}

	private ulong get_Cn_bc_configValue(nv_items_enum_type nvIndex, bool bRFNVRead)
	{
		if (phone != null)
		{
			byte[] array = new byte[8];
			ushort iDataSz = 8;
			ushort iFTM_Error_Code = 0;
			ulong result = 0uL;
			try
			{
				if (bRFNVRead)
				{
					phone.QLIB_FTM_RFNV_READ((ushort)nvIndex, array, ref iDataSz, ref iFTM_Error_Code);
				}
				else
				{
					phone.NVRead((ushort)nvIndex, array, 8);
				}
				result = BitConverter.ToUInt64(array, 0);
			}
			catch (PhoneException ex)
			{
				DebugMessageCB(MessageLevel.EXCEPTION, "PhoneException " + ex.Message);
			}
			return result;
		}
		return 0uL;
	}

	public void SetupUI()
	{
		if (phone != null)
		{
			ulong num = get_Cn_bc_configValue(nv_items_enum_type.NV_RF_BC_CONFIG_I, bRFNVRead: false);
			phone.StartLogging("c:\\temp\\debug.txt");
			ulong num2 = get_Cn_bc_configValue(nv_items_enum_type.RFNV_RF_BC_CONFIG_C2_I, bRFNVRead: true);
			ulong num3 = get_Cn_bc_configValue(nv_items_enum_type.RFNV_RF_BC_CONFIG_C4_I, bRFNVRead: true);
			phone.StopLogging();
			ClearAllTextBoxesRelatedToBand();
			GSM_C0_Mode.Items.Clear();
			if ((num & 0x80000) == 524288)
			{
				GSM_C0_Mode.Items.Add(BandChain.GSM_850);
			}
			if ((num & 0x100) == 256)
			{
				GSM_C0_Mode.Items.Add(BandChain.GSM_900);
			}
			if ((num & 0x80) == 128)
			{
				GSM_C0_Mode.Items.Add(BandChain.DCS_1800);
			}
			if ((num & 0x200000) == 2097152)
			{
				GSM_C0_Mode.Items.Add(BandChain.PCS_1900);
			}
			if ((num2 & 0x80000) == 524288)
			{
				GSM_C0_Mode.Items.Add(BandChain.C2_GSM_850);
			}
			if ((num2 & 0x100) == 256)
			{
				GSM_C0_Mode.Items.Add(BandChain.C2_GSM_900);
			}
			if ((num2 & 0x80) == 128)
			{
				GSM_C0_Mode.Items.Add(BandChain.C2_DCS_1800);
			}
			if ((num2 & 0x200000) == 2097152)
			{
				GSM_C0_Mode.Items.Add(BandChain.C2_PCS_1900);
			}
			if ((num3 & 0x80000) == 524288)
			{
				GSM_C0_Mode.Items.Add(BandChain.C4_GSM_850);
			}
			if ((num3 & 0x100) == 256)
			{
				GSM_C0_Mode.Items.Add(BandChain.C4_GSM_900);
			}
			if ((num3 & 0x80) == 128)
			{
				GSM_C0_Mode.Items.Add(BandChain.C4_DCS_1800);
			}
			if ((num3 & 0x200000) == 2097152)
			{
				GSM_C0_Mode.Items.Add(BandChain.C4_PCS_1900);
			}
		}
		LoadExtraSettings();
	}

	public void LoadExtraSettings()
	{
		if (pSA != null)
		{
			if (pSA.IsGetPowerSupported())
			{
				PowerMeas.Visibility = Visibility.Visible;
				GSM_Power.Visibility = Visibility.Visible;
			}
			else
			{
				PowerMeas.Visibility = Visibility.Collapsed;
				GSM_Power.Visibility = Visibility.Collapsed;
			}
		}
	}

	public void SetCompAttr<T>(T component, SetAttribute attr, string text)
	{
		if (component is TextBox)
		{
			TextBox textBox = component as TextBox;
			if (textBox.Dispatcher.CheckAccess())
			{
				if (attr == SetAttribute.Text)
				{
					textBox.Text = text;
				}
			}
			else
			{
				SetComponentAttributeCB<T, string> method = SetCompAttr;
				base.Dispatcher.BeginInvoke(method, component, attr, text);
			}
		}
		else
		{
			if (!(component is Label))
			{
				return;
			}
			Label label = component as Label;
			if (label.Dispatcher.CheckAccess())
			{
				if (attr == SetAttribute.Text)
				{
					label.Content = text;
				}
			}
			else
			{
				SetComponentAttributeCB<T, string> method2 = SetCompAttr;
				base.Dispatcher.BeginInvoke(method2, component, attr, text);
			}
		}
	}

	public void SetCompAttr<T>(T component, SetAttribute attr, bool bEnable)
	{
		if (!(component is Control))
		{
			return;
		}
		Control control = component as Control;
		if (control.Dispatcher.CheckAccess())
		{
			switch (attr)
			{
			case SetAttribute.IsEnable:
				control.IsEnabled = bEnable;
				break;
			case SetAttribute.Visibility:
				if (bEnable)
				{
					control.Visibility = Visibility.Visible;
				}
				else
				{
					control.Visibility = Visibility.Collapsed;
				}
				break;
			}
		}
		else
		{
			SetComponentAttributeCB<T, bool> method = SetCompAttr;
			base.Dispatcher.BeginInvoke(method, component, attr, bEnable);
		}
	}

	private void ContRxOn_Click(object sender, RoutedEventArgs e)
	{
		if (GSM_C0_Mode.SelectedIndex != -1)
		{
			bContinuousFlag = true;
			m_DLLevel = null;
			m_channel = null;
			if (ushort.TryParse(Channel.Text, out var result))
			{
				m_channel = result;
			}
			if (double.TryParse(DLLevel.Text, out var result2))
			{
				m_DLLevel = result2;
			}
			if (m_channel.HasValue && m_DLLevel.HasValue)
			{
				SetCompAttr(DL_Change, SetAttribute.IsEnable, bEnable: false);
				SetCompAttr(DLLevel, SetAttribute.IsEnable, bEnable: false);
				SetCompAttr(GSM_C0_Tx_Off, SetAttribute.IsEnable, bEnable: false);
				SetCompAttr(btContRxOn, SetAttribute.IsEnable, bEnable: false);
				SetCompAttr(btContRxOff, SetAttribute.IsEnable, bEnable: true);
				SetCompAttr(btContRxOn, SetAttribute.Visibility, bEnable: false);
				SetCompAttr(btContRxOff, SetAttribute.Visibility, bEnable: true);
				thread = new Thread(GSM_Rx_Continuous_Measure);
				thread.Name = "Meas Rx";
				thread.Start();
			}
		}
	}

	private void ContRxStop_Click(object sender, RoutedEventArgs e)
	{
		bContinuousFlag = false;
	}

	private double GetPowerFromRSSI(uint RSSI)
	{
		double num = 10.0 * Math.Log(RSSI, 10.0);
		return num - 116.0;
	}

	public string GetDLLevelText()
	{
		string text = null;
		if (DLLevel.Dispatcher.CheckAccess())
		{
			return DLLevel.Text;
		}
		GetTextBoxValueCB method = GetDLLevelText;
		return (string)base.Dispatcher.Invoke(method);
	}

	public int? GetDLChangeSelectedIndex()
	{
		int? result = null;
		if (DL_Change.Dispatcher.CheckAccess())
		{
			if (DL_Change.SelectedItem != null)
			{
				result = DL_Change.SelectedIndex;
			}
			return result;
		}
		GetComboBoxSelectedIndexCB method = GetDLChangeSelectedIndex;
		return (int?)base.Dispatcher.Invoke(method);
	}

	private double? GetDLPower()
	{
		double? result = null;
		if (double.TryParse(GetDLLevelText(), out var result2))
		{
			result = result2;
		}
		return result;
	}

	private void GSM_Rx_Continuous_Measure()
	{
		SetCompAttr(txtContRxValue, SetAttribute.Text, "");
		if (phone != null)
		{
			try
			{
				phone.FTM_SET_MODE_ID(getModeIDFromChain(selectedChain));
				phone.FTM_SET_MODE(selectedBand);
				phone.FTM_SET_CHAN(m_channel.Value);
				if (pSG != null)
				{
					uint iChannel = phone.Band_Helper_CalculateDLChannel((ushort)CalV4Parser.ModeIDToQMSLBandHelperBandClass((int)selectedBand), m_channel.Value);
					double dFrequencyInMHz = phone.Band_Helper_CalculateDLFrequency((ushort)CalV4Parser.ModeIDToQMSLBandHelperBandClass((int)selectedBand), iChannel);
					pSG.SetCenterFrequency(dFrequencyInMHz, 0.0);
					pSG.EnableOutput(onOff: true);
					pSG.SetPowerLevel(m_DLLevel.Value);
					Thread.Sleep(500);
					phone.FTM_SET_RX_CONTINUOUS(0, 0);
					phone.FTM_SET_LNA_RANGE(0);
					Thread.Sleep(200);
					while (bContinuousFlag)
					{
						uint piRssiValue = 0u;
						uint piRssiValue2 = 0u;
						double? dLPower = GetDLPower();
						if (dLPower.HasValue)
						{
							pSG.EnableOutput(onOff: true);
							double? num = null;
							int? dLChangeSelectedIndex = GetDLChangeSelectedIndex();
							int? num2 = dLChangeSelectedIndex;
							num = ((num2.GetValueOrDefault() == 0 && num2.HasValue) ? new double?(dLPower.Value - 3.0) : ((dLChangeSelectedIndex == 1) ? new double?(dLPower.Value - 6.0) : ((dLChangeSelectedIndex != 2) ? (dLPower - 3.0) : null)));
							pSG.SetPowerLevel(dLPower.Value);
							Thread.Sleep(400);
							phone.FTM_GET_RSSI(ref piRssiValue);
							Thread.Sleep(100);
							if (num.HasValue)
							{
								pSG.SetPowerLevel(num.Value);
							}
							else
							{
								pSG.EnableOutput(onOff: false);
							}
							Thread.Sleep(400);
							phone.FTM_GET_RSSI(ref piRssiValue2);
							double num3 = Math.Log(piRssiValue, 10.0);
							double num4 = Math.Log(piRssiValue2, 10.0);
							double num5 = (num4 - num3) * 10.0;
							DebugMessageCB(MessageLevel.SUCCESS, base.Resources["Changeis"].ToString() + " " + $"{num5:0.##}" + " dB");
							SetCompAttr(txtContRxValue, SetAttribute.Text, num5.ToString("0.00"));
							Thread.Sleep(100);
						}
						else
						{
							DebugMessageCB(MessageLevel.EXCEPTION, "Incorrect DL level input");
						}
					}
					pSG.EnableOutput(onOff: false);
				}
			}
			catch (PhoneException ex)
			{
				DebugMessageCB(MessageLevel.EXCEPTION, "PhoneException " + ex.Message);
			}
			catch (Exception ex2)
			{
				DebugMessageCB(MessageLevel.EXCEPTION, "Unkonwn Exception " + ex2.Message);
			}
		}
		SetCompAttr(DL_Change, SetAttribute.IsEnable, bEnable: true);
		SetCompAttr(DLLevel, SetAttribute.IsEnable, bEnable: true);
		SetCompAttr(GSM_C0_Tx_Off, SetAttribute.IsEnable, bEnable: true);
		SetCompAttr(btContRxOn, SetAttribute.IsEnable, bEnable: true);
		SetCompAttr(btContRxOff, SetAttribute.IsEnable, bEnable: false);
		SetCompAttr(btContRxOn, SetAttribute.Visibility, bEnable: true);
		SetCompAttr(btContRxOff, SetAttribute.Visibility, bEnable: false);
	}

	private void GSM_C0_Tx_Off_Click(object sender, RoutedEventArgs e)
	{
		if (GSM_C0_Mode.SelectedIndex == -1 || phone == null)
		{
			return;
		}
		phone.FTM_SET_MODE_ID(getModeIDFromChain(selectedChain));
		phone.FTM_SET_MODE(selectedBand);
		phone.FTM_SET_CHAN(Convert.ToUInt16(Channel.Text));
		if (pSG == null)
		{
			return;
		}
		uint iChannel = phone.Band_Helper_CalculateDLChannel((ushort)CalV4Parser.ModeIDToQMSLBandHelperBandClass((int)selectedBand), Convert.ToUInt16(Channel.Text));
		double dFrequencyInMHz = phone.Band_Helper_CalculateDLFrequency((ushort)CalV4Parser.ModeIDToQMSLBandHelperBandClass((int)selectedBand), iChannel);
		try
		{
			pSG.SetCenterFrequency(dFrequencyInMHz, 0.0);
			pSG.EnableOutput(onOff: true);
			pSG.SetPowerLevel(Convert.ToDouble(DLLevel.Text));
			Thread.Sleep(500);
			phone.FTM_SET_RX_CONTINUOUS(0, 0);
			phone.FTM_SET_LNA_RANGE(0);
			Thread.Sleep(200);
			uint piRssiValue = 0u;
			phone.FTM_GET_RSSI(ref piRssiValue);
			if (pSG != null)
			{
				if (DL_Change.SelectedIndex == 0)
				{
					pSG.SetPowerLevel(Convert.ToDouble(DLLevel.Text) - 3.0);
				}
				else if (DL_Change.SelectedIndex == 1)
				{
					pSG.SetPowerLevel(Convert.ToDouble(DLLevel.Text) - 6.0);
				}
				else if (DL_Change.SelectedIndex == 2)
				{
					pSG.EnableOutput(onOff: false);
				}
				else
				{
					pSG.SetPowerLevel(Convert.ToDouble(DLLevel.Text) - 3.0);
				}
			}
			Thread.Sleep(200);
			uint piRssiValue2 = 0u;
			phone.FTM_GET_RSSI(ref piRssiValue2);
			double num = Math.Log(piRssiValue, 10.0);
			double num2 = Math.Log(piRssiValue2, 10.0);
			double num3 = (num2 - num) * 10.0;
			pSG.EnableOutput(onOff: false);
			DebugMessageCB(MessageLevel.SUCCESS, base.Resources["Changeis"].ToString() + " " + $"{num3:0.##}" + " dB");
		}
		catch (PhoneException ex)
		{
			DebugMessageCB(MessageLevel.EXCEPTION, "PhoneException " + ex.Message);
		}
	}

	private void ChannelValueChanged(object sender, TextChangedEventArgs e)
	{
		if (Channel.Text.Length > 0 && phone != null)
		{
			double num = phone.Band_Helper_CalculateULFrequency((ushort)CalV4Parser.ModeIDToQMSLBandHelperBandClass((int)selectedBand), Convert.ToUInt16(Channel.Text));
			uint iChannel = phone.Band_Helper_CalculateDLChannel((ushort)CalV4Parser.ModeIDToQMSLBandHelperBandClass((int)selectedBand), Convert.ToUInt16(Channel.Text));
			double num2 = phone.Band_Helper_CalculateDLFrequency((ushort)CalV4Parser.ModeIDToQMSLBandHelperBandClass((int)selectedBand), iChannel);
			Tx.Text = num + " MHz";
			Rx.Text = num2 + " MHz";
		}
	}

	public void FTM_GSM_RF_Unload(object sender, RoutedEventArgs e)
	{
		bContinuousFlag = false;
	}

	private void TxOff_Click(object sender, RoutedEventArgs e)
	{
		if (GSM_C0_Mode.SelectedIndex == -1 || phone == null)
		{
			return;
		}
		try
		{
			phone.FTM_SET_MODE_ID(getModeIDFromChain(selectedChain));
			phone.FTM_SET_MODE(selectedBand);
			phone.FTM_SET_CHAN(Convert.ToUInt16(Channel.Text));
			phone.FTM_SET_TX_OFF();
			DebugMessageCB(MessageLevel.SUCCESS, base.Resources["SetTXoff"].ToString() + " " + selectedChain.ToString() + " " + base.Resources["Band"].ToString() + ": " + selectedBand.ToString() + base.Resources["Channel"].ToString() + ": " + Channel.Text);
		}
		catch (PhoneException ex)
		{
			DebugMessageCB(MessageLevel.EXCEPTION, "PhoneException " + ex.Message);
		}
	}

	public void SetLanguage(string culture)
	{
		ResourceDictionary resourceDictionary = new ResourceDictionary();
		try
		{
			resourceDictionary.Source = new Uri(Thread.GetDomain().BaseDirectory + "\\Resources\\UI_" + culture + ".xaml", UriKind.Absolute);
		}
		catch
		{
			resourceDictionary.Source = new Uri(Thread.GetDomain().BaseDirectory + "..\\Resources\\UI_en-US.xaml", UriKind.Absolute);
		}
		base.Resources.MergedDictionaries.Clear();
		base.Resources.MergedDictionaries.Add(resourceDictionary);
	}
}
