using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using AR;
using COMM;
namespace Project.Dialog
{
    public partial class fXbeeSetting : Form
    {
        public fXbeeSetting()
        {
            InitializeComponent();
            VAR.BOOL[eVarBool.DISABLE_AUTOCONN_XBEE] = true;
            PUB.XBE.Close();
            this.serialPort1.DataReceived += SerialPort1_DataReceived;
        }
        private void fXbeeSetting_Load(object sender, EventArgs e)
        {
            this.tbPortName.Items.Clear();
            foreach (var item in System.IO.Ports.SerialPort.GetPortNames())
            {
                this.tbPortName.Items.Add(item);
            }

            this.tbPortName.Text = PUB.setting.Port_XBE;
            this.tbBaud.Text = PUB.setting.Baud_XBE.ToString();
            
        }
        void showlog(string Message)
        {
            if (rtXbee.Visible)
            {
                rtXbee.AddMsg(DateTime.Now, "NORMAL", Message);
            }
        }

        void showlog(arCtl.LogTextBox rtRx, DateTime LogTime, string TypeStr, string Message)
        {
            if (rtRx.Visible)
            {
                rtRx.AddMsg(LogTime, TypeStr, Message);
            }
        }
        private void button1_Click(object sender, EventArgs e)
        {
            if (this.serialPort1.IsOpen)
            {
                serialPort1.Close();
                showlog("closed");
            }   
            else
            {
                serialPort1.PortName = tbPortName.Text;
                serialPort1.BaudRate = int.Parse(tbBaud.Text);
                serialPort1.Open();
                showlog("open");
            }
        }

        private void fXbeeSetting_FormClosed(object sender, FormClosedEventArgs e)
        {
            VAR.BOOL[eVarBool.DISABLE_AUTOCONN_XBEE] =  false;
        }

	private volatile bool isCommandExecuting = false;

        private void SerialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            if (isCommandExecuting) return;

            try
            {
                string data = serialPort1.ReadExisting();
                var hexdata = System.Text.Encoding.Default.GetBytes(data);
                var hexstr = string.Join(" ", hexdata.Select(t => t.ToString("X2")));
                if (!string.IsNullOrEmpty(data))
                {
                    this.BeginInvoke(new Action(() =>
                    {
                        showlog($"RxAsync: {hexstr}");
                    }));
                }
            }
            catch { }
        }

        private string Cmd(string cmd, int timeout = 1000)
        {
            isCommandExecuting = true;
            try
            {
                if (!serialPort1.IsOpen) return "Error: Port Closed";

                serialPort1.DiscardInBuffer();
                serialPort1.Write(cmd);

                System.Threading.Thread.Sleep(20);
                serialPort1.ReadTimeout = timeout;
                string res = serialPort1.ReadTo("\r");
                System.Threading.Thread.Sleep(20);
                showlog($"Tx:{cmd.Trim()}, Rx:{res}");

                //명령수신호 10ms 대기후 다음 명령을 전송
                System.Threading.Thread.Sleep(20);

                return res;
            }
            catch (Exception ex)
            {
                showlog($"Err: {ex.Message}");
                return "Error";
            }
            finally
            {
                isCommandExecuting = false;
            }
        }
        private void btpand_Click(object sender, EventArgs e)
        {
            //각명령마다 회신을 확인하고 다음명령을 실행해야함
            //명령수신호 10ms 대기후 다음 명령을 전송
            //명령을 설정하면 응답은 OK\d 형태로 입력된다.
            var cmds = new string[] { 
                "+++",
                $"ATID{tbpanid.Text}\r" ,
                $"ATCN\r"};

            foreach (var cmd in cmds)
            {
                if(!Cmd(cmd).Contains("OK"))
                {
                    showlog("FAIL");
                    break;
                }
            }
        }

        private void btch_Click(object sender, EventArgs e)
        {
            var cmds = new string[] {
                "+++",
                $"ATCH{tbch.Text}\r" ,
                $"ATCN\r"};
            foreach (var cmd in cmds)
            {
                if (!Cmd(cmd).Contains("OK"))
                {
                    showlog("FAIL");
                    break;
                }
            }
        }

        private void btmy_Click(object sender, EventArgs e)
        {
            var cmds = new string[] {
                "+++",
                $"ATMY{tbmy.Text}\r" ,
                $"ATCN\r"};
            foreach (var cmd in cmds)
            {
                if (!Cmd(cmd).Contains("OK"))
                {
                    showlog("FAIL");
                    break;
                }
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //read all(id,ch,my)
            if (Cmd("+++").Contains("OK"))
            {
               var id  = Cmd("ATID\r");
                var ch = Cmd("ATCH\r");
                var my = Cmd("ATMY\r");
                Cmd("ATCN\r");
                this.BeginInvoke(new Action(() => {
                    this.tbpanid.Text = id;
                    this.tbch.Text = ch;
                    this.tbmy.Text = my;
                }));
            }
        }
    }
}
