//***********************************************************************/
//*                                                                     */
//*     IF-60 API Sample Program                                        */
//*                                                      2014/9/2       */
//*     Copyright(c) 2014  TEXIO TECHNOLOGY CORPORATION                 */
//***********************************************************************/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;

namespace PSF_Access
{
    // サンプルフォーム
    public partial class PSF_Access : Form
    {
        private int DeviceId;           // オープンしたデバイスのID。
        private int if_sel;
        private const int IF_USB = 1;
        private const int IF_GPIB0 = 2;
        private const int IF_COM1 = 3;


        private SerialPort serialPort1; // COM1 Object

        private string SYSAddr;         // local Addr Name
        private int PcAddr;             // PC Addr

        // コンストラクタ
        public PSF_Access()
        {
            InitializeComponent();
        }

        // フォームロード
        private void PWA_Access_Load(object sender, EventArgs e)
        {
            // 使用するインターフェースを選択できるようにする。
            comboBox1.Items.Add("USB");
            comboBox1.Items.Add("COM");
            comboBox1.SelectedIndex = 0;

            // PCアドレス
            for (int address = 1; address < 30; address++)
            {
                comboBox2.Items.Add(address.ToString());
            }
            comboBox2.SelectedIndex = 0;

            // システムアドレス
            for (int address = 1; address < 30; address++)
            {
                comboBox3.Items.Add(address.ToString());
            }
            comboBox3.SelectedIndex = 0;

            serialPort1 = new SerialPort();
        }

        // フォームクローズ
        private void PWA_Access_FormClosing(object sender, FormClosingEventArgs e)
        {
            if(if_sel != 0)
            {
                // OUTPUT OFF
                PSF_Send(PcAddr, ":outp 0");

                // ローカル状態
                PSF_Send(PcAddr, ":Remote0");

                // アドレス設定　マスタ
                PSF_Send(PcAddr, ":ADDR1");
                PSF_Send(PcAddr, ":Remote0");

                // クローズ
                PSF_DeviceClose(PcAddr);
            }
        }

        // Open / Close
        private void button1_Click(object sender, EventArgs e)
        {
            // Device Open
            if (button1.Text == "OPEN")
            {
                // 使用するインターフェースを選択
                if(comboBox1.Text == "USB")
                {
                    if_sel = IF_USB;
                }
                else if (comboBox1.Text == "COM")
                {
                    if_sel = IF_COM1;
                }

                // パーソナルコンピュータアドレス
                PcAddr = Int32.Parse(comboBox2.Text);

                // システムアドレス
                SYSAddr = ":ADDR " + comboBox3.Text;

                // オープン
                DeviceId = PSF_DeviceOpen(PcAddr);

                if(DeviceId > 0)
                {
                    // アドレス設定
                    PSF_Send(PcAddr, SYSAddr);

                    // OUTPUT OFF
                    PSF_Send(PcAddr, ":OUTP 0");

                    // 表示切り替え CHA-電圧-電流
                    PSF_Send(PcAddr, ":Conf:disp1");

                    // 画面表示
                    button1.Text = "CLOSE";
                    button2.Enabled = true;
                    button2.Text = "ON";
                    button3.Enabled = true;
                    button4.Enabled = true;
                    button5.Enabled = true;
                    button6.Enabled = true;
                    button7.Enabled = true;
                    textBox1.Text = "";
                }
                else
                {
                    // エラーを表示
                    textBox1.Text = " Device Open ERR";
                }
            }
            // Device Close
            else
            {
                // OUTPUT OFF
                PSF_Send(PcAddr, ":outp 0");

                // ローカル状態
                PSF_Send(PcAddr, ":Remote0");

                // アドレス設定 マスタ
                PSF_Send(PcAddr, ":ADDR1");

                // ローカル設定
                PSF_Send(PcAddr, ":Remote0");

                // クローズ
                PSF_DeviceClose(PcAddr);

                // 画面表示
                button1.Text = "OPEN";
                button2.Text = "ON";
                button2.BackColor = System.Drawing.SystemColors.Control;
                button2.Enabled = false;
                button3.Enabled = false;
                button4.Enabled = false;
                button5.Enabled = false;
                button6.Enabled = false;
                button7.Enabled = false;
                textBox1.Text = "";
                if_sel = 0;
            }
        }

        // Output On/Off
        private void button2_Click(object sender, EventArgs e)
        {
            if (button2.Text == "ON")
            {
                // OutputをONに設定
                PSF_Send(PcAddr, ":outp1");

                // 表示の更新
                button2.Text = "OFF";
                button2.BackColor = System.Drawing.Color.Red;
            }
            else
            {
                // OutputをOFFに設定
                PSF_Send(PcAddr, ":outp0");

                // 表示の更新
                button2.Text = "ON";
                button2.BackColor = System.Drawing.SystemColors.Control;
            }
        }

        // Preset 1
        private void button3_Click(object sender, EventArgs e)
        {
            // Preset 1を選択
            PSF_Send(PcAddr, ":pres:call 1");
        }

        // Preset 2
        private void button4_Click(object sender, EventArgs e)
        {
            // Preset 2を選択
            PSF_Send(PcAddr, ":pres:call 2");
        }

        // Preset 3
        private void button5_Click(object sender, EventArgs e)
        {
            // Preset 3を選択
            PSF_Send(PcAddr, ":pres:call 3");
        }

        // Preset 0
        private void button6_Click(object sender, EventArgs e)
        {
            // Preset 0を選択
            PSF_Send(PcAddr, ":pres:call 0");
        }

        // Read
        private void button7_Click(object sender, EventArgs e)
        {
            string bbuf = "";
            string[] meas_value;

            // モニタ要求
            PSF_Send(PcAddr, ":meas?");

            // 応答待ち
            System.Threading.Thread.Sleep(200);

            // モニタ値受信
            PSF_Recive(PcAddr, 64, ref bbuf);

            // モニタ値はカンマ区切りで電圧、電流、電力、ステータス
            meas_value = bbuf.Split(',');
            if(meas_value.Length > 3)
            {
                StringBuilder sb = new StringBuilder();
                sb.Append(meas_value[0]);
                sb.AppendLine("V");
                sb.Append(meas_value[1]);
                sb.AppendLine("A");
                sb.Append(meas_value[2]);
                sb.AppendLine("W");
                sb.Append(meas_value[3]);
                sb.Append("  0:CV/1:CC/2:CP");
                textBox1.Text = sb.ToString();
            }
        }

        //***********************************************************************/
        //*     IF-60　Interface Select                                         */
        //***********************************************************************/

        // オープン
        private int PSF_DeviceOpen(int addr)
        {
            int ret = -1;
            try
            {
                switch (if_sel)
                {
                    case IF_USB:
                        ret = IF_60.USB488_DeviceOpen(addr);
                        break;

                    case IF_COM1:
                        serialPort1.PortName = "COM" + addr.ToString();
                        serialPort1.BaudRate = 57600;
                        serialPort1.DataBits = 8;
                        serialPort1.Parity = System.IO.Ports.Parity.None;
                        serialPort1.StopBits = System.IO.Ports.StopBits.One;
                        serialPort1.Handshake = System.IO.Ports.Handshake.RequestToSend;
                        serialPort1.RtsEnable = true;
                        serialPort1.ReadTimeout = 3000;
                        serialPort1.WriteTimeout = 500;
                        serialPort1.Open();
                        serialPort1.DiscardInBuffer();
                        ret = 1;
                        break;
                }
            }
            catch (System.Exception caught)
            {
                MessageBox.Show(caught.Message, "OpenErr", MessageBoxButtons.OK, MessageBoxIcon.Error);
                ret = -1;
            }
            return ret;
        }

        // クローズ
        private int PSF_DeviceClose(int addr)
        {
            int ret = -1;
            try
            {
                switch (if_sel)
                {
                    case IF_USB:
                        ret = IF_60.USB488_DeviceClose(addr);
                        break;

                    case IF_COM1:
                        serialPort1.Close();
                        ret = 0;
                        break;
                }
            }
            catch (System.Exception caught)
            {
                MessageBox.Show(caught.Message, "CloseErr", MessageBoxButtons.OK, MessageBoxIcon.Error);
                ret = -1;
            }

            return ret;
        }

        // リモート
        private int PSF_SetRemote(int addr, int rMode)
        {
            int ret = -1;
            switch (if_sel)
            {
                case IF_USB:
                    ret = IF_60.USB488_SetRemote(addr, rMode);
                    break;

                case IF_COM1:
                    ret = 0;
                    break;
            }
            return ret;
        }

        // コマンド送信
        private int PSF_Send(int addr, string strBuf)
        {
            int ret = -1;

            try
            {
                switch (if_sel)
                {
                    case IF_USB:
                        ret = IF_60.USB488_Send(addr, strBuf);
                        break;

                    case IF_COM1:
                        serialPort1.WriteLine(strBuf);
                        ret = strBuf.Length;
                        break;
                }
            }
            catch (System.Exception caught)
            {
                MessageBox.Show(caught.Message, "SendErr", MessageBoxButtons.OK, MessageBoxIcon.Error);
                ret = -1;
            }
            return ret;
        }

        // 応答受信
        private int PSF_Recive(int addr, int Count, ref string strBuf)
        {
            int ret = -1;
            var sb = new StringBuilder(Count + 1);

            try
            {
                switch (if_sel)
                {
                    case IF_USB:
                        ret = IF_60.USB488_Receive(addr, Count, sb);
                        if (ret > 0)
                        {
                            strBuf = sb.ToString();
                        }
                        else
                        {
                            MessageBox.Show("Read Error", "Read Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            strBuf = "";
                        }
                        break;

                    case IF_COM1:
                        strBuf = serialPort1.ReadLine();
                        ret = strBuf.Length;
                        break;
                }
            }
            catch (System.Exception caught)
            {
                MessageBox.Show(caught.Message, "Read Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                strBuf = "";
                ret = -1;
            }

            return ret;
        }
    }
}
