using System;
using System.Collections.Generic;
using System.Windows.Forms;
using QCRPG.Framework;
using QCRPG.TSL.NFC.Packets;

namespace QCRPG.TSL.NFC;

public class NFCGooier : GooierBase, QCRPG.Framework.IObserver<ConnectionStateChangeInfo>
{
	protected enum ControlEnableMode
	{
		DEFAULT,
		CONNECTION_OPENED,
		CONNECTION_CLOSED
	}

	protected const string menuTextOpenConnection = "Open Connection";

	protected const string menuTextCloseConnection = "Close Connection";

	protected Configurer configurer;

	protected NFCAPI nfcAPI;

	protected PacketListBase packetList;

	protected NFCConfigSettings nfcConfigSettings;

	protected NFCMainWorkerThread nfcMainWorkerThread;

	protected PacketUserControl packetUserControl;

	protected ToolStripButton toolStripButtonOpenConnection;

	protected ToolStripButton toolStripButtonCloseConnection;

	protected OpenConnectionSlavePortRateForm openConnectionSlavePortRateForm = new OpenConnectionSlavePortRateForm();

	protected NFCConfigUserControl nfcConfigUserControl;

	protected CombinedScripter combinedScripter;

	public NFCGooier(string technologyName, Logger logger, Configurer configurer, NFCAPI nfcAPI, PacketListBase packetList, NFCConfigSettings nfcConfigSettings, NFCMainWorkerThread nfcMainWorkerThread)
		: base(technologyName, logger)
	{
		this.configurer = configurer;
		this.nfcAPI = nfcAPI;
		this.packetList = packetList;
		this.nfcConfigSettings = nfcConfigSettings;
		this.nfcMainWorkerThread = nfcMainWorkerThread;
		List<PacketBase> list = new List<PacketBase>();
		list.AddRange(packetList.CommandPackets);
		list.Add(new Data());
		list.Add(new RawData());
		PacketHelper.RemoveTypeFromList(typeof(ReadI2c), list);
		PacketHelper.RemoveTypeFromList(typeof(WriteI2c), list);
		packetUserControl = new PacketUserControl(list);
		packetUserControl.RegisterLogMessageObserver(logger);
		configurer.RegisterConfigurableObject(openConnectionSlavePortRateForm, "OpenConnectionSlavePortRateFormSettings");
		nfcConfigUserControl = new NFCConfigUserControl(nfcConfigSettings);
		nfcConfigUserControl.SetInternalControlVisibility(visible: false);
	}

	protected override void StartupComplete()
	{
		SetControlEnables(ControlEnableMode.DEFAULT);
		nfcAPI.RegisterConnectionStateChangeInfoObserver(this);
	}

	public void SetCombinedScripter(CombinedScripter combinedScripter)
	{
		this.combinedScripter = combinedScripter;
		nfcMainWorkerThread.SetCombinedScripter(combinedScripter);
	}

	public void ApplicationReady()
	{
		if (nfcConfigSettings.OpenNFCConnectionOnStartup)
		{
			byte slaveAddress = openConnectionSlavePortRateForm.SlaveAddress;
			string selectedPortName = openConnectionSlavePortRateForm.SelectedPortName;
			int selectedDataRate = openConnectionSlavePortRateForm.SelectedDataRate;
			try
			{
				nfcAPI.OpenConnection(slaveAddress, selectedPortName, selectedDataRate);
			}
			catch (Exception ex)
			{
				logger.Enqueue(new LogMessage(LogMessageType.Error, ex));
			}
		}
	}

	protected override void AddUserControls()
	{
		userControls.Add(packetUserControl);
		userControls.Add(nfcConfigUserControl);
		configurer.RegisterConfigurableObject(packetUserControl, "PacketUserControlSettings");
		configurer.RegisterConfigurableObject(nfcConfigUserControl, "NFCConfigUserControlSettings");
	}

	protected override void BuildDropDownMenu()
	{
		dropDownMenu.Text = technologyName;
		AddOpenCloseDropDownMenuItems();
		SetDropDownMenuItemNames();
	}

	protected void AddOpenCloseDropDownMenuItems()
	{
		dropDownMenu.DropDownItems.Add("Open Connection", null, OpenConnectionHandler);
		dropDownMenu.DropDownItems.Add("Close Connection", null, CloseConnectionHandler);
	}

	protected void SetDropDownMenuItemNames()
	{
		for (int i = 0; i < dropDownMenu.DropDownItems.Count; i++)
		{
			dropDownMenu.DropDownItems[i].Name = dropDownMenu.DropDownItems[i].Text;
		}
	}

	protected override void BuildCustomToolStrip()
	{
		AddOpenCloseToolStripItems();
	}

	protected void AddOpenCloseToolStripItems()
	{
		toolStripButtonOpenConnection = new ToolStripButton(Resources.GetImage("OpenConnection.png"));
		toolStripButtonOpenConnection.DisplayStyle = ToolStripItemDisplayStyle.Image;
		toolStripButtonOpenConnection.AutoToolTip = true;
		toolStripButtonOpenConnection.ToolTipText = "Open an NFC serial port connection";
		toolStripButtonOpenConnection.Click += OpenConnectionHandler;
		customToolStripItems.Add(toolStripButtonOpenConnection);
		toolStripButtonCloseConnection = new ToolStripButton(Resources.GetImage("CloseConnection.png"));
		toolStripButtonCloseConnection.DisplayStyle = ToolStripItemDisplayStyle.Image;
		toolStripButtonCloseConnection.AutoToolTip = true;
		toolStripButtonCloseConnection.ToolTipText = "Close the NFC serial port connection";
		toolStripButtonCloseConnection.Click += CloseConnectionHandler;
		customToolStripItems.Add(toolStripButtonCloseConnection);
	}

	protected void OpenConnectionHandler(object sender, EventArgs e)
	{
		OpenConnectionAndDoStartupActions();
	}

	protected virtual bool OpenConnectionAndDoStartupActions()
	{
		openConnectionSlavePortRateForm.Title = "Open NFC Connection";
		if (openConnectionSlavePortRateForm.ShowDialog() != DialogResult.OK)
		{
			return false;
		}
		byte slaveAddress = openConnectionSlavePortRateForm.SlaveAddress;
		string selectedPortName = openConnectionSlavePortRateForm.SelectedPortName;
		int selectedDataRate = openConnectionSlavePortRateForm.SelectedDataRate;
		try
		{
			nfcAPI.OpenConnection(slaveAddress, selectedPortName, selectedDataRate);
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, ex));
			MessageBoxes.ShowErrorBox("Error opening NFC connection");
			return false;
		}
		nfcMainWorkerThread.InitDevice(nfcConfigSettings);
		return true;
	}

	protected void CloseConnectionHandler(object sender, EventArgs e)
	{
		try
		{
			nfcAPI.CloseConnection();
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, ex));
			MessageBoxes.ShowErrorBox("Error closing NFC connection");
			SetControlEnables(ControlEnableMode.CONNECTION_CLOSED);
		}
	}

	public void NotifyObserver(ConnectionStateChangeInfo connectionStateChangeInfo)
	{
		if (invokeControl == null)
		{
			UpdateControlEnablesFromConnectionStateChangeInfo(connectionStateChangeInfo);
			return;
		}
		invokeControl.BeginInvoke((MethodInvoker)delegate
		{
			UpdateControlEnablesFromConnectionStateChangeInfo(connectionStateChangeInfo);
		});
	}

	private void UpdateControlEnablesFromConnectionStateChangeInfo(ConnectionStateChangeInfo connectionStateChangeInfo)
	{
		if (connectionStateChangeInfo.openStateChanged)
		{
			if (connectionStateChangeInfo.openState)
			{
				SetControlEnables(ControlEnableMode.CONNECTION_OPENED);
			}
			else
			{
				SetControlEnables(ControlEnableMode.CONNECTION_CLOSED);
			}
		}
	}

	protected virtual void SetControlEnables(ControlEnableMode controlEnableMode)
	{
		switch (controlEnableMode)
		{
		case ControlEnableMode.DEFAULT:
			SetControlEnables(ControlEnableMode.CONNECTION_CLOSED);
			break;
		case ControlEnableMode.CONNECTION_OPENED:
			dropDownMenu.DropDownItems["Open Connection"].Enabled = false;
			toolStripButtonOpenConnection.Enabled = false;
			dropDownMenu.DropDownItems["Close Connection"].Enabled = true;
			toolStripButtonCloseConnection.Enabled = true;
			break;
		case ControlEnableMode.CONNECTION_CLOSED:
			dropDownMenu.DropDownItems["Close Connection"].Enabled = false;
			toolStripButtonCloseConnection.Enabled = false;
			dropDownMenu.DropDownItems["Open Connection"].Enabled = true;
			toolStripButtonOpenConnection.Enabled = true;
			break;
		default:
			throw new Exception("Unhandled control enable mode: " + controlEnableMode);
		}
	}

	public override void UpdateTitleBar()
	{
		GooierBase.SetWindowText((IntPtr)mainWindowHandle, "QCRPG-NFC");
	}
}
