using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using NationalInstruments.NI4882;	 // Import of GPIB class

namespace Sample
{
    class GPIB_NI
    {
        // (0)Class variable
        private Device GpibDevice;                                  // GPIB Device
        public string MsgBuf = "";                                  // Received Data

        // (1)Connect
        public bool OpenInterface(string BoardID, string PrimaryAddress)
        {
            bool ret = false;

            try
            {
                GpibDevice = new Device(Convert.ToInt32(BoardID), Convert.ToByte(PrimaryAddress), 0, TimeoutValue.T1s);     // Create a GPIB object
                ret = true;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }

            return ret;
        }

        // (2)Disconnect
        public bool CloseInterface()
        {
            bool ret = false;

            try
            {
                GpibDevice.Dispose();                                                   // Dispose the GPIB object
                ret = true;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }

            return ret;

        }

        // (3)Send commands
        public bool SendMsg(string strMsg)
        {
            bool ret = false;

            try
            {
                strMsg += "\r\n";                                                       // Add a terminator, CR+LR, to transmitted command
                GpibDevice.Write(strMsg);                                               // Write data in the transmit buffer
                ret = true;
            }
            catch (Exception e)
            {
                MsgBuf = "Error";
                MessageBox.Show(e.Message);
            }

            return ret;

        }

        // (4)Receive
        public bool ReceiveMsg(long timeout_ms)
        {
            bool ret = false;
            string rcv = "";
            StringBuilder buf = new StringBuilder();
            Stopwatch sw = new Stopwatch();

            MsgBuf = "";                                                                // Clear received data
            sw.Start();                                                                 // Start a stopwatch
                                                                                        // Continue the loop until LF is received 
            while (true)
            {
                try
                {
                    rcv = "";
                    rcv = GpibDevice.ReadString();                                      // Read data from the receive buffer
                    rcv = rcv.Replace("\r", "");                                        // Delete CR in received data
                    if (rcv.IndexOf("\n") >= 0)                                         // End the loop when LF is received
                    {
                        rcv = rcv.Substring(0, rcv.IndexOf("\n"));                      // Extract data without LF and the following from the original received data
                        buf.Append(rcv);                                                // Save the data
                        MsgBuf = buf.ToString();
                        break;
                    }
                    else
                    {
                        buf.Append(rcv);                                                // Save the data
                    }
                    // Timeout processing
                    if (sw.ElapsedMilliseconds > timeout_ms)
                    {
                        MsgBuf = "Timeout";
                        MessageBox.Show(MsgBuf);
                        return ret;
                    }
                }
                catch (Exception e)
                {
                    GpibStatusFlags statusFlag = GpibDevice.GetCurrentStatus();
                    if ((statusFlag & GpibStatusFlags.IOComplete) == 0)
                    {
                        // Exceptions other than IO Complete
                        MsgBuf = "Error";
                        MessageBox.Show(e.Message);
                        return ret;
                    }
                    else
                    {
                        // Exception IO Complete
                        rcv = rcv.Replace("\r", "");                                    // Delete CR in received data
                        if (rcv.IndexOf("\n") >= 0)                                     // End the loop when LF is received
                        {
                            rcv = rcv.Substring(0, rcv.IndexOf("\n"));                  // Extract data without LF and the following from the original received data
                            buf.Append(rcv);                                            // Save the data
                            MsgBuf = buf.ToString();
                            break;
                        }
                        else
                        {
                            buf.Append(rcv);                                            // Save the data
                        }
                        // Timeout processing
                        if (sw.ElapsedMilliseconds > timeout_ms)
                        {
                            MsgBuf = "Timeout";
                            MessageBox.Show(MsgBuf);
                            return ret;
                        }
                    }
                }
            }
            sw.Stop();                                                                  // Stop a stopwatch
            ret = true;

            return ret;
        }

        // (5)Transmit and receive commands
        public bool SendQueryMsg(string strMsg, long timeout_ms)
        {
            bool ret = false;

            ret = SendMsg(strMsg);                                                      // Transmit commands
            if (ret)
            {
                if (strMsg.Contains("?"))
                {
                    ret = ReceiveMsg(timeout_ms);                                       // Receive response when command transmission is succeeded
                }
            }

            return ret;
        }
    }

}
