using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using QCRPG.Framework;

namespace QCRPG.TSL.FM;

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

	private const string menuTextOpenConnection = "Open Connection";

	private const string menuTextCloseConnection = "Close Connection";

	private Configurer configurer;

	private FMAPI fmAPI;

	private PacketListBase packetList;

	private PacketUserControl packetUserControl;

	private ToolStripButton toolStripButtonOpenConnection;

	private ToolStripButton toolStripButtonCloseConnection;

	private OpenConnectionSlavePortRateForm openConnectionSlavePortRateForm = new OpenConnectionSlavePortRateForm();

	[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
	public static extern int StrCmpLogicalW(string psz1, string psz2);

	public FMGooier(string technologyName, Logger logger, Configurer configurer, FMAPI fmAPI, PacketListBase packetList)
		: base(technologyName, logger)
	{
		this.configurer = configurer;
		this.fmAPI = fmAPI;
		this.packetList = packetList;
		packetUserControl = new PacketUserControl(packetList.CommandPackets);
		packetUserControl.RegisterLogMessageObserver(logger);
		configurer.RegisterConfigurableObject(openConnectionSlavePortRateForm, "OpenConnectionSlavePortRateFormSettings");
	}

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

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

	protected override void BuildDropDownMenu()
	{
		dropDownMenu.Text = technologyName;
		dropDownMenu.DropDownItems.Add("Open Connection", null, OpenConnectionHandler);
		dropDownMenu.DropDownItems.Add("Close Connection", null, CloseConnectionHandler);
		for (int i = 0; i < dropDownMenu.DropDownItems.Count; i++)
		{
			dropDownMenu.DropDownItems[i].Name = dropDownMenu.DropDownItems[i].Text;
		}
	}

	protected override void BuildCustomToolStrip()
	{
		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);
	}

	private void OpenConnectionHandler(object sender, EventArgs e)
	{
		openConnectionSlavePortRateForm.Title = "Open FM Connection";
		if (openConnectionSlavePortRateForm.ShowDialog() != DialogResult.OK)
		{
			return;
		}
		byte slaveAddress = openConnectionSlavePortRateForm.SlaveAddress;
		string selectedPortName = openConnectionSlavePortRateForm.SelectedPortName;
		int selectedDataRate = openConnectionSlavePortRateForm.SelectedDataRate;
		try
		{
			fmAPI.OpenConnection(slaveAddress, selectedPortName, selectedDataRate);
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, ex));
			MessageBoxes.ShowErrorBox("Error opening FM connection");
		}
	}

	private void CloseConnectionHandler(object sender, EventArgs e)
	{
		try
		{
			fmAPI.CloseConnection();
		}
		catch (Exception ex)
		{
			logger.Enqueue(new LogMessage(LogMessageType.Error, ex));
			MessageBoxes.ShowErrorBox("Error closing FM 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);
			}
		}
	}

	private 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-FM");
	}
}
