//--------------------------------------------------------------
//	COM ポートの自動選択で使うクラス
//
//		作成者：三上直樹，2022/02/10 作成，©三上直樹 2022
//--------------------------------------------------------------

using System.Collections.Generic;
using System.Windows.Forms;
using System.Threading;

using ThreadTimer = System.Threading.Timer;

namespace Mikami.Application
{
	public class AutoSelect
	{
		private readonly string deviceID_;
		private readonly MySerialPort sp_;
		private readonly ToolStripLabel label_;
		private readonly Queue<string> name_ = ComPort.Tabulate();
		private readonly ThreadTimer timerAck_;	// マイコンからの応答を待つ際に使う

		// コンストラクタ
		public AutoSelect(string id, MySerialPort sp, ToolStripLabel label)
		{
			deviceID_ = id;
			sp_ = sp;
			label_ = label;
			timerAck_ = new ThreadTimer(new TimerCallback(AckTimeout));
			ComPortCheck();
		}

		// タイムアウト検出用タイマの停止
		public void StopTimer() => timerAck_.Change(-1, 0);

		// COM ポートのチェック
		private void ComPortCheck()
		{
			if (name_.Count == 0)
				label_.Text = "マイコン側の準備ができていません．";
			else
			{
				timerAck_.Change(100, 0);	// タイムアウト監視タイマの開始
				if (sp_.Open(name_.Dequeue()))
					sp_.SendTo(deviceID_);	// マイコンへ "ACK" の送信を要求
			}
		}

		// マイコンの準備ができていない（"ACK" が返ってこない）場合の処理
		private void AckTimeout(object state)
		{
			if (sp_.IsOpen) sp_.Close();	// シリアルポートのクローズ処理
			Thread.Sleep(50);		// 時間を少し空ける
			ComPortCheck();
		}
	}
}
